PluginProbe
WebTotem Security / trunk
WebTotem Security vtrunk
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 trunk, at lib/Interface.php

489 lines 15.4 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 }
106 }
107
108
109 if (!WebTotemOption::isActivated() and version_compare(WEBTOTEM_VERSION, '3.0.3', '<=')) {
110 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'));
111 }
112
113 }
114
115 /**
116 * Checking whether agents are installed, if they are not installed, then install.
117 */
118 private static function checkAgents(){
119
120 $api_key = WebTotemOption::getOption('api_key');
121
122 $host = WebTotemAPI::siteInfo();
123
124 if ($api_key && array_key_exists('id', $host) && $host['id']) {
125
126 // Install Agent Manager if it was not previously installed.
127 $am_installed = WebTotemAgentManager::checkInstalledService('am');
128 if (!$am_installed['file_status']) {
129
130 $am_was_installed = WebTotemAgentManager::amInstall();
131
132 if (!$am_was_installed) {
133 WebTotemOption::setOptions(['am_installed' => FALSE]);
134 }
135 }
136
137 }
138 }
139
140 /**
141 * Checking whether the site added date has been saved, if not, then requests the data and saves.
142 */
143 private static function checkSiteAddedDate(){
144 if (WebTotemRequest::get('hid')) {
145 $host = WebTotemOption::getHost(WebTotemRequest::get('hid'));
146 } else {
147 $host = WebTotemAPI::siteInfo();
148 }
149
150 $site_created_at = WebTotemOption::getOption('site_created_at');
151
152 $site_created_at = $site_created_at ? json_decode($site_created_at, true) : [];
153
154 if(!array_key_exists($host['name'], $site_created_at)){
155 $createdAt = WebTotemAPI::getGetSiteAddedDate($host['name']);
156 if($createdAt){
157 WebTotemOption::setOptions(['site_created_at' => [ $host['name'] => $createdAt] ]);
158 }
159 }
160 }
161
162 /**
163 * When adding a new site, add it to the WebTotem platform.
164 */
165 public static function addNewSite($new_site){
166 $domain = untrailingslashit($new_site->domain . $new_site->path);
167
168 WebTotemAPI::addMultiSiteNewSites([$domain]);
169 }
170
171 /**
172 * Verify the nonce of the previous page after a form submission.
173 *
174 * @return bool True if the nonce is valid, false otherwise.
175 */
176 public static function checkNonce() {
177 if (!empty($_POST)) {
178 $name = 'wtotem_page_nonce';
179 $value = WebTotemRequest::post($name);
180
181 if (!$value || !wp_verify_nonce($value, $name)) {
182 WebTotemOption::setNotification('error', __('The WordPress CSRF check failed. The submitted form is missing an important unique code. Go back and try again.', 'wtotem'));
183 return false;
184 }
185 }
186
187 return true;
188 }
189
190 /**
191 * Add 2fa to the profile form.
192 *
193 * @return void
194 */
195 public static function add2faProfileForm(){
196
197 if(!WebTotemLogin::isTwoFactorEnabled()){ return; }
198
199 if ( isset( $_GET['user_id'] ) ) {
200 if( !current_user_can( 'manage_options' ) ){
201 return;
202 }
203 $user_id = (int) $_GET['user_id'];
204 $user = get_user_by( 'id', $user_id );
205 } else {
206 $user = wp_get_current_user();
207 }
208
209 $current_user = wp_get_current_user();
210
211 if ( ! is_a( $user, '\WP_User' ) || ! is_a( $current_user, '\WP_User' ) ) {
212 return;
213 }
214
215 $composer_autoload = WEBTOTEM_PLUGIN_PATH . '/vendor/autoload.php';
216 if ( file_exists( $composer_autoload ) ) {
217 require_once $composer_autoload;
218 }
219
220 $template = new WebTotemTemplate();
221
222 $build[] = [
223 'template' => 'two_factor_user_profile_modal',
224 'variables' => [
225 'two_factor' => WebTotemLogin::getTwoFactorData($user),
226 'user_id' => $user_id ?? $user->ID,
227 'can_manage_options' => current_user_can( 'manage_options' )
228 ],
229 ];
230
231 $page_content = $template->arrayRender($build);
232 echo $page_content;
233 }
234
235 /**
236 * Authentication.
237 *
238 * @return mixed
239 */
240 public static function wt_authenticate($user, $username = null, $password = null) {
241
242 if(WebTotemCaptcha::isEnabled()) {
243 if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
244 return $user;
245 }
246 $token = WebTotemCaptcha::get_token();
247 $score = WebTotemCaptcha::score($token, WebTotemOption::getPluginSettings('recaptcha_v3_secret'));
248 if($score < 0.5) {
249 return new \WP_Error('authentication_failed', __('<strong>ERROR</strong>&nbsp;: Please check the ReCaptcha box or try to reload page.','wtotem'));
250 }
251 }
252
253 if(isset($_POST['wtotem-token']) && is_string($_POST['wtotem-token']) && !empty($_POST['wtotem-token'])){
254 if ( is_object( $user ) && ( $user instanceof \WP_User ) ) {
255 if ( WebTotemLogin::hasUser2faActivated( $user ) ) {
256 $check2faCode = WebTotemLogin::check2faCode( $user, $_POST['wtotem-token']);
257
258 if ( ! $check2faCode ) {
259 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() ) ) );
260 }
261 }
262 }
263 }
264
265 return WebTotemBFProtection::checkBruteForceAttempts($user, $username);
266 }
267
268 /**
269 * Password brute force protection.
270 *
271 * @return mixed
272 */
273 public static function wt_lost_password($errors = null, $user_data = null) {
274 return WebTotemBFProtection::lostPassword($errors);
275 }
276
277 /**
278 * Restore and then hide the readme file when updating the WordPress.
279 *
280 * @param string $string
281 * @return string
282 */
283 public static function restoreReadmeWhenUpdating($string) {
284 static $didRun;
285 if (!isset($didRun)) {
286 $didRun = true;
287 WebTotemOption::restoreReadme();
288 register_shutdown_function('WebTotemOption::hideReadme');
289 }
290
291 return $string;
292 }
293
294 /**
295 * Login Page
296 */
297 public static function loginEnqueueScripts() {
298
299 $recaptcha_enabled = WebTotemCaptcha::isEnabled();
300 if ($recaptcha_enabled) {
301 $recaptcha_site_key = WebTotemOption::getPluginSettings('recaptcha_v3_site_key');
302 wp_enqueue_script('wtotem_recaptcha', 'https://www.google.com/recaptcha/api.js?render=' . $recaptcha_site_key);
303 }
304
305 wp_register_script(
306 'wtotem_login',
307 WEBTOTEM_URL . '/includes/js/login.js',
308 ['jquery'],
309 WebTotem::fileVersion('includes/js/login.js'),
310 false
311 );
312 wp_enqueue_script('wtotem_login');
313
314 wp_register_style(
315 'wtotem_login',
316 WEBTOTEM_URL . '/includes/css/login.css',
317 [],
318 WebTotem::fileVersion('includes/css/login.css')
319 );
320 wp_enqueue_style('wtotem_login');
321
322 wp_localize_script('wtotem_login', 'wtotem_login_vars', [
323 'recaptcha_site_key' => WebTotemCaptcha::_siteKey(),
324 'recaptcha_is_enabled' => $recaptcha_enabled,
325 'ajaxurl' => admin_url('admin-ajax.php', 'relative'),
326 'two_factor_is_enabled' => WebTotemLogin::isTwoFactorEnabled() and WebTotemLogin::anyTwoFactorActivated(),
327 ]);
328 }
329
330 /**
331 * Added a pop-up window to the plugins page
332 */
333 public static function registerDeletePrompt() {
334 wp_register_style(
335 'wtotem_prompt_css',
336 WEBTOTEM_URL . '/includes/css/prompt.css',
337 [],
338 WebTotem::fileVersion('includes/css/prompt.css')
339 );
340 wp_enqueue_style('wtotem_prompt_css');
341
342 $composer_autoload = WEBTOTEM_PLUGIN_PATH . '/vendor/autoload.php';
343 if ( file_exists( $composer_autoload ) ) {
344 require_once $composer_autoload;
345 }
346
347 $template = new WebTotemTemplate();
348 $build[] = [
349 'variables' => [
350 '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'),
351 'action' => 'reinstall_agents',
352 'page_nonce' => wp_create_nonce('wtotem_page_nonce'),
353 ],
354 'template' => 'prompt',
355 ];
356
357 echo $template->arrayRender($build);
358 }
359
360 /**
361 * A safe way to add JavaScript and css files to a WordPress-managed page
362 *
363 * @return void
364 */
365 public static function enqueueScripts() {
366
367 // Adding CSS files.
368 wp_register_style(
369 'wtotem_flatpickr',
370 WEBTOTEM_URL . '/includes/css/flatpickr.min.css',
371 [],
372 WebTotem::fileVersion('includes/css/flatpickr.min.css')
373 );
374 wp_enqueue_style('wtotem_flatpickr');
375
376 wp_register_style(
377 'wtotem_toastr_css',
378 WEBTOTEM_URL . '/includes/css/toastr.min.css',
379 [],
380 WebTotem::fileVersion('includes/css/toastr.min.css')
381 );
382 wp_enqueue_style('wtotem_toastr_css');
383
384 wp_register_style(
385 'wtotem_main_css',
386 WEBTOTEM_URL . '/includes/css/main.css',
387 [],
388 WebTotem::fileVersion('includes/css/main.css')
389 );
390 wp_enqueue_style('wtotem_main_css');
391
392 // Adding JS files.
393 wp_register_script(
394 'wtotem_amplitude',
395 WEBTOTEM_URL . '/includes/js/amplitude.js',
396 [ 'jquery' ],
397 WebTotem::fileVersion('includes/js/amplitude.js'),
398 false
399 );
400 wp_enqueue_script('wtotem_amplitude');
401
402 wp_register_script(
403 'wtotem_d3',
404 WEBTOTEM_URL . '/includes/js/d3.v4.js',
405 ['jquery'],
406 WebTotem::fileVersion('includes/js/d3.v4.js'),
407 true
408 );
409 wp_enqueue_script('wtotem_d3');
410
411 wp_register_script(
412 'wtotem_chart',
413 WEBTOTEM_URL . '/includes/js/chart.js',
414 ['jquery', 'wtotem_d3', 'wtotem_jsdelivr'],
415 WebTotem::fileVersion('includes/js/chart.js'),
416 true
417 );
418 wp_enqueue_script('wtotem_chart');
419
420 wp_register_script(
421 'wtotem_flatpickr_js',
422 WEBTOTEM_URL . '/includes/js/flatpickr.js',
423 [ 'jquery', 'wp-i18n' ],
424 WebTotem::fileVersion('includes/js/flatpickr.js'),
425 true
426 );
427 wp_set_script_translations( 'wtotem_flatpickr_js', 'wtotem', WEBTOTEM_PLUGIN_PATH . '/lang/');
428 wp_enqueue_script('wtotem_flatpickr_js');
429
430 wp_register_script(
431 'wtotem_jsdelivr',
432 WEBTOTEM_URL . '/includes/js/jsdelivr_chart.js',
433 [ 'jquery' ],
434 WebTotem::fileVersion('includes/js/jsdelivr_chart.js'),
435 true
436 );
437 wp_enqueue_script('wtotem_jsdelivr');
438
439 wp_register_script(
440 'wtotem_jquery_qrcode',
441 WEBTOTEM_URL . '/includes/js/jquery.qrcode.min.js',
442 [ 'jquery' ],
443 WebTotem::fileVersion('includes/js/jquery.qrcode.min.js'),
444 true
445 );
446 wp_enqueue_script('wtotem_jquery_qrcode');
447
448 wp_register_script(
449 'wtotem_progress_bar',
450 WEBTOTEM_URL . '/includes/js/progress_bar.js',
451 [],
452 WebTotem::fileVersion('includes/js/progress_bar.js'),
453 true
454 );
455 wp_enqueue_script('wtotem_progress_bar');
456
457 wp_register_script(
458 'wtotem_toastr',
459 WEBTOTEM_URL . '/includes/js/toastr.min.js',
460 [],
461 WebTotem::fileVersion('includes/js/toastr.min.js'),
462 true
463 );
464 wp_enqueue_script('wtotem_toastr');
465
466 $_page = WebTotemRequest::get('page');
467 if($_page === 'wtotem_settings'){
468 // wp_register_script(
469 // 'wtotem_country_blocking',
470 // WEBTOTEM_URL . '/includes/js/country-blocking.js',
471 // ['wp-i18n'],
472 // WebTotem::fileVersion('includes/js/country-blocking.js'),
473 // true
474 // );
475 // wp_set_script_translations( 'wtotem_country_blocking', 'wtotem' , WEBTOTEM_PLUGIN_PATH . '/lang/');
476 // wp_enqueue_script('wtotem_country_blocking');
477 }
478
479 wp_register_script(
480 'wtotem_main',
481 WEBTOTEM_URL . '/includes/js/main.js',
482 ['jquery'],
483 WebTotem::fileVersion('includes/js/main.js'),
484 true
485 );
486 wp_enqueue_script('wtotem_main');
487 }
488 }
489