PluginProbe
WebTotem Security / 3.0.0
WebTotem Security v3.0.0
3.0.1 3.0.0 trunk 1.0 1.1 1.2 1.3 1.3.1 1.3.2 1.3.3 2.0 2.1 2.1.1 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.1.7 2.1.8 2.1.9 2.2.1 2.2.2 2.2.3 2.2.4 All 109 releases
wt-security / lib / Interface.php

Interface.php in WebTotem Security 3.0.0, at lib/Interface.php

499 lines 15.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 if (!defined('WEBTOTEM_INIT') || WEBTOTEM_INIT !== true) {
4 if (!headers_sent()) {
5 header('HTTP/1.1 403 Forbidden');
6 }
7 die("Protected By WebTotem!");
8 }
9
10 /**
11 * Plugin initializer.
12 *
13 */
14 class WebTotemInterface extends WebTotem {
15
16 /**
17 * Execute pre-checks before every page.
18 *
19 * @return void
20 */
21 public static function startupChecks() {
22
23 /** Hide or show WP version */
24 if (WebTotemOption::getPluginSettings('hide_wp_version')) {
25 WebTotemOption::hideWPVersion();
26
27 add_filter('style_loader_src', 'WebTotemOption::replaceVersion');
28 add_filter('script_loader_src', 'WebTotemOption::replaceVersion');
29
30 }
31
32 /** Disable user enumeration */
33 if (WebTotemOption::getPluginSettings('disable_user_enumeration')) {
34 if (!is_admin()) {
35 // default URL format
36 if (preg_match('/author=([0-9]*)/i', $_SERVER['QUERY_STRING'])) {
37 header("Location: " . get_home_url());
38 die();
39 }
40 add_filter('redirect_canonical', 'wtsec_check_enum', 10, 2);
41
42 }
43
44 function wtsec_check_enum($redirect, $request) {
45 // permalink URL format
46 if (preg_match('/\?author=([0-9]*)(\/*)/i', $request)) {
47 header("Location: " . get_home_url());
48 die();
49 } else {
50 return $redirect;
51 }
52 }
53
54 }
55
56
57 $_page = WebTotemRequest::get('page');
58 if(strpos($_page, 'wtotem') === 0 ) {
59 $composer_autoload = WEBTOTEM_PLUGIN_PATH . '/vendor/autoload.php';
60 if ( file_exists( $composer_autoload ) ) {
61 require_once $composer_autoload;
62 }
63 }
64
65 $_page = WebTotemRequest::get('page');
66 if(strpos($_page, 'wtotem') === 0){
67
68 if(!WebTotemOption::isActivated()){
69 // Checking the old version of options.
70 WebTotemOption::checkOldOptions();
71 }
72
73 WebTotemOption::multisiteCheck();
74
75 $version = WebTotemOption::getOption('plugin_version');
76 if (WebTotemOption::isActivated() and !empty($version) and version_compare($version, '3.0.0', '<')) {
77 WebTotemDB::clearSettings();
78 WebTotemOption::setOptions(['plugin_version' => WEBTOTEM_VERSION]);
79 }
80
81 if(!WebTotemOption::isActivated() and $_page !== 'wtotem_activation') {
82 // If the plugin is not activated by the API key, then redirect to the activation page.
83 wp_safe_redirect( WebTotem::adminURL('admin.php?page=wtotem_activation') );
84 exit;
85 }
86 elseif (WebTotemOption::isActivated() and ($_page === 'wtotem_activation' or $_page === 'wtotem')){
87 // If the plugin is activated by the API key, then redirect to the main page.
88 if(self::isMultiSite() and is_super_admin()){
89 // Main page is all sites page.
90 wp_safe_redirect( WebTotem::adminURL('admin.php?page=wtotem_all_sites') );
91 } else {
92 // Main page is dashboard page.
93 wp_safe_redirect( WebTotem::adminURL('admin.php?page=wtotem_dashboard') );
94 }
95 exit;
96 }
97 elseif(WebTotemOption::isActivated()) {
98 // Checking whether agents are installed, if they are not installed, then install.
99 self::checkAgents();
100 // self::checkSiteAddedDate();
101
102 // Check if the plugin version has changed.
103 WebTotemAgentManager::checkVersion();
104
105 $sapi = @php_sapi_name();
106 if( $sapi != "cli" ) {
107 if ($waf = WebTotemOption::getOption("waf_file")) {
108 $include_waf_file = ABSPATH . '_include_' . $waf;
109
110 if (is_file($include_waf_file) && is_readable($include_waf_file)) {
111 include_once $include_waf_file;
112 }
113 }
114 }
115 }
116 }
117
118
119 if (!WebTotemOption::isActivated() and version_compare(WEBTOTEM_VERSION, '3.0.3', '<=')) {
120 WebTotemOption::setNotification('warning', __('We’ve made significant changes to the backend of our platform.. To continue using the plugin, please re-authorize your account in the dashboard and generate a new API key here: <a target="_blank" href="https://app.wtotem.com"> cabinet </a>.', 'wtotem'));
121 }
122
123 }
124
125 /**
126 * Checking whether agents are installed, if they are not installed, then install.
127 */
128 private static function checkAgents(){
129
130 $api_key = WebTotemOption::getOption('api_key');
131
132 $host = WebTotemAPI::siteInfo();
133
134 if ($api_key && array_key_exists('id', $host) && $host['id']) {
135
136 // Install Agent Manager if it was not previously installed.
137 $am_installed = WebTotemAgentManager::checkInstalledService('am');
138 if (!$am_installed['file_status']) {
139
140 $am_was_installed = WebTotemAgentManager::amInstall();
141
142 if (!$am_was_installed) {
143 WebTotemOption::setOptions(['am_installed' => FALSE]);
144 }
145 }
146
147 }
148 }
149
150 /**
151 * Checking whether the site added date has been saved, if not, then requests the data and saves.
152 */
153 private static function checkSiteAddedDate(){
154 if (WebTotemRequest::get('hid')) {
155 $host = WebTotemOption::getHost(WebTotemRequest::get('hid'));
156 } else {
157 $host = WebTotemAPI::siteInfo();
158 }
159
160 $site_created_at = WebTotemOption::getOption('site_created_at');
161
162 $site_created_at = $site_created_at ? json_decode($site_created_at, true) : [];
163
164 if(!array_key_exists($host['name'], $site_created_at)){
165 $createdAt = WebTotemAPI::getGetSiteAddedDate($host['name']);
166 if($createdAt){
167 WebTotemOption::setOptions(['site_created_at' => [ $host['name'] => $createdAt] ]);
168 }
169 }
170 }
171
172 /**
173 * When adding a new site, add it to the WebTotem platform.
174 */
175 public static function addNewSite($new_site){
176 $domain = untrailingslashit($new_site->domain . $new_site->path);
177
178 WebTotemAPI::addMultiSiteNewSites([$domain]);
179 }
180
181 /**
182 * Verify the nonce of the previous page after a form submission.
183 *
184 * @return bool True if the nonce is valid, false otherwise.
185 */
186 public static function checkNonce() {
187 if (!empty($_POST)) {
188 $name = 'wtotem_page_nonce';
189 $value = WebTotemRequest::post($name);
190
191 if (!$value || !wp_verify_nonce($value, $name)) {
192 WebTotemOption::setNotification('error', __('The WordPress CSRF check failed. The submitted form is missing an important unique code. Go back and try again.', 'wtotem'));
193 return false;
194 }
195 }
196
197 return true;
198 }
199
200 /**
201 * Add 2fa to the profile form.
202 *
203 * @return void
204 */
205 public static function add2faProfileForm(){
206
207 if(!WebTotemLogin::isTwoFactorEnabled()){ return; }
208
209 if ( isset( $_GET['user_id'] ) ) {
210 if( !current_user_can( 'manage_options' ) ){
211 return;
212 }
213 $user_id = (int) $_GET['user_id'];
214 $user = get_user_by( 'id', $user_id );
215 } else {
216 $user = wp_get_current_user();
217 }
218
219 $current_user = wp_get_current_user();
220
221 if ( ! is_a( $user, '\WP_User' ) || ! is_a( $current_user, '\WP_User' ) ) {
222 return;
223 }
224
225 $composer_autoload = WEBTOTEM_PLUGIN_PATH . '/vendor/autoload.php';
226 if ( file_exists( $composer_autoload ) ) {
227 require_once $composer_autoload;
228 }
229
230 $template = new WebTotemTemplate();
231
232 $build[] = [
233 'template' => 'two_factor_user_profile_modal',
234 'variables' => [
235 'two_factor' => WebTotemLogin::getTwoFactorData($user),
236 'user_id' => $user_id ?? $user->ID,
237 'can_manage_options' => current_user_can( 'manage_options' )
238 ],
239 ];
240
241 $page_content = $template->arrayRender($build);
242 echo $page_content;
243 }
244
245 /**
246 * Authentication.
247 *
248 * @return mixed
249 */
250 public static function wt_authenticate($user, $username = null, $password = null) {
251
252 if(WebTotemCaptcha::isEnabled()) {
253 if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
254 return $user;
255 }
256 $token = WebTotemCaptcha::get_token();
257 $score = WebTotemCaptcha::score($token, WebTotemOption::getPluginSettings('recaptcha_v3_secret'));
258 if($score < 0.5) {
259 return new \WP_Error('authentication_failed', __('<strong>ERROR</strong>&nbsp;: Please check the ReCaptcha box or try to reload page.','wtotem'));
260 }
261 }
262
263 if(isset($_POST['wtotem-token']) && is_string($_POST['wtotem-token']) && !empty($_POST['wtotem-token'])){
264 if ( is_object( $user ) && ( $user instanceof \WP_User ) ) {
265 if ( WebTotemLogin::hasUser2faActivated( $user ) ) {
266 $check2faCode = WebTotemLogin::check2faCode( $user, $_POST['wtotem-token']);
267
268 if ( ! $check2faCode ) {
269 return new \WP_Error( 'wtotem_two_factor_failed', wp_kses( __( '<strong>CODE INVALID</strong>: The 2FA code provided is either expired or invalid. Please try again.', 'wtotem' ), array( 'strong' => array() ) ) );
270 }
271 }
272 }
273 }
274
275 return WebTotemBFProtection::checkBruteForceAttempts($user, $username);
276 }
277
278 /**
279 * Password brute force protection.
280 *
281 * @return mixed
282 */
283 public static function wt_lost_password($errors = null, $user_data = null) {
284 return WebTotemBFProtection::lostPassword($errors);
285 }
286
287 /**
288 * Restore and then hide the readme file when updating the WordPress.
289 *
290 * @param string $string
291 * @return string
292 */
293 public static function restoreReadmeWhenUpdating($string) {
294 static $didRun;
295 if (!isset($didRun)) {
296 $didRun = true;
297 WebTotemOption::restoreReadme();
298 register_shutdown_function('WebTotemOption::hideReadme');
299 }
300
301 return $string;
302 }
303
304 /**
305 * Login Page
306 */
307 public static function loginEnqueueScripts() {
308
309 $recaptcha_enabled = WebTotemCaptcha::isEnabled();
310 if ($recaptcha_enabled) {
311 $recaptcha_site_key = WebTotemOption::getPluginSettings('recaptcha_v3_site_key');
312 wp_enqueue_script('wtotem_recaptcha', 'https://www.google.com/recaptcha/api.js?render=' . $recaptcha_site_key);
313 }
314
315 wp_register_script(
316 'wtotem_login',
317 WEBTOTEM_URL . '/includes/js/login.js',
318 ['jquery'],
319 WebTotem::fileVersion('includes/js/login.js'),
320 false
321 );
322 wp_enqueue_script('wtotem_login');
323
324 wp_register_style(
325 'wtotem_login',
326 WEBTOTEM_URL . '/includes/css/login.css',
327 [],
328 WebTotem::fileVersion('includes/css/login.css')
329 );
330 wp_enqueue_style('wtotem_login');
331
332 wp_localize_script('wtotem_login', 'wtotem_login_vars', [
333 'recaptcha_site_key' => WebTotemCaptcha::_siteKey(),
334 'recaptcha_is_enabled' => $recaptcha_enabled,
335 'ajaxurl' => admin_url('admin-ajax.php', 'relative'),
336 'two_factor_is_enabled' => WebTotemLogin::isTwoFactorEnabled() and WebTotemLogin::anyTwoFactorActivated(),
337 ]);
338 }
339
340 /**
341 * Added a pop-up window to the plugins page
342 */
343 public static function registerDeletePrompt() {
344 wp_register_style(
345 'wtotem_prompt_css',
346 WEBTOTEM_URL . '/includes/css/prompt.css',
347 [],
348 WebTotem::fileVersion('includes/css/prompt.css')
349 );
350 wp_enqueue_style('wtotem_prompt_css');
351
352 $composer_autoload = WEBTOTEM_PLUGIN_PATH . '/vendor/autoload.php';
353 if ( file_exists( $composer_autoload ) ) {
354 require_once $composer_autoload;
355 }
356
357 $template = new WebTotemTemplate();
358 $build[] = [
359 'variables' => [
360 'message' => __('Are you sure you want to deactivate the plugin?<br>Don\'t worry, even after removing the plugin, our system will continue to protect your site: <ul class="confirmation-dialog__list"><li>the current host will remain in the account</li><li>agents will stay on the current site</li><li>accumulated history, monitoring, agent management and all other functions are available in the account on the <a href="https://wtotem.com" target="_blank">site</a></li></ul>', 'wtotem'),
361 'action' => 'reinstall_agents',
362 'page_nonce' => wp_create_nonce('wtotem_page_nonce'),
363 ],
364 'template' => 'prompt',
365 ];
366
367 echo $template->arrayRender($build);
368 }
369
370 /**
371 * A safe way to add JavaScript and css files to a WordPress-managed page
372 *
373 * @return void
374 */
375 public static function enqueueScripts() {
376
377 // Adding CSS files.
378 wp_register_style(
379 'wtotem_flatpickr',
380 WEBTOTEM_URL . '/includes/css/flatpickr.min.css',
381 [],
382 WebTotem::fileVersion('includes/css/flatpickr.min.css')
383 );
384 wp_enqueue_style('wtotem_flatpickr');
385
386 wp_register_style(
387 'wtotem_toastr_css',
388 WEBTOTEM_URL . '/includes/css/toastr.min.css',
389 [],
390 WebTotem::fileVersion('includes/css/toastr.min.css')
391 );
392 wp_enqueue_style('wtotem_toastr_css');
393
394 wp_register_style(
395 'wtotem_main_css',
396 WEBTOTEM_URL . '/includes/css/main.css',
397 [],
398 WebTotem::fileVersion('includes/css/main.css')
399 );
400 wp_enqueue_style('wtotem_main_css');
401
402 // Adding JS files.
403 wp_register_script(
404 'wtotem_amplitude',
405 WEBTOTEM_URL . '/includes/js/amplitude.js',
406 [ 'jquery' ],
407 WebTotem::fileVersion('includes/js/amplitude.js'),
408 false
409 );
410 wp_enqueue_script('wtotem_amplitude');
411
412 wp_register_script(
413 'wtotem_d3',
414 WEBTOTEM_URL . '/includes/js/d3.v4.js',
415 ['jquery'],
416 WebTotem::fileVersion('includes/js/d3.v4.js'),
417 true
418 );
419 wp_enqueue_script('wtotem_d3');
420
421 wp_register_script(
422 'wtotem_chart',
423 WEBTOTEM_URL . '/includes/js/chart.js',
424 ['jquery', 'wtotem_d3', 'wtotem_jsdelivr'],
425 WebTotem::fileVersion('includes/js/chart.js'),
426 true
427 );
428 wp_enqueue_script('wtotem_chart');
429
430 wp_register_script(
431 'wtotem_flatpickr_js',
432 WEBTOTEM_URL . '/includes/js/flatpickr.js',
433 [ 'jquery', 'wp-i18n' ],
434 WebTotem::fileVersion('includes/js/flatpickr.js'),
435 true
436 );
437 wp_set_script_translations( 'wtotem_flatpickr_js', 'wtotem', WEBTOTEM_PLUGIN_PATH . '/lang/');
438 wp_enqueue_script('wtotem_flatpickr_js');
439
440 wp_register_script(
441 'wtotem_jsdelivr',
442 WEBTOTEM_URL . '/includes/js/jsdelivr_chart.js',
443 [ 'jquery' ],
444 WebTotem::fileVersion('includes/js/jsdelivr_chart.js'),
445 true
446 );
447 wp_enqueue_script('wtotem_jsdelivr');
448
449 wp_register_script(
450 'wtotem_jquery_qrcode',
451 WEBTOTEM_URL . '/includes/js/jquery.qrcode.min.js',
452 [ 'jquery' ],
453 WebTotem::fileVersion('includes/js/jquery.qrcode.min.js'),
454 true
455 );
456 wp_enqueue_script('wtotem_jquery_qrcode');
457
458 wp_register_script(
459 'wtotem_progress_bar',
460 WEBTOTEM_URL . '/includes/js/progress_bar.js',
461 [],
462 WebTotem::fileVersion('includes/js/progress_bar.js'),
463 true
464 );
465 wp_enqueue_script('wtotem_progress_bar');
466
467 wp_register_script(
468 'wtotem_toastr',
469 WEBTOTEM_URL . '/includes/js/toastr.min.js',
470 [],
471 WebTotem::fileVersion('includes/js/toastr.min.js'),
472 true
473 );
474 wp_enqueue_script('wtotem_toastr');
475
476 $_page = WebTotemRequest::get('page');
477 if($_page === 'wtotem_settings'){
478 // wp_register_script(
479 // 'wtotem_country_blocking',
480 // WEBTOTEM_URL . '/includes/js/country-blocking.js',
481 // ['wp-i18n'],
482 // WebTotem::fileVersion('includes/js/country-blocking.js'),
483 // true
484 // );
485 // wp_set_script_translations( 'wtotem_country_blocking', 'wtotem' , WEBTOTEM_PLUGIN_PATH . '/lang/');
486 // wp_enqueue_script('wtotem_country_blocking');
487 }
488
489 wp_register_script(
490 'wtotem_main',
491 WEBTOTEM_URL . '/includes/js/main.js',
492 ['jquery'],
493 WebTotem::fileVersion('includes/js/main.js'),
494 true
495 );
496 wp_enqueue_script('wtotem_main');
497 }
498 }
499