PluginProbe
Defender Security – Malware Scanner, Login Security & Firewall / 6.3.0
Defender Security – Malware Scanner, Login Security & Firewall v6.3.0
6.3.0 6.2.3 6.2.4 6.2.0 6.2.1 6.2.2 6.1.0 5.3.1 5.4.0 5.4.1 5.5.0 5.5.1 5.6.0 5.6.1 5.6.2 5.7.0 5.7.1 5.7.2 5.8.0 5.8.1 5.9.0 6.0.0 6.0.1 3.0.1 3.1.0 All 141 releases
← All changes | src/model/setting/class-user-agent-lockout.php +63 -111 5.6.0 → 6.3.0 View file →
@@ -34,9 +34,9 @@
34 34 *
35 35 * @var bool
36 36 * @defender_property
37 37 */
38 - public $enabled = false;
38 + public bool $enabled = false;
39 39
40 40 /**
41 41 * Blacklist User Agents.
42 42 *
@@ -107,9 +107,9 @@
107 107 *
108 108 * @var bool
109 109 * @defender_property
110 110 */
111 - public $malicious_bot_enabled = false;
111 + public bool $malicious_bot_enabled = false;
112 112
113 113 /**
114 114 * How the lock is going to be, if we choose permanent, then their IP will be blacklisted.
115 115 *
@@ -151,9 +151,9 @@
151 151 *
152 152 * @var bool
153 153 * @defender_property
154 154 */
155 - public $fake_bots_enabled = false;
155 + public bool $fake_bots_enabled = false;
156 156
157 157 /**
158 158 * How the lock is going to be, if we choose permanent, then their IP will be blacklisted.
159 159 *
@@ -196,9 +196,9 @@
196 196 *
197 197 * @var bool
198 198 * @defender_property
199 199 */
200 - public $bot_trap_enabled = false;
200 + public bool $bot_trap_enabled = false;
201 201
202 202 /**
203 203 * How the lock is going to be, if we choose permanent, then their IP will be blacklisted.
204 204 *
@@ -231,9 +231,20 @@
231 231 *
232 232 * @var array
233 233 */
234 234 protected $rules = array(
235 - array( array( 'enabled', 'empty_headers', 'blocklist_presets', 'script_presets' ), 'boolean' ),
235 + array(
236 + array(
237 + 'enabled',
238 + 'empty_headers',
239 + 'blocklist_presets',
240 + 'script_presets',
241 + 'malicious_bot_enabled',
242 + 'bot_trap_enabled',
243 + 'fake_bots_enabled',
244 + ),
245 + 'boolean',
246 + ),
236 247 array( array( 'malicious_bot_lockout_type' ), 'in', self::BOT_LOCKOUT_TYPE_ALLOWED ),
237 248 array( array( 'malicious_bot_lockout_duration_unit' ), 'in', self::BOT_LOCKOUT_DURATION_UNIT_ALLOWED ),
238 249 array( array( 'fake_bots_lockout_type' ), 'in', self::BOT_LOCKOUT_TYPE_ALLOWED ),
239 250 array( array( 'fake_bots_lockout_duration_unit' ), 'in', self::BOT_LOCKOUT_DURATION_UNIT_ALLOWED ),
@@ -292,18 +303,20 @@
292 303 *
293 304 * @return bool Returns true if the User Agent Lockout feature is active, false otherwise.
294 305 */
295 306 public function is_active(): bool {
296 - return (bool) apply_filters(
307 + $enable = apply_filters(
297 308 'wd_user_agents_enable',
298 309 $this->enabled
299 310 );
311 +
312 + return is_bool( $enable ) ? $enable : (bool) $enable;
300 313 }
301 314
302 315 /**
303 - * Get list of blocklisted or allowlisted data.
316 + * Get a list of blocklisted or allowlisted data.
304 317 *
305 - * @param string $type blocklist|allowlist.
318 + * @param string $type blocklist|allowlist.
306 319 * @param bool $lower Whether to convert the list to lowercase.
307 320 *
308 321 * @return array
309 322 */
@@ -308,15 +321,31 @@
308 321 * @return array
309 322 */
310 323 public function get_lockout_list( $type = 'blocklist', $lower = true ): array {
311 324 $data = 'blocklist' === $type ? $this->blacklist : $this->whitelist;
312 - $arr = array_filter( preg_split( "/\r\n|\n|\r/", $data ), 'boolval' );
313 - $arr = array_map( 'trim', $arr );
325 + $data = trim( $data );
326 +
327 + if ( '' === $data ) {
328 + return array();
329 + }
330 +
331 + $arr = preg_split( "/\r\n|\n|\r/", $data );
332 + if ( ! is_array( $arr ) ) {
333 + return array();
334 + }
335 +
314 336 if ( $lower ) {
315 - $arr = array_map( 'strtolower', $arr );
337 + $arr = array_map(
338 + function ( $value ) {
339 + return strtolower( trim( $value ) );
340 + },
341 + $arr
342 + );
343 + } else {
344 + $arr = array_map( 'trim', $arr );
316 345 }
317 346
318 - return $arr;
347 + return array_unique( $arr );
319 348 }
320 349
321 350 /**
322 351 * Define settings labels.
@@ -340,10 +369,10 @@
340 369 *
341 370 * @return array
342 371 */
343 372 public function get_access_status( $ua ): array {
344 - $blocklist = str_replace( '#', '\#', $this->get_all_selected_blocklist_ua() );
345 - $allowlist = str_replace( '#', '\#', $this->get_lockout_list( 'allowlist' ) );
373 + $blocklist = $this->get_all_selected_blocklist_ua();
374 + $allowlist = $this->get_lockout_list( 'allowlist' );
346 375
347 376 // Escape regex special characters in each item before building the pattern.
348 377 $blocklist_escaped = array_map( 'preg_quote', $blocklist, array_fill( 0, count( $blocklist ), '#' ) );
349 378 $allowlist_escaped = array_map( 'preg_quote', $allowlist, array_fill( 0, count( $allowlist ), '#' ) );
@@ -350,12 +379,12 @@
350 379
351 380 $blocklist_regex_pattern = '#' . implode( '|', $blocklist_escaped ) . '#i';
352 381 $allowlist_regex_pattern = '#' . implode( '|', $allowlist_escaped ) . '#i';
353 382
354 - $blocklist_match = preg_match( $blocklist_regex_pattern, $ua );
355 - $allowlist_match = preg_match( $allowlist_regex_pattern, $ua );
383 + $blocklist_match = count( $blocklist ) > 0 && 1 === preg_match( $blocklist_regex_pattern, $ua );
384 + $allowlist_match = count( $allowlist ) > 0 && 1 === preg_match( $allowlist_regex_pattern, $ua );
356 385
357 - if ( 1 !== $blocklist_match && 1 !== $allowlist_match ) {
386 + if ( ! $blocklist_match && ! $allowlist_match ) {
358 387 return array( 'na' );
359 388 }
360 389
361 390 $result = array();
@@ -360,14 +389,14 @@
360 389
361 390 $result = array();
362 391
363 392 // Check blocklist first - if it matches, add 'banned'.
364 - if ( 1 === $blocklist_match ) {
393 + if ( $blocklist_match ) {
365 394 $result[] = 'banned';
366 395 }
367 396
368 397 // Check allowlist - if it matches, add 'allowlist'.
369 - if ( 1 === $allowlist_match ) {
398 + if ( $allowlist_match ) {
370 399 $result[] = 'allowlist';
371 400 }
372 401
373 402 return $result;
@@ -373,100 +402,8 @@
373 402 return $result;
374 403 }
375 404
376 405 /**
377 - * Checks if a user agent is present in a given list.
378 - *
379 - * @param string $ua The user agent to check.
380 - * @param string $collection The type of list to check against ('blocklist' or 'allowlist').
381 - *
382 - * @return bool Returns true if the user agent is in the list, false otherwise.
383 - */
384 - public function is_ua_in_list( $ua, $collection ): bool {
385 - if ( 'allowlist' === $collection ) {
386 - $arr = str_replace( '#', '\#', $this->get_lockout_list( $collection ) );
387 - } else {
388 - $arr = str_replace( '#', '\#', $this->get_all_selected_blocklist_ua() );
389 - }
390 -
391 - // Escape regex special characters in each item before building the pattern.
392 - $arr_escaped = array_map( 'preg_quote', $arr, array_fill( 0, count( $arr ), '#' ) );
393 - $list_regex_pattern = '#' . implode( '|', $arr_escaped ) . '#i';
394 -
395 - return 1 === preg_match( $list_regex_pattern, $ua );
396 - }
397 -
398 - /**
399 - * Remove User Agent from a list.
400 - *
401 - * @param string $ua The user agent to remove.
402 - * @param string $collection blocklist|allowlist.
403 - *
404 - * @return void
405 - */
406 - public function remove_from_list( $ua, $collection ) {
407 - if ( 'allowlist' === $collection ) {
408 - $arr = $this->get_lockout_list( $collection );
409 - // Array can contain uppercase.
410 - $orig_arr = str_replace( '#', '\#', $this->get_lockout_list( $collection, false ) );
411 - } else {
412 - $arr = $this->get_all_selected_blocklist_ua();
413 - // Array can contain uppercase.
414 - $orig_arr = str_replace( '#', '\#', $this->get_all_selected_blocklist_ua( false ) );
415 - }
416 -
417 - $list_regex_pattern = '#' . implode( '|', $arr ) . '#i';
418 - $list_match = preg_match( $list_regex_pattern, $ua );
419 - if ( false !== $list_match ) {
420 - if ( 'blocklist' === $collection ) {
421 - // Check in 'Blocklist Presets'.
422 - if ( $this->blocklist_presets ) {
423 - $key = array_search( $ua, $this->blocklist_preset_values, true );
424 - if ( false !== $key ) {
425 - unset( $this->blocklist_preset_values[ $key ] );
426 - $this->blocklist_preset_values = array_values( $this->blocklist_preset_values );
427 - }
428 - }
429 - // Check in 'Script Presets' using Regex.
430 - if ( $this->script_presets ) {
431 - if ( false !== strpos( $ua, User_Agent_Service::GO_HTTP_CLIENT_KEY . '/' ) ) {
432 - $key_script_preset = User_Agent_Service::GO_HTTP_CLIENT_KEY;
433 - } elseif ( false !== strpos( $ua, User_Agent_Service::PYTHON_REQUESTS_KEY . '/' ) ) {
434 - $key_script_preset = User_Agent_Service::PYTHON_REQUESTS_KEY;
435 - } else {
436 - $key_script_preset = '';
437 - }
438 -
439 - $key = array_search( $key_script_preset, $this->script_preset_values, true );
440 - if ( false !== $key ) {
441 - unset( $this->script_preset_values[ $key ] );
442 - $this->script_preset_values = array_values( $this->script_preset_values );
443 - }
444 - }
445 - // Check 'Custom User Agents' case.
446 - $arr_blocklist = $this->get_lockout_list( 'blocklist', false );
447 - if ( array() !== $arr_blocklist ) {
448 - $key = array_search( $ua, $arr_blocklist, true );
449 - if ( false !== $key && isset( $arr_blocklist[ $key ] ) ) {
450 - unset( $arr_blocklist[ $key ] );
451 - // Convert back to string.
452 - $this->blacklist = implode( PHP_EOL, $arr_blocklist );
453 - }
454 - }
455 - } elseif ( 'allowlist' === $collection ) {
456 - $key = array_search( $ua, $arr, true );
457 - if ( false !== $key && isset( $arr[ $key ] ) ) {
458 - unset( $arr[ $key ] );
459 - // Convert back to string.
460 - $this->whitelist = implode( PHP_EOL, $arr );
461 - }
462 - }
463 -
464 - $this->save();
465 - }
466 - }
467 -
468 - /**
469 406 * Add an UA to the list.
470 407 *
471 408 * @param string $ua User agent name.
472 409 * @param string $collection blocklist|allowlist.
@@ -504,8 +441,23 @@
504 441 $arr[] = trim( $ua );
505 442 $arr = array_unique( $arr );
506 443
507 444 return implode( PHP_EOL, $arr );
445 + }
446 +
447 + /**
448 + * Filter the UAs, as we use a textarea to submit, so it can contain some un-valid UAs.
449 + */
450 + protected function after_validate(): void {
451 + $this->blacklist = implode(
452 + PHP_EOL,
453 + array_filter( $this->get_lockout_list( 'blocklist' ), 'strlen' )
454 + );
455 +
456 + $this->whitelist = implode(
457 + PHP_EOL,
458 + array_filter( $this->get_lockout_list( 'allowlist' ), 'strlen' )
459 + );
508 460 }
509 461
510 462 /**
511 463 * Get the module name.