PluginProbe
The WP Remote WordPress Plugin / 6.72
The WP Remote WordPress Plugin v6.72
6.72 6.69 6.65 6.62 6.48 6.47 4.87 4.97 5.05 5.09 5.16 5.22 5.24 5.25 5.38 5.41 5.42 5.45 5.47 5.53 5.56 5.65 5.68 5.72 5.73 All 53 releases
wpremote / protect / fw.php

fw.php in The WP Remote WordPress Plugin 6.72, at protect/fw.php

1,812 lines 58.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 if (!defined('ABSPATH') && !defined('MCDATAPATH')) exit;
3
4 if (!class_exists('WPRProtectFW_V672')) :
5 require_once dirname( __FILE__ ) . '/fw/rule/errors.php';
6 require_once dirname( __FILE__ ) . '/fw/rule/engine.php';
7 require_once dirname( __FILE__ ) . '/fw/rule.php';
8
9 class WPRProtectFW_V672 {
10 private $brand_name;
11 private $protect_mode;
12 private $request;
13 private $ipstore;
14 private $logger;
15
16 private $is_shutdown_cb_set = false;
17 private $is_rule_initialized = false;
18 private $is_wpf_rule_initialized = false;
19 private $is_ip_cookie_set = false;
20 private $is_request_profiled = false;
21 private $is_on_boot_rules_executed = false;
22 private $is_ip_checked_for_blacklisted = false;
23 private $is_ip_whitelisted = null;
24 private $has_valid_bypass_cookie;
25
26 private $mode = WPRProtectFW_V672::MODE_DISABLED;
27 private $ip_cookie_mode = WPRProtectFW_V672::IP_COOKIE_MODE_DISABLED;
28 private $admin_cookie_mode = WPRProtectFW_V672::ADMIN_COOKIE_MODE_DISABLED;
29 private $bypass_level = WPRProtectFW_V672::WP_USER_ROLE_LEVEL_CONTRIBUTOR;
30 private $wpf_rule_init_mode = WPRProtectFW_V672::WPF_RULE_INIT_MODE_WP;
31 private $custom_roles = array();
32 private $cookie_key = "";
33 private $cookie_path = "";
34 private $cookie_domain = "";
35 private $cookie_validity = 2592000;
36 private $can_set_cache_prevention_cookie = false;
37 private $rules_mode = WPRProtectFW_V672::RULES_MODE_DISABLED;
38 private $is_geo_blocking = false;
39 private $is_wp_user_cookie_enabled = false;
40 private $log_config = array();
41 private $request_profiling_mode = WPRProtectFW_V672::REQ_PROFILING_MODE_DISABLED;
42 private $logging_mode = WPRProtectFW_V672::LOGGING_MODE_VISITOR;
43 private $skip_log_config = array();
44 private $skip_log_cookies = array();
45 private $skip_log_headers = array();
46 private $skip_log_post_params = array();
47 private $skip_log_json_params = array();
48 private $wp_user_caps_to_consider = array();
49
50 private $request_profiled_data = array();
51 private $rules = array();
52 private $wpf_rules = array();
53 private $rule_log = array();
54 private $matched_rules = array();
55 private $break_rule_matching = false;
56 private $can_log_raw_body = false;
57 private $log_slice_size = WPRProtectFW_V672::LOG_SLICE_SIZE;
58
59 private static $instance = null;
60
61 const MODE_DISABLED = 1;
62 const MODE_AUDIT = 2;
63 const MODE_PROTECT = 3;
64
65 const RULES_MODE_DISABLED = 1;
66 const RULES_MODE_AUDIT = 2;
67 const RULES_MODE_PROTECT = 3;
68
69 const REQ_PROFILING_MODE_DISABLED = 1;
70 const REQ_PROFILING_MODE_NORMAL = 2;
71 const REQ_PROFILING_MODE_DEBUG = 3;
72
73 const IP_COOKIE_MODE_ENABLED = 1;
74 const IP_COOKIE_MODE_DISABLED = 2;
75
76 const WPF_RULE_INIT_MODE_PREPEND = 1;
77 const WPF_RULE_INIT_MODE_WP = 2;
78
79 const ADMIN_COOKIE_MODE_ENABLED = 1;
80 const ADMIN_COOKIE_MODE_DISABLED = 2;
81
82 const WP_USER_ROLE_LEVEL_UNKNOWN = 0;
83 const WP_USER_ROLE_LEVEL_SUBSCRIBER = 1;
84 const WP_USER_ROLE_LEVEL_CONTRIBUTOR = 2;
85 const WP_USER_ROLE_LEVEL_AUTHOR = 3;
86 const WP_USER_ROLE_LEVEL_EDITOR = 4;
87 const WP_USER_ROLE_LEVEL_ADMIN = 5;
88 const WP_USER_ROLE_LEVEL_CUSTOM = 6;
89
90 #XNOTE: Need clarity.
91 const WS_CONF_MODE_APACHEMODPHP = 1;
92 const WS_CONF_MODE_APACHESUPHP = 2;
93 const WS_CONF_MODE_CGI_FASTCGI = 3;
94 const WS_CONF_MODE_NGINX = 4;
95 const WS_CONF_MODE_LITESPEED = 5;
96 const WS_CONF_MODE_IIS = 6;
97
98 const LOGGING_MODE_VISITOR = 1;
99 const LOGGING_MODE_COMPLETE = 2;
100 const LOGGING_MODE_DISABLED = 3;
101
102 const DEFAULT_WP_USER_ROLE_LEVELS = array(
103 'administrator' => WPRProtectFW_V672::WP_USER_ROLE_LEVEL_ADMIN,
104 'editor' => WPRProtectFW_V672::WP_USER_ROLE_LEVEL_EDITOR,
105 'author' => WPRProtectFW_V672::WP_USER_ROLE_LEVEL_AUTHOR,
106 'contributor' => WPRProtectFW_V672::WP_USER_ROLE_LEVEL_CONTRIBUTOR,
107 'subscriber' => WPRProtectFW_V672::WP_USER_ROLE_LEVEL_SUBSCRIBER
108 );
109
110 const EXTRA_WP_USER_ROLE_LEVELS = array(
111 'custom' => WPRProtectFW_V672::WP_USER_ROLE_LEVEL_CUSTOM,
112 'unknown' => WPRProtectFW_V672::WP_USER_ROLE_LEVEL_UNKNOWN
113 );
114
115 const TABLE_NAME = "fw_requests";
116 const IP_COOKIE_NAME = "mcfw-ip-cookie";
117 const BYPASS_COOKIE_NAME = "mcfw-bypass-cookie";
118 const PREVENT_CACHE_COOKIE_NAME = "wp-mcfw-prevent-cache-cookie";
119
120 const LOG_SLICE_SIZE = 1024;
121
122 private function __construct($protect_mode, $request, $config, $brand_name) {
123 $this->request = $request;
124 $this->brand_name = $brand_name;
125 $this->protect_mode = $protect_mode;
126
127 if (array_key_exists('mode', $config) && is_int($config['mode'])) {
128 $this->mode = $config['mode'];
129 }
130
131 if (array_key_exists('ipcookiemode', $config) && is_int($config['ipcookiemode'])) {
132 $this->ip_cookie_mode = $config['ipcookiemode'];
133 }
134
135 if (array_key_exists('admincookiemode', $config) && is_int($config['admincookiemode'])) {
136 $this->admin_cookie_mode = $config['admincookiemode'];
137 }
138
139 if (array_key_exists('iswpusercookieenabled', $config) &&
140 is_bool($config['iswpusercookieenabled'])) {
141
142 $this->is_wp_user_cookie_enabled = $config['iswpusercookieenabled'];
143 }
144
145 if (array_key_exists('bypasslevel', $config) && is_int($config['bypasslevel'])) {
146 $this->bypass_level = $config['bypasslevel'];
147 }
148
149 if (array_key_exists('wpfruleinitmode', $config) && is_int($config['wpfruleinitmode'])) {
150 $this->wpf_rule_init_mode = $config['wpfruleinitmode'];
151 }
152
153 if (array_key_exists('customroles', $config) && is_array($config['customroles'])) {
154 $this->custom_roles = $config['customroles'];
155 }
156
157 if (array_key_exists('wpusercapstoconsider', $config) &&
158 is_array($config['wpusercapstoconsider'])) {
159
160 $this->wp_user_caps_to_consider = $config['wpusercapstoconsider'];
161 }
162
163 if (array_key_exists('cookiekey', $config) && is_string($config['cookiekey'])) {
164 $this->cookie_key = $config['cookiekey'];
165 }
166
167 if (array_key_exists('cookiepath', $config) && is_string($config['cookiepath'])) {
168 $this->cookie_path = $config['cookiepath'];
169 }
170
171 if (array_key_exists('cookiedomain', $config) && is_string($config['cookiedomain'])) {
172 $this->cookie_domain = $config['cookiedomain'];
173 }
174
175 if (array_key_exists('cookievalidity', $config) && is_int($config['cookievalidity'])) {
176 $this->cookie_validity = $config['cookievalidity'];
177 }
178
179 if (array_key_exists('cansetcachepreventioncookie', $config) &&
180 is_bool($config['cansetcachepreventioncookie'])) {
181
182 $this->can_set_cache_prevention_cookie = $config['cansetcachepreventioncookie'];
183 }
184
185 if (array_key_exists('rulesmode', $config) && is_int($config['rulesmode'])) {
186 $this->rules_mode = $config['rulesmode'];
187 }
188
189 if (array_key_exists('isgeoblocking', $config) && is_bool($config['isgeoblocking'])) {
190 $this->is_geo_blocking = $config['isgeoblocking'];
191 }
192
193 if (array_key_exists('logconfig', $config) && is_array($config['logconfig'])) {
194 $this->log_config = $config['logconfig'];
195 }
196
197 if (array_key_exists('canlograwbody', $this->log_config) &&
198 is_bool($this->log_config['canlograwbody'])) {
199
200 $this->can_log_raw_body = $this->log_config['canlograwbody'];
201 }
202
203 if (array_key_exists('logslicesize', $this->log_config) &&
204 is_int($this->log_config['logslicesize'])) {
205
206 $this->log_slice_size = $this->log_config['logslicesize'];
207 }
208
209 if (array_key_exists('reqprofilingmode', $this->log_config) &&
210 is_int($this->log_config['reqprofilingmode'])) {
211
212 $this->request_profiling_mode = $this->log_config['reqprofilingmode'];
213 }
214
215 if (array_key_exists('loggingmode', $this->log_config) &&
216 is_int($this->log_config['loggingmode'])) {
217
218 $this->logging_mode = $this->log_config['loggingmode'];
219 }
220
221 if (array_key_exists('except', $this->log_config) && is_array($this->log_config['except'])) {
222 $this->skip_log_config = $this->log_config['except'];
223 }
224
225 if (array_key_exists('cookies', $this->skip_log_config) &&
226 is_array($this->skip_log_config['cookies'])) {
227
228 $this->skip_log_cookies = $this->skip_log_config['cookies'];
229 }
230
231 if (array_key_exists('headers', $this->skip_log_config) &&
232 is_array($this->skip_log_config['headers'])) {
233
234 $this->skip_log_headers = $this->skip_log_config['headers'];
235 }
236
237 if (array_key_exists('post', $this->skip_log_config) &&
238 is_array($this->skip_log_config['post'])) {
239
240 $this->skip_log_post_params = $this->skip_log_config['post'];
241 }
242
243 if (array_key_exists('json', $this->skip_log_config) &&
244 is_array($this->skip_log_config['json'])) {
245
246 $this->skip_log_json_params = $this->skip_log_config['json'];
247 }
248
249 if ($this->isPrependMode()) {
250 $log_file = MCDATAPATH . MCCONFKEY . '-mc.log';
251 $this->ipstore = new WPRProtectIpstore_V672(WPRProtectIpstore_V672::STORAGE_TYPE_FS);
252 $this->logger = new WPRProtectLogger_V672($log_file, WPRProtectLogger_V672::TYPE_FS);
253 } else {
254 $this->ipstore = new WPRProtectIpstore_V672(WPRProtectIpstore_V672::STORAGE_TYPE_DB);
255 $this->logger = new WPRProtectLogger_V672(WPRProtectFW_V672::TABLE_NAME, WPRProtectLogger_V672::TYPE_DB);
256 }
257
258 if ($this->is_wp_user_cookie_enabled) {
259 $this->loadWPUser();
260 }
261
262 $this->initRules();
263 }
264
265 public static function getInstance($protect_mode, $request, $config, $brand_name) {
266 if (!isset(self::$instance)) {
267 self::$instance = new self($protect_mode, $request, $config, $brand_name);
268 } elseif (self::$instance->protect_mode != $protect_mode && $protect_mode == WPRProtect_V672::MODE_WP) {
269 self::$instance->protect_mode = $protect_mode;
270 self::$instance->brand_name = $brand_name;
271 self::$instance->ipstore = new WPRProtectIpstore_V672(WPRProtectIpstore_V672::STORAGE_TYPE_DB);
272 self::$instance->initRules();
273 }
274
275 return self::$instance;
276 }
277
278 public static function uninstall() {
279 WPRProtect_V672::$db->dropBVTable(WPRProtectFW_V672::TABLE_NAME);
280 }
281
282 public function init() {
283 if (!$this->isModeDisabled()) {
284 $this->setShutdownCallback();
285 $this->profileRequest();
286 $this->setAdminCookie();
287 $this->setWPUserCookie();
288 $this->setIPCookie();
289 $this->blockRequestForBlacklistedIP();
290 if (!$this->is_on_boot_rules_executed) {
291 $this->handleRequestOnRuleMatch($this->rules);
292
293 $this->is_on_boot_rules_executed = true;
294 }
295 }
296 }
297
298 private function isPrependMode() {
299 return ($this->protect_mode === WPRProtect_V672::MODE_PREPEND);
300 }
301
302 private function isWPMode() {
303 return ($this->protect_mode === WPRProtect_V672::MODE_WP);
304 }
305
306 private function isModeDisabled() {
307 return ($this->mode === WPRProtectFW_V672::MODE_DISABLED);
308 }
309
310 private function isModeProtect() {
311 return ($this->mode === WPRProtectFW_V672::MODE_PROTECT);
312 }
313
314 private function isAdminCookieEnabled() {
315 return ($this->admin_cookie_mode === WPRProtectFW_V672::ADMIN_COOKIE_MODE_ENABLED);
316 }
317
318 private function isIPCookieEnabled() {
319 return ($this->ip_cookie_mode === WPRProtectFW_V672::IP_COOKIE_MODE_ENABLED);
320 }
321
322 private function isRequestProfilingDisabled() {
323 return ($this->request_profiling_mode === WPRProtectFW_V672::REQ_PROFILING_MODE_DISABLED);
324 }
325
326 private function isRequestProfilingModeDebug() {
327 return ($this->request_profiling_mode === WPRProtectFW_V672::REQ_PROFILING_MODE_DEBUG);
328 }
329
330 private function isRequestHasValidBypassCookie() {
331 if (!isset($this->has_valid_bypass_cookie)) {
332 $cookie = (string) $this->request->getCookies(WPRProtectFW_V672::BYPASS_COOKIE_NAME);
333 $new_cookie = $this->generateBypassCookie();
334 $is_valid = ($this->isAdminCookieEnabled() && $new_cookie && ($cookie === $new_cookie));
335 $this->has_valid_bypass_cookie = $is_valid;
336 }
337
338 return $this->has_valid_bypass_cookie;
339 }
340
341 private function isRulesModeProtect() {
342 return ($this->rules_mode === WPRProtectFW_V672::RULES_MODE_PROTECT);
343 }
344
345 public function isLoggingModeComplete() {
346 return ($this->logging_mode === WPRProtectFW_V672::LOGGING_MODE_COMPLETE);
347 }
348
349 public function isLoggingModeVisitor() {
350 return ($this->logging_mode === WPRProtectFW_V672::LOGGING_MODE_VISITOR);
351 }
352
353 public function isGeoBlockingEnabled() {
354 return ($this->is_geo_blocking === true);
355 }
356
357 private function isWPFRuleInitModePrepend() {
358 return ($this->wpf_rule_init_mode === WPRProtectFW_V672::WPF_RULE_INIT_MODE_PREPEND);
359 }
360
361 private function isWPFRuleInitModeWP() {
362 return ($this->wpf_rule_init_mode === WPRProtectFW_V672::WPF_RULE_INIT_MODE_WP);
363 }
364
365 private function canInitWPFRules() {
366 if (!$this->isWPFRuleInitModePrepend() && $this->isPrependMode()) {
367 return false;
368 }
369
370 return true;
371 }
372
373 private function generateBypassCookie() {
374 $time = floor(time() / $this->cookie_validity);
375
376 return hash('sha256', $this->bypass_level . $time . $this->cookie_key);
377 }
378
379 private function getWPFRules($action_name) {
380 if (!array_key_exists($action_name, $this->wpf_rules)) {
381 return array();
382 }
383 return $this->wpf_rules[$action_name];
384 }
385
386 public function setWPUserCookieHandler() {
387 if (function_exists('is_user_logged_in') && is_user_logged_in()) {
388 $current_wp_user = $this->getCurrentWPUser();
389
390 if (!$current_wp_user->isIdentical($this->request->wp_user)) {
391 $serialized_wp_user = WPRProtectWPUser_V672::_serialize($current_wp_user);
392 $cookie_val = $serialized_wp_user . '_' .
393 WPRProtectUtils_V672::signMessage($serialized_wp_user, $this->cookie_key);
394 $cookie_val = base64_encode($cookie_val);
395
396 $this->setCookie(WPRProtectWPUser_V672::COOKIE_NAME, $cookie_val);
397 }
398 } elseif ($this->request->wp_user->isLoggedIn()) {
399 $this->request->wp_user = WPRProtectWPUser_V672::defaultUser();
400 $this->unsetCookie(WPRProtectWPUser_V672::COOKIE_NAME);
401 }
402 }
403
404 private function getCurrentWPUser() {
405 $id = 0;
406 $role_level = 0;
407 $capabilities = array();
408 $time = (int) floor(time() / $this->cookie_validity);
409
410 if (function_exists('wp_get_current_user')) {
411 $user = wp_get_current_user();
412 $id = $user->ID;
413 $role_level = $this->getCurrentWPUserRoleLevel();
414 $capabilities = $this->getCurrentWPUserCapabilities();
415 }
416
417 return (new WPRProtectWPUser_V672($id, $role_level, $capabilities, $time));
418 }
419
420 private function getCurrentWPUserCapabilities() {
421 $capabilities = array();
422
423 if (function_exists('current_user_can')) {
424 foreach ($this->wp_user_caps_to_consider as $capability => $id) {
425 if (current_user_can($capability)) {
426 $capabilities[] = $id;
427 }
428 }
429 sort($capabilities);
430 }
431
432 return $capabilities;
433 }
434
435 private function loadWPUser() {
436 $this->request->wp_user = WPRProtectWPUser_V672::defaultUser();
437
438 $cookie_val = $this->request->getCookies(WPRProtectWPUser_V672::COOKIE_NAME);
439 if (!is_string($cookie_val)) {
440 return;
441 }
442
443 $cookie_val = base64_decode($cookie_val, true);
444 if ($cookie_val === false) {
445 return;
446 }
447
448 $cookie_val_array = explode('_', $cookie_val);
449 if (count($cookie_val_array) !== 2) {
450 return;
451 }
452 list($serialized_user, $signature) = $cookie_val_array;
453
454 if (WPRProtectUtils_V672::verifyMessage($serialized_user, $signature, $this->cookie_key) === true) {
455 $wp_user = WPRProtectWPUser_V672::_unserialize($serialized_user);
456
457 if (!isset($wp_user) || $wp_user->time !== (int) floor(time() / $this->cookie_validity)) {
458 return;
459 }
460
461 $this->request->wp_user = $wp_user;
462
463 $capability_names = array_flip($this->wp_user_caps_to_consider);
464 foreach ($this->request->wp_user->capabilities as $capability) {
465 if (array_key_exists($capability, $capability_names)) {
466 $this->request->wp_user->capability_names[] = $capability_names[$capability];
467 }
468 }
469
470 $role_by_level = array_flip(array_merge(WPRProtectFW_V672::DEFAULT_WP_USER_ROLE_LEVELS,
471 WPRProtectFW_V672::EXTRA_WP_USER_ROLE_LEVELS));
472 $this->request->wp_user->role = $role_by_level[$this->request->wp_user->role_level];
473 }
474 }
475
476 private function pushWPFRule($action_name, $rule) {
477 if (!array_key_exists($action_name, $this->wpf_rules)) {
478 $this->wpf_rules[$action_name] = array();
479 }
480
481 $this->wpf_rules[$action_name][] = $rule;
482 }
483
484 private function initRules() {
485 if (!$this->isRulesModeProtect() || $this->isRequestIPWhitelisted()) {
486 return;
487 }
488
489 if ($this->is_rule_initialized && $this->is_wpf_rule_initialized) {
490 return;
491 }
492
493 if ($this->isPrependMode()) {
494 $rules_file = MCDATAPATH . MCCONFKEY . '-' . 'mc_rules.json';
495 $rule_arrays = WPRProtectUtils_V672::parseFile($rules_file);
496 } else {
497 $rule_arrays = WPRProtect_V672::$settings->getOption('bvruleset');
498 if(!is_array($rule_arrays)) {
499 $rule_arrays = array();
500 }
501 }
502
503 if (empty($rule_arrays)) {
504 $this->updateRuleLog('errors', 'ruleset', 'Invalid RuleSet');
505 return;
506 }
507
508 foreach($rule_arrays as $rule_array) {
509 $rule = WPRProtectFWRule_V672::init($rule_array);
510
511 if ($rule) {
512 if (!$this->is_rule_initialized && $rule->isExeOnBoot()) {
513 if (!$this->isRequestHasValidBypassCookie()) {
514 $this->initRule($rule);
515 }
516 } elseif (!$this->is_wpf_rule_initialized && $this->canInitWPFRules()) {
517 $this->initWPFRule($rule);
518 }
519 }
520 }
521
522 $this->is_rule_initialized = true;
523 if ($this->canInitWPFRules()) {
524 $this->is_wpf_rule_initialized = true;
525 }
526 }
527
528 private function initRule($rule) {
529 $this->rules[] = $rule;
530 }
531
532 private function initWPFRule($rule) {
533 switch ($rule->execute_on) {
534 case WPRProtectFWRule_V672::EXE_ON_PRE_UPDATE_OPTION:
535 $this->addWPHook($rule, 'pre_update_option', 'handleRequestOnPreUpdateOption', 3);
536 break;
537 case WPRProtectFWRule_V672::EXE_ON_PRE_DELETE_POST:
538 $this->addWPHook($rule, 'pre_delete_post', 'handleRequestOnPreDeletePost', 3);
539 break;
540 case WPRProtectFWRule_V672::EXE_ON_WP_INSERT_POST_EMPTY_CONTENT:
541 $this->addWPHook($rule, 'wp_insert_post_empty_content',
542 'handleRequestOnWPInsertPostEmptyContent', 2);
543 break;
544 case WPRProtectFWRule_V672::EXE_ON_INSERT_USER_META:
545 $this->addWPHook($rule, 'insert_user_meta', 'handleRequestOnInsertUserMeta', 4);
546 break;
547 case WPRProtectFWRule_V672::EXE_ON_DELETE_OPTION:
548 $this->addWPHook($rule, 'delete_option', 'handleRequestOnDeleteOption', 1, 'action');
549 break;
550 case WPRProtectFWRule_V672::EXE_ON_DELETE_USER:
551 $this->addWPHook($rule, 'delete_user', 'handleRequestOnDeleteUser', 3, 'action');
552 break;
553 case WPRProtectFWRule_V672::EXE_ON_PASSWORD_RESET:
554 $this->addWPHook($rule, 'password_reset', 'handleRequestOnPasswordReset', 2, 'action');
555 break;
556 case WPRProtectFWRule_V672::EXE_ON_SEND_AUTH_COOKIES:
557 $this->addWPHook($rule, 'send_auth_cookies', 'handleRequestOnSendAuthCookies', 6);
558 break;
559 case WPRProtectFWRule_V672::EXE_ON_SET_AUTH_COOKIE:
560 $this->addWPHook($rule, 'set_auth_cookie', 'handleRequestOnSetAuthCookie', 6, 'action');
561 break;
562 case WPRProtectFWRule_V672::EXE_ON_INIT:
563 $this->addWPHook($rule, 'init', 'handleRequestOnInit', 0, 'action');
564 break;
565 case WPRProtectFWRule_V672::EXE_ON_USER_REGISTER:
566 $this->addWPHook($rule, 'user_register', 'handleRequestOnUserRegister', 2, 'action');
567 break;
568 case WPRProtectFWRule_V672::EXE_ON_ADD_USER_META:
569 $this->addWPHook($rule, 'add_user_meta', 'handleRequestOnAddUserMeta', 3, 'action');
570 break;
571 case WPRProtectFWRule_V672::EXE_ON_UPDATE_USER_METADATA:
572 $this->addWPHook($rule, 'update_user_metadata', 'handleRequestOnUpdateUserMetadata', 5);
573 break;
574 case WPRProtectFWRule_V672::EXE_ON_UPDATE_USER_META:
575 $this->addWPHook($rule, 'update_user_meta', 'handleRequestOnUpdateUserMeta', 4, 'action');
576 break;
577 case WPRProtectFWRule_V672::EXE_ON_ADD_OPTION:
578 $this->addWPHook($rule, 'add_option', 'handleRequestOnAddOption', 2, 'action');
579 break;
580 case WPRProtectFWRule_V672::EXE_ON_WP_PRE_INSERT_USER_DATA:
581 $this->addWPHook($rule, 'wp_pre_insert_user_data', 'handleRequestOnWPPreInsertUserData', 4);
582 break;
583 case WPRProtectFWRule_V672::EXE_ON_REST_REQUEST_BEFORE_CALLBACKS:
584 $this->addWPHook($rule, 'rest_request_before_callbacks',
585 'handleRequestOnRestRequestBeforeCallbacks', 3);
586 break;
587 case WPRProtectFWRule_V672::EXE_ON_ADMIN_INIT:
588 $this->addWPHook($rule, 'admin_init', 'handleRequestOnAdminInit', 0, 'action');
589 break;
590 case WPRProtectFWRule_V672::EXE_ON_WP_HANDLE_UPLOAD_PREFILTER:
591 $this->addWPHook($rule, 'wp_handle_upload_prefilter',
592 'handleRequestOnWPHandleUploadPrefilter', 1);
593 break;
594 case WPRProtectFWRule_V672::EXE_ON_TEMPLATE_REDIRECT:
595 $this->addWPHook($rule, 'template_redirect', 'handleRequestOnTemplateRedirect', 0, 'action');
596 break;
597 case WPRProtectFWRule_V672::EXE_ON_WP_LOADED:
598 $this->addWPHook($rule, 'wp_loaded', 'handleRequestOnWPLoaded', 0, 'action');
599 break;
600 case WPRProtectFWRule_V672::EXE_ON_ADD_POST_METADATA:
601 $this->addWPHook($rule, 'add_post_metadata', 'handleRequestOnAddPostMetadata', 5);
602 break;
603 case WPRProtectFWRule_V672::EXE_ON_UPDATE_POST_METADATA:
604 $this->addWPHook($rule, 'update_post_metadata', 'handleRequestOnUpdatePostMetadata', 5);
605 break;
606 case WPRProtectFWRule_V672::EXE_ON_DELETE_POST_METADATA:
607 $this->addWPHook($rule, 'delete_post_metadata', 'handleRequestOnDeletePostMetadata', 5);
608 break;
609 case WPRProtectFWRule_V672::EXE_ON_ADD_TERM_METADATA:
610 $this->addWPHook($rule, 'add_term_metadata', 'handleRequestOnAddTermMetadata', 5);
611 break;
612 case WPRProtectFWRule_V672::EXE_ON_UPDATE_TERM_METADATA:
613 $this->addWPHook($rule, 'update_term_metadata', 'handleRequestOnUpdateTermMetadata', 5);
614 break;
615 case WPRProtectFWRule_V672::EXE_ON_DELETE_TERM_METADATA:
616 $this->addWPHook($rule, 'delete_term_metadata', 'handleRequestOnDeleteTermMetadata', 5);
617 break;
618 case WPRProtectFWRule_V672::EXE_ON_ADD_COMMENT_METADATA:
619 $this->addWPHook($rule, 'add_comment_metadata', 'handleRequestOnAddCommentMetadata', 5);
620 break;
621 case WPRProtectFWRule_V672::EXE_ON_UPDATE_COMMENT_METADATA:
622 $this->addWPHook($rule, 'update_comment_metadata', 'handleRequestOnUpdateCommentMetadata', 5);
623 break;
624 case WPRProtectFWRule_V672::EXE_ON_DELETE_COMMENT_METADATA:
625 $this->addWPHook($rule, 'delete_comment_metadata', 'handleRequestOnDeleteCommentMetadata', 5);
626 break;
627 case WPRProtectFWRule_V672::EXE_ON_ADD_USER_METADATA:
628 $this->addWPHook($rule, 'add_user_metadata', 'handleRequestOnAddUserMetadata', 5);
629 break;
630 case WPRProtectFWRule_V672::EXE_ON_DELETE_USER_METADATA:
631 $this->addWPHook($rule, 'delete_user_metadata', 'handleRequestOnDeleteUserMetadata', 5);
632 break;
633 }
634 }
635
636 private function addWPHook($rule, $hook_name, $function_name, $accepted_args, $hook_type = 'filter') {
637 //Initialize the hook once for all rule of the same type.
638 if (empty($this->getWPFRules($function_name))) {
639 $callback = array($this, $function_name);
640
641 if ($this->isWPMode()) {
642 if ($hook_type == 'action') {
643 add_action($hook_name, $callback, -9999999, $accepted_args);
644 } else {
645 add_filter($hook_name, $callback, -9999999, $accepted_args);
646 }
647 } else {
648 WPRProtectUtils_V672::preInitWPHook($hook_name, $callback, -9999999, $accepted_args);
649 }
650 }
651
652 $this->pushWPFRule($function_name, $rule);
653 }
654
655 public function handleRequestOnPreUpdateOption($value, $option, $old_value) {
656 $rules = $this->getWPFRules('handleRequestOnPreUpdateOption');
657
658 if (!empty($rules)) {
659 $variables = array('value' => $value, 'option' => $option, 'old_value' => $old_value);
660 $log_data = $variables;
661 $this->handleRequestOnRuleMatch($rules, $variables, $log_data);
662 }
663
664 return $value;
665 }
666
667 public function handleRequestOnPreDeletePost($delete, $post, $force_delete) {
668 $rules = $this->getWPFRules('handleRequestOnPreDeletePost');
669
670 if (!empty($rules)) {
671 $variables = array('delete' => $delete, 'post' => $post, 'force_delete' => $force_delete);
672
673 $log_data = array(
674 'id' => $post->ID,
675 'post_type' => $post->post_type,
676 'post_status' => $post->post_status
677 );
678
679 $this->handleRequestOnRuleMatch($rules, $variables, $log_data);
680 }
681
682 return $delete;
683 }
684
685 public function handleRequestOnWPInsertPostEmptyContent($maybe_empty, $postarr) {
686 $rules = $this->getWPFRules('handleRequestOnWPInsertPostEmptyContent');
687
688 if (!empty($rules)) {
689 $variables = array('maybe_empty' => $maybe_empty, 'postarr' => $postarr);
690
691 $log_data = array();
692 if (isset($postarr['post_type'])) {
693 $log_data['post_type'] = $postarr['post_type'];
694 }
695 if (isset($postarr['ID'])) {
696 $log_data['id'] = $postarr['ID'];
697 }
698
699 $this->handleRequestOnRuleMatch($rules, $variables, $log_data);
700 }
701
702 return $maybe_empty;
703 }
704
705 public function handleRequestOnInsertUserMeta($meta, $user, $update, $userdata = null) {
706 $rules = $this->getWPFRules('handleRequestOnInsertUserMeta');
707
708 if (!empty($rules)) {
709 $variables = array(
710 'meta' => $meta,
711 'update' => $update
712 );
713 $log_data = $variables;
714
715 $variables['userdata'] = $userdata;
716 if (isset($userdata['user_login']) && is_string($userdata['user_login'])) {
717 $log_data['username'] = sanitize_user($userdata['user_login'], true);
718 }
719 if (isset($userdata['role'])) {
720 $log_data['role'] = $userdata['role'];
721 }
722
723 $variables['user'] = $user;
724 $log_data['user'] = $this->getUserLogData($user);
725
726 $this->handleRequestOnRuleMatch($rules, $variables, $log_data);
727 }
728
729 return $meta;
730 }
731
732 public function handleRequestOnDeleteOption($option) {
733 $rules = $this->getWPFRules('handleRequestOnDeleteOption');
734
735 if (!empty($rules)) {
736 $variables = array('option' => $option);
737 $log_data = $variables;
738 $this->handleRequestOnRuleMatch($rules, $variables, $log_data);
739 }
740 }
741
742 public function handleRequestOnDeleteUser($id, $reassign, $user = null) {
743 $rules = $this->getWPFRules('handleRequestOnDeleteUser');
744
745 if (!empty($rules)) {
746 if(is_null($user)) {
747 $user = $this->getUserBy('id', $id);
748 }
749
750 $variables = array('id' => $id, 'reassign' => $reassign);
751 $log_data = $variables;
752
753 $variables['user'] = $user;
754 $log_data['user'] = $this->getUserLogData($user);
755
756 $this->handleRequestOnRuleMatch($rules, $variables, $log_data);
757 }
758 }
759
760 public function handleRequestOnPasswordReset($user, $new_pass) {
761 $rules = $this->getWPFRules('handleRequestOnPasswordReset');
762
763 if (!empty($rules)) {
764 $variables = array('user' => $user, 'new_pass' => $new_pass);
765 $log_data = array(
766 'new_pass' => "MD5: " . md5($new_pass),
767 'user' => $this->getUserLogData($user)
768 );
769 $this->handleRequestOnRuleMatch($rules, $variables, $log_data);
770 }
771 }
772
773 public function handleRequestOnSendAuthCookies($send, $expire = null,
774 $expiration = null, $user_id = null, $scheme = null, $token = null) {
775 $rules = $this->getWPFRules('handleRequestOnSendAuthCookies');
776
777 if (!empty($rules)) {
778 $user = $this->getUserBy('id', $user_id);
779
780 $variables = array(
781 'user_id' => $user_id,
782 'send' => $send,
783 'expire' => $expire,
784 'expiration' => $expiration,
785 'scheme' => $scheme
786 );
787
788 $log_data = $variables;
789 $variables['token'] = $token;
790 $log_data['token'] = "MD5: " . md5($token);
791
792 $variables['user'] = $user;
793 $log_data['user'] = $this->getUserLogData($user);
794
795 $this->handleRequestOnRuleMatch($rules, $variables, $log_data);
796 }
797
798 return $send;
799 }
800
801 public function handleRequestOnSetAuthCookie($auth_cookie, $expire, $expiration, $user_id, $scheme, $token = null) {
802 $rules = $this->getWPFRules('handleRequestOnSetAuthCookie');
803
804 if (!empty($rules)) {
805 $user = $this->getUserBy('id', $user_id);
806
807 $variables = array(
808 'user_id' => $user_id,
809 'auth_cookie' => md5($auth_cookie),
810 'expire' => $expire,
811 'expiration' => $expiration,
812 'scheme' => $scheme
813 );
814
815 $log_data = $variables;
816
817 $variables['token'] = $token;
818 $log_data['token'] = "MD5: " . md5($token);
819
820 $variables['user'] = $user;
821 $log_data['user'] = $this->getUserLogData($user);
822
823 $this->handleRequestOnRuleMatch($rules, $variables, $log_data);
824 }
825 }
826
827 public function handleRequestOnInit() {
828 $rules = $this->getWPFRules('handleRequestOnInit');
829
830 if (!empty($rules)) {
831 $variables = array();
832 $this->handleRequestOnRuleMatch($rules, $variables);
833 }
834 }
835
836 public function handleRequestOnUserRegister($user_id, $userdata = null) {
837 $rules = $this->getWPFRules('handleRequestOnUserRegister');
838
839 if (!empty($rules)) {
840 $user = $this->getUserBy('id', $user_id);
841
842 $variables = array(
843 'user_id' => $user_id,
844 );
845
846 $log_data = $variables;
847
848 $variables['userdata'] = $userdata;
849 $log_data['user'] = $this->getUserLogData($user);
850
851 $this->handleRequestOnRuleMatch($rules, $variables, $log_data);
852 }
853 }
854
855 public function handleRequestOnAddUserMeta($object_id, $meta_key, $meta_value) {
856 $rules = $this->getWPFRules('handleRequestOnAddUserMeta');
857
858 if (!empty($rules)) {
859 $user = $this->getUserBy('id', $object_id);
860
861 $variables = array(
862 'object_id' => $object_id,
863 'meta_key' => $meta_key,
864 'meta_value' => $meta_value
865 );
866 $log_data = $variables;
867
868 $variables['user'] = $user;
869 $log_data['user'] = $this->getUserLogData($user);
870
871 $this->handleRequestOnRuleMatch($rules, $variables, $log_data);
872 }
873 }
874
875 public function handleRequestOnUpdateUserMetadata($check, $object_id, $meta_key, $meta_value, $prev_value) {
876 $rules = $this->getWPFRules('handleRequestOnUpdateUserMetadata');
877
878 if (!empty($rules)) {
879 $user = $this->getUserBy('id', $object_id);
880
881 $variables = array(
882 'check' => $check,
883 'object_id' => $object_id,
884 'meta_key' => $meta_key,
885 'meta_value' => $meta_value,
886 'prev_value' => $prev_value
887 );
888
889 $log_data = $variables;
890
891 $variables['user'] = $user;
892 $log_data['user'] = $this->getUserLogData($user);
893
894 $this->handleRequestOnRuleMatch($rules, $variables, $log_data);
895 }
896
897 return $check;
898 }
899
900 public function handleRequestOnUpdateUserMeta($meta_id, $object_id, $meta_key, $meta_value) {
901 $rules = $this->getWPFRules('handleRequestOnUpdateUserMeta');
902
903 if (!empty($rules)) {
904 $user = $this->getUserBy('id', $object_id);
905
906 $variables = array(
907 'meta_id' => $meta_id,
908 'object_id' => $object_id,
909 'meta_key' => $meta_key,
910 'meta_value' => $meta_value
911 );
912
913 $log_data = $variables;
914
915 $variables['user'] = $user;
916 $log_data['user'] = $this->getUserLogData($user);
917
918 $this->handleRequestOnRuleMatch($rules, $variables, $log_data);
919 }
920 }
921
922 public function handleRequestOnWPPreInsertUserData($data, $update, $user_id, $userdata = null) {
923 $rules = $this->getWPFRules('handleRequestOnWPPreInsertUserData');
924
925 if (!empty($rules)) {
926 $user = $this->getUserBy('id', $user_id);
927
928 $variables = array(
929 'update' => $update,
930 'user_id' => $user_id,
931 );
932 $log_data = $variables;
933
934 $variables['data'] = $data;
935 $variables['userdata'] = $userdata;
936
937 $log_data['data'] = array();
938 if (isset($data['user_login'])) {
939 $log_data['data']['user_login'] = $data['user_login'];
940 }
941 if (isset($data['user_email'])) {
942 $log_data['data']['user_email'] = $data['user_email'];
943 }
944
945 $log_data['userdata'] = array();
946 if (isset($userdata['role'])) {
947 $log_data['userdata']['role'] = $userdata['role'];
948 }
949
950 $variables['user'] = $user;
951 $log_data['user'] = $this->getUserLogData($user);
952
953 $this->handleRequestOnRuleMatch($rules, $variables, $log_data);
954 }
955
956 return $data;
957 }
958
959 public function handleRequestOnAddOption($option, $value) {
960 $rules = $this->getWPFRules('handleRequestOnAddOption');
961
962 if (!empty($rules)) {
963 $variables = array(
964 'option' => $option,
965 'value' => $value
966 );
967 $log_data = $variables;
968
969 $this->handleRequestOnRuleMatch($rules, $variables, $log_data);
970 }
971 }
972
973 private function handleRequestOnLifecycleHook($function_name, $hook_name) {
974 $rules = $this->getWPFRules($function_name);
975
976 if (!empty($rules)) {
977 $variables = $this->getLifecycleHookVariables($hook_name);
978 $this->handleRequestOnRuleMatch($rules, $variables, $variables);
979 }
980 }
981
982 private function getLifecycleHookVariables($hook_name) {
983 $variables = array('hook' => $hook_name);
984
985 if (function_exists('is_admin')) {
986 $variables['is_admin'] = is_admin();
987 }
988
989 if (function_exists('wp_doing_ajax')) {
990 $variables['is_ajax'] = wp_doing_ajax();
991 } else {
992 $variables['is_ajax'] = (defined('DOING_AJAX') && DOING_AJAX);
993 }
994
995 $variables['is_cron'] = (defined('DOING_CRON') && DOING_CRON);
996 $variables['is_rest_request'] = (defined('REST_REQUEST') && REST_REQUEST);
997
998 return $variables;
999 }
1000
1001 public function handleRequestOnAdminInit() {
1002 $this->handleRequestOnLifecycleHook('handleRequestOnAdminInit', 'admin_init');
1003 }
1004
1005 public function handleRequestOnTemplateRedirect() {
1006 $this->handleRequestOnLifecycleHook('handleRequestOnTemplateRedirect', 'template_redirect');
1007 }
1008
1009 public function handleRequestOnWPLoaded() {
1010 $this->handleRequestOnLifecycleHook('handleRequestOnWPLoaded', 'wp_loaded');
1011 }
1012
1013 public function handleRequestOnRestRequestBeforeCallbacks($response, $handler, $request) {
1014 $rules = $this->getWPFRules('handleRequestOnRestRequestBeforeCallbacks');
1015
1016 if (!empty($rules)) {
1017 $this->handleRequestOnRuleMatch($rules);
1018 }
1019
1020 return $response;
1021 }
1022
1023 private function getSafeUploadFileData($file) {
1024 $data = array();
1025
1026 if (!is_array($file)) {
1027 return $data;
1028 }
1029
1030 foreach (array('name', 'type', 'size', 'error') as $key) {
1031 if (array_key_exists($key, $file) && (is_scalar($file[$key]) || is_null($file[$key]))) {
1032 $data[$key] = $file[$key];
1033 }
1034 }
1035
1036 if (array_key_exists('name', $data) && is_string($data['name'])) {
1037 $data['extension'] = strtolower(pathinfo($data['name'], PATHINFO_EXTENSION));
1038 }
1039
1040 return $data;
1041 }
1042
1043 private function getMetadataValueLogData($key, $value) {
1044 $data = array(
1045 $key . '_type' => gettype($value),
1046 $key . '_size' => null
1047 );
1048
1049 if (is_null($value)) {
1050 $data[$key . '_size'] = 0;
1051 } elseif (is_scalar($value)) {
1052 $data[$key . '_size'] = strlen((string) $value);
1053 } elseif (is_array($value)) {
1054 $data[$key . '_count'] = count($value);
1055 } elseif (is_object($value)) {
1056 $data[$key . '_count'] = count(get_object_vars($value));
1057 }
1058
1059 return $data;
1060 }
1061
1062 public function handleRequestOnWPHandleUploadPrefilter($file) {
1063 $rules = $this->getWPFRules('handleRequestOnWPHandleUploadPrefilter');
1064
1065 if (!empty($rules)) {
1066 $safe_file = $this->getSafeUploadFileData($file);
1067 $variables = array('file' => $safe_file);
1068 $this->handleRequestOnRuleMatch($rules, $variables, $variables);
1069 }
1070
1071 return $file;
1072 }
1073
1074 private function handleRequestOnMetadataFilter($function_name, $meta_type, $operation, $check,
1075 $object_id, $meta_key, $meta_value, $extra = array()) {
1076
1077 $rules = $this->getWPFRules($function_name);
1078
1079 if (!empty($rules)) {
1080 $variables = array_merge(array(
1081 'check' => $check,
1082 'meta_type' => $meta_type,
1083 'operation' => $operation,
1084 'object_id' => $object_id,
1085 'meta_key' => $meta_key,
1086 'meta_value' => $meta_value
1087 ), $extra);
1088
1089 $log_extra = $extra;
1090 if (array_key_exists('prev_value', $log_extra)) {
1091 $prev_value = $log_extra['prev_value'];
1092 unset($log_extra['prev_value']);
1093 $log_extra = array_merge($log_extra, $this->getMetadataValueLogData('prev_value', $prev_value));
1094 }
1095
1096 $log_data = array_merge(array(
1097 'meta_type' => $meta_type,
1098 'operation' => $operation,
1099 'object_id' => $object_id,
1100 'meta_key' => $meta_key
1101 ), $this->getMetadataValueLogData('meta_value', $meta_value), $log_extra);
1102
1103 $this->handleRequestOnRuleMatch($rules, $variables, $log_data);
1104 }
1105
1106 return $check;
1107 }
1108
1109 public function handleRequestOnAddPostMetadata($check, $object_id, $meta_key, $meta_value, $unique) {
1110 return $this->handleRequestOnMetadataFilter('handleRequestOnAddPostMetadata',
1111 'post', 'add', $check, $object_id, $meta_key, $meta_value, array('unique' => $unique));
1112 }
1113
1114 public function handleRequestOnUpdatePostMetadata($check, $object_id, $meta_key, $meta_value, $prev_value) {
1115 return $this->handleRequestOnMetadataFilter('handleRequestOnUpdatePostMetadata',
1116 'post', 'update', $check, $object_id, $meta_key, $meta_value, array('prev_value' => $prev_value));
1117 }
1118
1119 public function handleRequestOnDeletePostMetadata($check, $object_id, $meta_key, $meta_value, $delete_all) {
1120 return $this->handleRequestOnMetadataFilter('handleRequestOnDeletePostMetadata',
1121 'post', 'delete', $check, $object_id, $meta_key, $meta_value, array('delete_all' => $delete_all));
1122 }
1123
1124 public function handleRequestOnAddTermMetadata($check, $object_id, $meta_key, $meta_value, $unique) {
1125 return $this->handleRequestOnMetadataFilter('handleRequestOnAddTermMetadata',
1126 'term', 'add', $check, $object_id, $meta_key, $meta_value, array('unique' => $unique));
1127 }
1128
1129 public function handleRequestOnUpdateTermMetadata($check, $object_id, $meta_key, $meta_value, $prev_value) {
1130 return $this->handleRequestOnMetadataFilter('handleRequestOnUpdateTermMetadata',
1131 'term', 'update', $check, $object_id, $meta_key, $meta_value, array('prev_value' => $prev_value));
1132 }
1133
1134 public function handleRequestOnDeleteTermMetadata($check, $object_id, $meta_key, $meta_value, $delete_all) {
1135 return $this->handleRequestOnMetadataFilter('handleRequestOnDeleteTermMetadata',
1136 'term', 'delete', $check, $object_id, $meta_key, $meta_value, array('delete_all' => $delete_all));
1137 }
1138
1139 public function handleRequestOnAddCommentMetadata($check, $object_id, $meta_key, $meta_value, $unique) {
1140 return $this->handleRequestOnMetadataFilter('handleRequestOnAddCommentMetadata',
1141 'comment', 'add', $check, $object_id, $meta_key, $meta_value, array('unique' => $unique));
1142 }
1143
1144 public function handleRequestOnUpdateCommentMetadata($check, $object_id, $meta_key, $meta_value, $prev_value) {
1145 return $this->handleRequestOnMetadataFilter('handleRequestOnUpdateCommentMetadata',
1146 'comment', 'update', $check, $object_id, $meta_key, $meta_value, array('prev_value' => $prev_value));
1147 }
1148
1149 public function handleRequestOnDeleteCommentMetadata($check, $object_id, $meta_key, $meta_value, $delete_all) {
1150 return $this->handleRequestOnMetadataFilter('handleRequestOnDeleteCommentMetadata',
1151 'comment', 'delete', $check, $object_id, $meta_key, $meta_value, array('delete_all' => $delete_all));
1152 }
1153
1154 public function handleRequestOnAddUserMetadata($check, $object_id, $meta_key, $meta_value, $unique) {
1155 return $this->handleRequestOnMetadataFilter('handleRequestOnAddUserMetadata',
1156 'user', 'add', $check, $object_id, $meta_key, $meta_value, array('unique' => $unique));
1157 }
1158
1159 public function handleRequestOnDeleteUserMetadata($check, $object_id, $meta_key, $meta_value, $delete_all) {
1160 return $this->handleRequestOnMetadataFilter('handleRequestOnDeleteUserMetadata',
1161 'user', 'delete', $check, $object_id, $meta_key, $meta_value, array('delete_all' => $delete_all));
1162 }
1163
1164 private function setShutdownCallback() {
1165 if (!$this->is_shutdown_cb_set) {
1166 register_shutdown_function(array($this, 'log'));
1167 $this->is_shutdown_cb_set = true;
1168 }
1169 }
1170
1171 private function setCookie($name, $value, $expire = null) {
1172 if ($expire === null) {
1173 $expire = time() + $this->cookie_validity;
1174 }
1175
1176 $path = $this->cookie_path;
1177 $cookie_domain = $this->cookie_domain;
1178
1179 if (version_compare(PHP_VERSION, '5.2.0') >= 0) {
1180 $secure = function_exists('is_ssl') ? is_ssl() : false;
1181 @setcookie($name, $value, $expire, $path, $cookie_domain, $secure, true);
1182 } else {
1183 @setcookie($name, $value, $expire, $path);
1184 }
1185 }
1186
1187 private function unsetCookie($name) {
1188 $pastTime = time() - 3600;
1189 $this->setCookie($name, '', $pastTime);
1190 }
1191
1192 private function setAdminCookie() {
1193 if ($this->isWPMode() && $this->isAdminCookieEnabled()) {
1194 add_action('init', array($this, 'setBypassCookie'));
1195 }
1196 }
1197
1198 private function setWPUserCookie() {
1199 if ($this->isWPMode() && $this->is_wp_user_cookie_enabled) {
1200 add_action('init', array($this, 'setWPUserCookieHandler'), -9999999);
1201 }
1202 }
1203
1204 private function setIPCookie() {
1205 if (!$this->is_ip_cookie_set && $this->isIPCookieEnabled() &&
1206 !$this->request->getCookies(WPRProtectFW_V672::IP_COOKIE_NAME)) {
1207
1208 $time = floor(time() / 86400);
1209 $cookie = hash('sha256', $this->request->ip . $time . $this->cookie_key);
1210 if ($cookie) {
1211 $this->setCookie(WPRProtectFW_V672::IP_COOKIE_NAME, $cookie, time() + 86400);
1212 }
1213 }
1214 }
1215
1216 private function getCurrentWPUserRoleLevel() {
1217 if (function_exists('current_user_can')) {
1218 if (function_exists('is_super_admin') && is_super_admin()) {
1219 return WPRProtectFW_V672::WP_USER_ROLE_LEVEL_ADMIN;
1220 }
1221
1222 foreach ($this->custom_roles as $role) {
1223 if (current_user_can($role)) {
1224 return WPRProtectFW_V672::WP_USER_ROLE_LEVEL_CUSTOM;
1225 }
1226 }
1227
1228 foreach (WPRProtectFW_V672::DEFAULT_WP_USER_ROLE_LEVELS as $role => $level) {
1229 if (current_user_can($role)) {
1230 return $level;
1231 }
1232 }
1233 }
1234
1235 return 0;
1236 }
1237
1238 public function canLogRequest() {
1239 $can_log = false;
1240
1241 if ($this->isLoggingModeComplete()) {
1242 $can_log = true;
1243 } elseif ($this->isLoggingModeVisitor()) {
1244 $can_log = (!empty($this->matched_rules) || !$this->isRequestHasValidBypassCookie());
1245 }
1246
1247 return $can_log;
1248 }
1249
1250 public function log() {
1251 if ($this->canLogRequest()) {
1252 $this->logger->log($this->getRequestDataToLog());
1253 }
1254 }
1255
1256 private function canLogValue($key, $prefix) {
1257 switch ($prefix) {
1258 case 'BODY[':
1259 return $this->canLogPostValue($key);
1260 case 'COOKIES[':
1261 return $this->canLogCookieValue($key);
1262 case 'JSON[':
1263 return $this->canLogJsonValue($key);
1264 case 'HEADERS[':
1265 return $this->canLogHeaderValue($key);
1266 }
1267
1268 return true;
1269 }
1270
1271 private function canLogPostValue($key) {
1272 if (is_string($key) && in_array($key, $this->skip_log_post_params)) {
1273 return false;
1274 }
1275
1276 return true;
1277 }
1278
1279 private function canLogCookieValue($key) {
1280 if (is_string($key) && in_array($key, $this->skip_log_cookies)) {
1281 return false;
1282 }
1283
1284 return true;
1285 }
1286
1287 private function canLogHeaderValue($key) {
1288 if (is_string($key) && in_array($key, $this->skip_log_headers)) {
1289 return false;
1290 }
1291
1292 return true;
1293 }
1294
1295 private function canLogJsonValue($key) {
1296 return $this->canLogKeyValue($key, $this->skip_log_json_params);
1297 }
1298
1299 private function canLogKeyValue($key, $skip_params) {
1300 if (is_string($key) && in_array($key, $skip_params)) {
1301 return false;
1302 }
1303
1304 return true;
1305 }
1306
1307 private function getParamsToLog($params, $type) {
1308 $loggable_params = array();
1309
1310 if (is_array($params)) {
1311 foreach ($params as $key => $value) {
1312 if (is_array($value)) {
1313 $loggable_params[$key] = $this->getParamsToLog($value, $type);
1314 } else {
1315 if ($type == "POST" && !$this->canLogPostValue($key)) {
1316 $loggable_params[$key] = "Sensitive Data";
1317 } else if ($type == "JSON" && !$this->canLogJsonValue($key)) {
1318 $loggable_params[$key] = "Sensitive Data";
1319 } else {
1320 $loggable_params[$key] = $this->getSlicedValueToLog($value);
1321 }
1322 }
1323 }
1324 }
1325
1326 return $loggable_params;
1327 }
1328
1329 private function getRawBodyToLog($content) {
1330 return $this->getSlicedValueToLog($content);
1331 }
1332
1333 private function getBVCookies() {
1334 $cookies = array();
1335
1336 if ($this->request->getCookies(WPRProtectFW_V672::IP_COOKIE_NAME) !== NULL) {
1337 $cookie_val = (string) $this->request->getCookies(WPRProtectFW_V672::IP_COOKIE_NAME);
1338 $cookies[WPRProtectFW_V672::IP_COOKIE_NAME] = $cookie_val;
1339 }
1340
1341 return $cookies;
1342 }
1343
1344 private function getCookiesToLog($cookies) {
1345 $loggable_cookies = array();
1346
1347 if (is_array($cookies)) {
1348 foreach ($cookies as $key => $value) {
1349 if (!$this->canLogCookieValue($key)) {
1350 $loggable_cookies[$key] = "SensitiveData:" . md5($value);
1351 } else {
1352 $loggable_cookies[$key] = $value;
1353 }
1354 }
1355 }
1356
1357 return $loggable_cookies;
1358 }
1359
1360 private function getHeadersToLog($headers) {
1361 $loggable_headers = array();
1362
1363 if (is_array($headers)) {
1364 foreach ($headers as $key => $value) {
1365 if (!$this->canLogHeaderValue($key)) {
1366 $loggable_headers[$key] = "SensitiveData:" . md5($value);
1367 } else {
1368 $loggable_headers[$key] = $value;
1369 }
1370 }
1371 }
1372
1373 return $loggable_headers;
1374 }
1375
1376 private function getSlicedValueToLog($value, $size = null) {
1377 if (!is_scalar($value)) {
1378 return "Logging of " . gettype($value) . " is not supported.";
1379 }
1380
1381 if ($size === null) {
1382 $size = $this->log_slice_size;
1383 }
1384
1385 $loggable_value = '';
1386
1387 $valsize = $this->getLength($value);
1388 if ($valsize > $size) {
1389 $value = substr((string) $value, 0, $size);
1390 $loggable_value = "Data too long: {$valsize} : {$value}";
1391 } else {
1392 $loggable_value = $value;
1393 }
1394
1395 return $loggable_value;
1396 }
1397
1398 private function getRequestDataToLog() {
1399 $referer = $this->request->getHeader('Referer') ? $this->request->getHeader('Referer') : '';
1400 $user_agent = $this->request->getHeader('User-Agent')
1401 ? $this->request->getHeader('User-Agent') : '';
1402
1403 $rule_log = serialize($this->rule_log);
1404 if (strlen($rule_log) > 64000) {
1405 $rule_log = substr($rule_log, 0, 64000);
1406 }
1407
1408 $request_profiled_data = serialize($this->request_profiled_data);
1409 if (strlen($request_profiled_data) > 16000) {
1410 $request_profiled_data = serialize(array("keys" => array_keys($this->request_profiled_data)));
1411 if (strlen($request_profiled_data) > 16000) {
1412 $request_profiled_data = serialize(array("bv_over_size" => true));
1413 }
1414 }
1415
1416 $data = array(
1417 "path" => $this->request->path,
1418 "filenames" => serialize($this->request->file_names),
1419 "host" => $this->request->host,
1420 "time" => $this->request->timestamp,
1421 "ip" => $this->request->ip,
1422 "method" => $this->request->method,
1423 "query_string" => $request_profiled_data,
1424 "user_agent" => $user_agent,
1425 "resp_code" => $this->request->getRespCode(),
1426 "referer" => $referer,
1427 "status" => $this->request->status,
1428 "category" => $this->request->category,
1429 "rules_info" => $rule_log,
1430 "request_id" => $this->request->getRequestID(),
1431 "matched_rules"=> serialize($this->matched_rules)
1432 );
1433
1434 return $data;
1435 }
1436
1437 private function getLength($val) {
1438 $length = 0;
1439
1440 if (is_array($val)) {
1441 foreach ($val as $e) {
1442 $length += $this->getLength($e);
1443 }
1444
1445 return $length;
1446 } else {
1447 return strlen((string) $val);
1448 }
1449 }
1450
1451 private function matchCount($pattern, $subject) {
1452 $count = 0;
1453 if (is_array($subject)) {
1454 foreach ($subject as $val) {
1455 $count += $this->matchCount($pattern, $val);
1456 }
1457 return $count;
1458 } else {
1459 $count = preg_match_all((string) $pattern, (string) $subject, $matches);
1460 return ($count === false ? 0 : $count);
1461 }
1462 }
1463
1464 private function updateRuleLog($category, $sub_category, $value) {
1465 $category_data = array();
1466 $sub_category_data = array();
1467
1468 if (array_key_exists($category, $this->rule_log)) {
1469 $category_data = $this->rule_log[$category];
1470 }
1471
1472 if (array_key_exists($sub_category, $category_data)) {
1473 $sub_category_data = $category_data[$sub_category];
1474 }
1475
1476 $sub_category_data[] = $value;
1477 $category_data[$sub_category] = $sub_category_data;
1478
1479 $this->rule_log[$category] = $category_data;
1480 }
1481
1482 private function inspectRequest() {
1483 if (isset($this->request->wp_user)) {
1484 $this->updateRuleLog('inspect', "wpUserInfo", $this->request->wp_user->getInfo());
1485 }
1486
1487 $this->updateRuleLog('inspect', "headers", $this->getHeadersToLog($this->request->getHeaders()));
1488 $this->updateRuleLog('inspect', "cookies", $this->getCookiesToLog($this->request->getCookies()));
1489 $this->updateRuleLog('inspect', "getParams", $this->request->getGetParams());
1490 $this->updateRuleLog('inspect', "postParams", $this->getParamsToLog($this->request->getPostParams(), "POST"));
1491 $this->updateRuleLog('inspect', "jsonParams", $this->getParamsToLog($this->request->getJsonParams(), "JSON"));
1492 $this->updateRuleLog('inspect', "bodyParserStatus", $this->request->getBodyParserStatus());
1493 if ($this->can_log_raw_body) {
1494 $raw_body = $this->request->getRawBody();
1495 if (!empty($raw_body)) {
1496 $this->updateRuleLog('inspect', "rawBody", $this->getRawBodyToLog($raw_body));
1497 }
1498 }
1499 }
1500
1501 private function getUserBy($attribute, $value) {
1502 if (isset($value) && function_exists('get_user_by') && WPRProtectUtils_V672::havePluginsLoaded()) {
1503 return get_user_by($attribute, $value);
1504 }
1505 }
1506
1507 private function getUserLogData($user) {
1508 $user_data = array();
1509
1510 if (is_a($user, "WP_User")) {
1511 $user_data = array(
1512 'id' => $user->ID,
1513 'user_login' => $user->user_login,
1514 'user_email' => $user->user_email,
1515 'allcaps' => $user->allcaps,
1516 'roles' => $user->roles
1517 );
1518 }
1519
1520 return $user_data;
1521 }
1522
1523 private function profileRequestData($params, $debug = false, $prefix = '', $obraces = 1) {
1524 $profiled_data = array();
1525
1526 if (is_array($params)) {
1527 foreach ($params as $key => $value) {
1528 $original_key = $key;
1529 $key = $prefix . $key;
1530 if (is_array($value)) {
1531 $profiled_data = $profiled_data + $this->profileRequestData($value, $debug, $key . '[', $obraces + 1);
1532 } else {
1533 $key = $key . str_repeat(']', $obraces);
1534 $profiled_data[$key] = array();
1535 $valsize = $this->getLength($value);
1536 $profiled_data[$key]["size"] = $valsize;
1537 if ($debug === true && $valsize < 256 && $this->canLogValue($original_key, $prefix)) {
1538 $profiled_data[$key]["value"] = $value;
1539 continue;
1540 }
1541
1542 if (WPRHelper::safePregMatch('/^\d+$/', $value)) {
1543 $profiled_data[$key]["numeric"] = true;
1544 } elseif (WPRHelper::safePregMatch('/^\w+$/', $value)) {
1545 $profiled_data[$key]["regular_word"] = true;
1546 } elseif (WPRHelper::safePregMatch('/^\S+$/', $value)) {
1547 $profiled_data[$key]["special_word"] = true;
1548 } elseif (WPRHelper::safePregMatch('/^[\w\s]+$/', $value)) {
1549 $profiled_data[$key]["regular_sentence"] = true;
1550 } elseif (WPRHelper::safePregMatch('/^[\w\W]+$/', $value)) {
1551 $profiled_data[$key]["special_chars_sentence"] = true;
1552 }
1553
1554 if (WPRHelper::safePregMatch('/^\b((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\.){3}
1555 (25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\b$/x', $value)) {
1556 $profiled_data[$key]["ipv4"] = true;
1557 } elseif (WPRHelper::safePregMatch('/\b((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\.){3}
1558 (25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\b/x', $value)) {
1559 $profiled_data[$key]["embeded_ipv4"] = true;
1560 } elseif (WPRHelper::safePregMatch('/^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|
1561 ([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|
1562 ([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}
1563 (:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|
1564 ([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|
1565 :((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|
1566 ::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3}
1567 (25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|
1568 (2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))$/x', $value)) {
1569 $profiled_data[$key]["ipv6"] = true;
1570 } elseif (WPRHelper::safePregMatch('/(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|
1571 ([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|
1572 ([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}
1573 (:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|
1574 ([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|
1575 :((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|
1576 ::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3}
1577 (25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|
1578 (2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))/x', $value)) {
1579 $profiled_data[$key]["embeded_ipv6"] = true;
1580 }
1581
1582 if (WPRHelper::safePregMatch('/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,6}$/', $value)) {
1583 $profiled_data[$key]["email"] = true;
1584 } elseif (WPRHelper::safePregMatch('/[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,6}/', $value)) {
1585 $profiled_data[$key]["embeded_email"] = true;
1586 }
1587
1588 if (WPRHelper::safePregMatch('/^(http|ftp)s?:\/\/\S+$/i', $value)) {
1589 $profiled_data[$key]["link"] = true;
1590 } elseif (WPRHelper::safePregMatch('/(http|ftp)s?:\/\/\S+$/i', $value)) {
1591 $profiled_data[$key]["embeded_link"] = true;
1592 }
1593
1594 if (WPRHelper::safePregMatch('/<(html|head|title|base|link|meta|style|picture|source|img|
1595 iframe|embed|object|param|video|audio|track|map|area|form|label|input|button|
1596 select|datalist|optgroup|option|textarea|output|progress|meter|fieldset|legend|
1597 script|noscript|template|slot|canvas)/ix', $value)) {
1598 $profiled_data[$key]["embeded_html"] = true;
1599 }
1600
1601 if (WPRHelper::safePregMatch('/\.(jpg|jpeg|png|gif|ico|pdf|doc|docx|ppt|pptx|pps|ppsx|odt|xls|zip|gzip|
1602 xlsx|psd|mp3|m4a|ogg|wav|mp4|m4v|mov|wmv|avi|mpg|ogv|3gp|3g2|php|html|phtml|js|css)/ix', $value)) {
1603 $profiled_data[$key]["file"] = true;
1604 }
1605
1606 if ($this->matchCount(WPRProtectFWRule_V672::SQLIREGEX, $value) > 2) {
1607 $profiled_data[$key]["sql"] = true;
1608 }
1609
1610 if (WPRHelper::safePregMatch('/(?:\.{2}[\/]+)/', $value)) {
1611 $profiled_data[$key]["path_traversal"] = true;
1612 }
1613
1614 if (WPRHelper::safePregMatch('/\\b(?i:eval)\\s*\\(\\s*(?i:base64_decode|exec|file_get_contents|gzinflate|passthru|shell_exec|stripslashes|system)\\s*\\(/', $value)) {
1615 $profiled_data[$key]["php_eval"] = true;
1616 }
1617 }
1618 }
1619 }
1620
1621 return $profiled_data;
1622 }
1623
1624 private function profileRequest() {
1625 if (!$this->is_request_profiled && !$this->isRequestProfilingDisabled()) {
1626 $profiled_data = array();
1627 $log_raw_body = true;
1628
1629 $is_debug_mode = $this->isRequestProfilingModeDebug();
1630
1631 $content_type = $this->request->getContentType();
1632 if (is_string($content_type)) {
1633 $profiled_data += array("CONTENT_TYPE" => $this->getSlicedValueToLog($content_type));
1634 }
1635
1636 $content_length = $this->request->getContentLength();
1637 if (is_string($content_length)) {
1638 $profiled_data += array("CONTENT_LENGTH" => $this->getSlicedValueToLog($content_length));
1639 }
1640
1641 $action = $this->request->getAction();
1642 if (isset($action)) {
1643 $profiled_data += $this->profileRequestData(array("action" => $action), true, 'ACTION[');
1644 }
1645
1646 if (isset($this->request->wp_user)) {
1647 $wp_user_info = array(
1648 'id' => $this->request->wp_user->id
1649 );
1650 $profiled_data += $this->profileRequestData($wp_user_info, true, 'WP_USER[');
1651 }
1652
1653 $profiled_data += $this->profileRequestData($this->request->getGetParams(), true, 'GET[');
1654 $profiled_data += $this->profileRequestData($this->request->getFiles(), true, 'FILES[');
1655
1656 $cookies = $is_debug_mode ? $this->request->getCookies() : $this->getBVCookies();
1657 $profiled_data += $this->profileRequestData($cookies, true, 'COOKIES[');
1658
1659 if (!empty($this->request->getPostParams())) {
1660 $profiled_data += $this->profileRequestData($this->request->getPostParams(), $is_debug_mode, 'BODY[');
1661 $log_raw_body = false;
1662 }
1663
1664 $json_params = $this->request->getJsonParams();
1665 if (!empty($json_params) && !empty($json_params['JSON'])) {
1666 $profiled_data += $this->profileRequestData($json_params, $is_debug_mode, 'JSON[');
1667 $log_raw_body = false;
1668 }
1669
1670 if ($this->can_log_raw_body && $is_debug_mode && $log_raw_body && !empty($this->request->getRawBody())) {
1671 $profiled_data += array("RAW_BODY" => $this->getRawBodyToLog($this->request->getRawBody()));
1672 }
1673
1674 $body_parser_status = $this->request->getBodyParserStatus();
1675 $profiled_data = array(
1676 "BODY_RAW_STATUS" => $body_parser_status['raw_body_status'],
1677 "JSON_PARAMS_STATUS" => $body_parser_status['json_params_status']
1678 ) + $profiled_data;
1679
1680 $this->request_profiled_data = $profiled_data;
1681 $this->is_request_profiled = true;
1682 }
1683 }
1684
1685 private function isRequestIPWhitelisted() {
1686 if (!isset($this->is_ip_whitelisted)) {
1687 $this->is_ip_whitelisted = $this->ipstore->isFWIPWhitelisted($this->request->ip);
1688 }
1689
1690 return $this->is_ip_whitelisted;
1691 }
1692
1693 private function canRequestBypassFirewall() {
1694 if ($this->isRequestIPWhitelisted() || $this->isRequestHasValidBypassCookie()) {
1695 $this->request->category = WPRProtectRequest_V672::CATEGORY_WHITELISTED;
1696 $this->request->status = WPRProtectRequest_V672::STATUS_BYPASSED;
1697
1698 return true;
1699 } elseif (WPRProtectUtils_V672::isPrivateIP($this->request->ip)) {
1700 $this->request->category = WPRProtectRequest_V672::CATEGORY_PRIVATEIP;
1701 $this->request->status = WPRProtectRequest_V672::STATUS_BYPASSED;
1702
1703 return true;
1704 }
1705
1706 return false;
1707 }
1708
1709 private function blockRequestForBlacklistedIP() {
1710 if (!$this->canRequestBypassFirewall() && $this->isModeProtect()) {
1711 if (!$this->is_ip_checked_for_blacklisted ||
1712 ($this->isWPMode() && $this->isGeoBlockingEnabled())) {
1713
1714 $ip_category = $this->ipstore->getTypeIfBlacklistedIP($this->request->ip);
1715 if ($ip_category) {
1716 $this->terminateRequest($ip_category);
1717 }
1718
1719 $this->is_ip_checked_for_blacklisted = true;
1720 }
1721 }
1722 }
1723
1724 private function handleRequestOnRuleMatch($rules, $engine_vars = array(), $log_data = array()) {
1725 $normalized_engine_vars = WPRProtectFWRuleEngine_V672::normalizeVariables($engine_vars);
1726
1727 foreach ($rules as $rule) {
1728 if ($this->break_rule_matching) {
1729 break;
1730 }
1731
1732 $_engine_vars = $normalized_engine_vars;
1733 if (array_key_exists('variables', $rule->opts)) {
1734 $_engine_vars = array_merge($_engine_vars,
1735 WPRProtectFWRuleEngine_V672::normalizeVariables($rule->opts['variables']));
1736 }
1737
1738 $rule_engine = new WPRProtectFWRuleEngine_V672($this->request, $_engine_vars);
1739
1740 if ($rule_engine->evaluate($rule) && !$rule_engine->hasError()) {
1741 if (!empty($log_data)) {
1742 $this->updateRuleLog("info", (string) $rule->id, $log_data);
1743 }
1744
1745 $this->matched_rules[] = $rule->id;
1746
1747 foreach($rule->actions as $action) {
1748 switch ($action["type"]) {
1749 case "ALLOW":
1750 $this->break_rule_matching = true;
1751 $this->request->category = WPRProtectRequest_V672::CATEGORY_RULE_ALLOWED;
1752 return;
1753 case "BLOCK":
1754 if ($this->isModeProtect()) {
1755 $this->terminateRequest(WPRProtectRequest_V672::CATEGORY_RULE_BLOCKED);
1756 }
1757 return;
1758 case "INSPECT":
1759 $this->inspectRequest();
1760 break;
1761 }
1762 }
1763 } elseif ($rule_engine->hasError()) {
1764 $this->updateRuleLog("errors", (string) $rule->id, $rule_engine->getErrorMessage());
1765 }
1766 }
1767 }
1768
1769 private function terminateRequest($category) {
1770 $this->request->category = $category;
1771 $this->request->status = WPRProtectRequest_V672::STATUS_BLOCKED;
1772 $this->request->setRespCode(403);
1773
1774 if ($this->can_set_cache_prevention_cookie &&
1775 !$this->request->getCookies(WPRProtectFW_V672::PREVENT_CACHE_COOKIE_NAME)) {
1776 $value = "Prevent Caching Response.";
1777 $this->setCookie(WPRProtectFW_V672::PREVENT_CACHE_COOKIE_NAME, $value, time() + 43200);
1778 }
1779
1780 header("Cache-Control: no-cache, no-store, must-revalidate");
1781 header("Pragma: no-cache");
1782 header("Expires: 0");
1783 header('HTTP/1.0 403 Forbidden');
1784 // phpcs:disable WordPress.Security.EscapeOutput.OutputNotEscaped
1785 die("
1786 <div style='height: 98vh;'>
1787 <div style='text-align: center; padding: 10% 0; font-family: Arial, Helvetica, sans-serif;'>
1788 <div><p>" . $this->brand_name . " Firewall</p></div>
1789 <p>Blocked because of Malicious Activities</p>
1790 <p>Reference ID: " . $this->request->getRequestID() . "</p>
1791 </div>
1792 </div>
1793 ");
1794 // phpcs:enable WordPress.Security.EscapeOutput.OutputNotEscaped
1795 }
1796
1797 public function setBypassCookie() {
1798 if (function_exists('is_user_logged_in') && is_user_logged_in() &&
1799 !$this->isRequestHasValidBypassCookie()) {
1800
1801 $role_level = $this->getCurrentWPUserRoleLevel();
1802 if ($role_level >= $this->bypass_level) {
1803 $cookie = $this->generateBypassCookie();
1804 if ($cookie) {
1805 $this->setCookie(WPRProtectFW_V672::BYPASS_COOKIE_NAME, $cookie);
1806 }
1807 }
1808 }
1809 }
1810 }
1811 endif;
1812