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/controller/class-antibot-global-firewall.php +99 -97 5.8.0 → 6.3.0 View file →
@@ -71,8 +71,10 @@
71 71 $this->model = $model;
72 72 $this->service = $service;
73 73 $this->wpmudev = $wpmudev;
74 74
75 + add_action( 'admin_init', array( $this, 'maybe_hcm_connection_attempt' ), 20 );
76 + add_action( 'wpdef_hub_connector_synced', array( $this, 'maybe_hcm_connection_attempt' ) );
75 77 add_action( 'wpmudev_hub_connector_first_sync_completed', array( $this, 'maybe_hcm_connection_attempt' ) );
76 78
77 79 /**
78 80 * Download and store Blocklist from the API.
@@ -97,9 +99,8 @@
97 99 if ( $this->wpmudev->is_wpmu_hosting() ) {
98 100 add_action( 'init', array( $this, 'sync_state' ) );
99 101 }
100 102 add_action( 'init', array( $this, 'handle_expired_membership' ) );
101 - add_action( 'init', array( $this->service, 'maybe_set_notice_time' ) );
102 103 }
103 104
104 105 /**
105 106 * Handle request to save settings.
@@ -126,9 +127,9 @@
126 127 'redirect_to_feature_page' => array( 'type' => 'bool' ),
127 128 // End.
128 129 )
129 130 );
130 - $old_enabled = (bool) $this->model->enabled;
131 + $old_enabled = $this->model->enabled;
131 132
132 133 $location = 'Feature Page';
133 134 // Split module's titles and locations.
134 135 if ( isset( $data['module_title'] ) && 'antibot' === $data['module_title'] ) {
@@ -165,13 +166,8 @@
165 166 }
166 167 }
167 168
168 169 Config_Hub_Helper::set_clear_active_flag();
169 -
170 - // Hide the Antibot notice on the Dashboard page.
171 - if ( isset( $data['enabled'] ) && true === (bool) $data['enabled'] ) {
172 - delete_site_option( Antibot_Global_Firewall_Component::NOTICE_SLUG );
173 - }
174 170 // Maybe track.
175 171 if ( ! defender_is_wp_cli() && $old_enabled !== $data['enabled'] ) {
176 172 wd_di()->get( Antibot_Analytics::class )->track_antibot( $old_enabled, $location );
177 173 }
@@ -179,9 +175,9 @@
179 175 $update_message = $this->get_update_message( $data, $old_enabled, Antibot_Global_Firewall_Setting::get_module_name() );
180 176 $referrer = wp_get_referer();
181 177 if ( $referrer && strpos( $referrer, 'page=wp-defender' ) !== false ) {
182 178 $update_message = sprintf(
183 - /* translators: 1: Bold open tag, 2: Bold close tag */
179 + /* translators: 1: Module name. */
184 180 __( '%s is now enabled.', 'defender-security' ),
185 181 '<strong>' . Antibot_Global_Firewall_Setting::get_module_name() . '</strong>'
186 182 );
187 183 }
@@ -210,27 +206,15 @@
210 206 );
211 207 }
212 208
213 209 /**
214 - * Hide the Antibot notice.
215 - *
216 - * @return Response
217 - * @defender_route
218 - */
219 - public function hide_antibot_notice(): Response {
220 - delete_site_option( Antibot_Global_Firewall_Component::NOTICE_SLUG );
221 -
222 - return new Response( true, array() );
223 - }
224 -
225 - /**
226 210 * Queue assets and require data.
227 211 *
228 212 * @return void
229 213 */
230 214 public function enqueue_assets() {
231 - if ( $this->is_page_active() ) {
232 - wp_localize_script( 'def-iplockout', 'antibot', $this->data_frontend() );
215 + if ( ! $this->is_page_active() ) {
216 + return;
233 217 }
234 218 }
235 219
236 220 /**
@@ -238,22 +222,8 @@
238 222 *
239 223 * @return array
240 224 */
241 225 public function data_frontend(): array {
242 - /**
243 - * Show the onboarding reminder notice if:
244 - * 1. If the reminder time is set and the time difference is greater than a week.
245 - * 2. No click on the Cross icon before.
246 - */
247 - $is_reminder = false;
248 - $last_reminder = (int) get_site_option( Onboard::REMINDER_KEY, 0 );
249 - if ( $last_reminder > 0 ) {
250 - $time_diff = time() - $last_reminder;
251 - if ( $time_diff > WEEK_IN_SECONDS ) {
252 - $is_reminder = true;
253 - }
254 - }
255 -
256 226 $model_export = $this->model->export();
257 227 $model_export['managed_by'] = $this->service->get_managed_by();
258 228 $module_name = Antibot_Global_Firewall_Setting::get_module_name();
259 229
@@ -260,31 +230,30 @@
260 230 return array_merge(
261 231 array(
262 232 'model' => $model_export,
263 233 'misc' => array(
264 - 'module_slug' => Antibot_Global_Firewall_Setting::get_module_slug(),
265 - 'module_name' => $module_name,
266 - 'show_notice' => $is_reminder
267 - && (bool) get_site_option( Antibot_Global_Firewall_Component::NOTICE_SLUG, false ),
268 - 'sync_schedule' => __( 'Twice Daily', 'defender-security' ),
269 - 'ips_count' => $this->service->get_blocklisted_ip_count(),
270 - 'frontend_is_enabled' => $this->service->frontend_is_enabled(),
271 - 'frontend_mode' => $this->service->frontend_mode(),
272 - 'is_active' => $this->service->is_active(),
273 - 'show_stats_button' => ! $this->wpmudev->is_whitelabel_enabled(),
274 - 'show_checker' => ! $this->wpmudev->is_wpmu_hosting()
234 + 'module_slug' => Antibot_Global_Firewall_Setting::get_module_slug(),
235 + 'module_name' => $module_name,
236 + 'show_notice' => false,
237 + 'sync_schedule' => __( 'Twice Daily', 'defender-security' ),
238 + 'ips_count' => $this->service->get_blocklisted_ip_count(),
239 + 'blocklist_stats_full' => $this->service->get_cached_blocklist_stats_data(),
240 + 'frontend_is_enabled' => $this->service->frontend_is_enabled(),
241 + 'frontend_mode' => $this->service->frontend_mode(),
242 + 'is_active' => $this->service->is_active(),
243 + 'show_stats_button' => ! $this->wpmudev->is_whitelabel_enabled(),
244 + 'show_checker' => ! $this->wpmudev->is_wpmu_hosting()
275 245 || $this->wpmudev->is_wpmu_dev_admin()
276 246 || ! ( $this->service->is_active_via_hosting() && $this->wpmudev->is_whitelabel_enabled() ),
277 - 'active_tooltip_text' => __( 'List of exploit attempts detected and blocked across all connected sites by AntiBot Firewall.', 'defender-security' ),
278 - 'inactive_tooltip_text' => sprintf(
247 + 'active_tooltip_text' => __( 'List of exploit attempts detected and blocked across all connected sites by AntiBot Firewall.', 'defender-security' ),
248 + 'inactive_tooltip_text' => sprintf(
279 249 /* translators: %s: Module name. */
280 250 __( '%s is Inactive.', 'defender-security' ),
281 251 $module_name
282 252 ),
283 - 'current_user' => esc_html( wp_get_current_user()->display_name ?? __( 'User', 'defender-security' ) ),
284 - 'current_plan' => $this->get_membership_type(),
285 - 'is_expired_membership' => $this->is_expired_membership_type(),
286 - 'should_show_global_notice' => $this->service->should_show_global_notice(),
253 + 'current_user' => esc_html( wp_get_current_user()->display_name ?? __( 'User', 'defender-security' ) ),
254 + 'is_expired_membership' => $this->is_expired_membership_type(),
255 + 'show_antibot_options' => $this->service->get_states_of_antibot_options_for_different_hosting_types(),
287 256 ),
288 257 ),
289 258 $this->dump_routes_and_nonces()
290 259 );
@@ -329,9 +298,9 @@
329 298 public function maybe_hcm_connection_attempt() {
330 299 $data = get_site_transient( Hub_Connector::TRANSIENT_KEY );
331 300 $module_slug = $data['module_slug'] ?? '';
332 301
333 - if ( Antibot_Global_Firewall_Setting::get_module_slug() === $module_slug && self::get_status() ) {
302 + if ( Antibot_Global_Firewall_Setting::get_module_slug() === $module_slug && self::get_hcm_status() ) {
334 303 delete_site_transient( Hub_Connector::TRANSIENT_KEY );
335 304
336 305 if ( 'plugin' === $this->service->get_managed_by() ) {
337 306 $this->service->managed_by_plugin_action();
@@ -377,13 +346,16 @@
377 346 */
378 347 public function remove_data() {
379 348 $this->service->delete_blocklist();
380 349
350 + delete_site_option( Antibot_Global_Firewall_Component::DOWNLOAD_SYNC_NEXT_RUN_OPTION );
351 + // Don't display Antibot global notice. We can delete slugs about this notice in the future.
381 352 delete_site_option( Antibot_Global_Firewall_Component::NOTICE_SLUG );
382 - delete_site_option( Antibot_Global_Firewall_Component::DOWNLOAD_SYNC_NEXT_RUN_OPTION );
383 353 delete_site_option( Antibot_Global_Firewall_Component::GLOBAL_NOTICE_TIME_OPTION );
354 + // Blocklist stats data.
384 355 delete_site_transient( Antibot_Global_Firewall_Component::BLOCKLIST_STATS_KEY . '_' . Antibot_Global_Firewall_Setting::MODE_BASIC );
385 356 delete_site_transient( Antibot_Global_Firewall_Component::BLOCKLIST_STATS_KEY . '_' . Antibot_Global_Firewall_Setting::MODE_STRICT );
357 + delete_site_transient( Antibot_Global_Firewall_Component::BLOCKLIST_STATS_FULL_KEY );
386 358 delete_site_transient( Antibot_Global_Firewall_Component::IS_SWITCHING_TO_PLUGIN_IN_PROGRESS );
387 359 }
388 360
389 361 /**
@@ -447,9 +419,9 @@
447 419 'sanitize' => 'sanitize_text_field',
448 420 ),
449 421 'email' => array(
450 422 'type' => 'string',
451 - 'sanitize' => 'sanitize_text_field',
423 + 'sanitize' => 'sanitize_email',
452 424 ),
453 425 'service' => array(
454 426 'type' => 'string',
455 427 'sanitize' => 'sanitize_text_field',
@@ -459,18 +431,40 @@
459 431 'sanitize' => 'sanitize_text_field',
460 432 ),
461 433 )
462 434 );
435 +
436 + $reporter_email = isset( $data['email'] ) ? trim( $data['email'] ) : '';
437 + if ( '' === $reporter_email || ! is_email( $reporter_email ) ) {
438 + return new Response(
439 + false,
440 + array(
441 + 'message' => esc_html__( 'A valid email address is required.', 'defender-security' ),
442 + )
443 + );
444 + }
445 +
463 446 // Logging.
464 447 $message = sprintf(
465 448 'IP: %s, email: %s, service: %s, reason: %s',
466 449 $data['ip'],
467 - $data['email'],
450 + $reporter_email,
468 451 $data['service'],
469 452 $data['reason']
470 453 );
471 454 $this->service->log_ip_message( $message );
472 455
456 + // Track the request. Forced so it operates independently of tracking consent.
457 + $this->forced_track(
458 + 'def_request_trusted_ip',
459 + array(
460 + 'IP Address' => $data['ip'],
461 + 'User Email' => $reporter_email,
462 + 'Service' => $data['service'],
463 + 'Reason' => $data['reason'],
464 + )
465 + );
466 +
473 467 return new Response( true, array() );
474 468 }
475 469
476 470 /**
@@ -504,8 +498,17 @@
504 498
505 499 $bl_service = wd_di()->get( Blacklist_Lockout::class );
506 500 $gi_service = wd_di()->get( Global_IP::class );
507 501
502 + $ip = $data['ip'];
503 +
504 + $is_ip_allowed = $bl_service->is_ip_whitelisted( $ip )
505 + || $bl_service->is_country_whitelist( $ip )
506 + || ( $gi_service->is_global_ip_enabled() && $gi_service->is_ip_allowed( $ip ) );
507 +
508 + // Fetch the latest Custom IP blocklist from the Hub so we don't rely on stale cached data.
509 + $gi_service->fetch_global_ip_list();
510 +
508 511 return new Response(
509 512 true,
510 513 array(
511 514 'success' => true,
@@ -510,11 +513,11 @@
510 513 array(
511 514 'success' => true,
512 515 'show_notice' => false,
513 516 'message' => __( 'The IP address is searched successfully.', 'defender-security' ),
514 - 'local' => $bl_service->is_blacklist( $data['ip'] ),
515 - 'central' => $gi_service->is_global_ip_enabled() && $gi_service->is_ip_blocked( $data['ip'] ),
516 - 'antibot' => $this->service->is_ip_blocked( $data['ip'] ),
517 + 'local' => ! $is_ip_allowed && $bl_service->is_blacklist( $data['ip'] ),
518 + 'central' => ! $is_ip_allowed && $gi_service->is_global_ip_enabled() && $gi_service->is_ip_blocked( $data['ip'] ),
519 + 'antibot' => ! $is_ip_allowed && $this->service->is_ip_blocked( $ip ),
517 520 )
518 521 );
519 522 }
520 523
@@ -543,17 +546,19 @@
543 546 'message' => esc_html__( 'Invalid IP address.', 'defender-security' ),
544 547 )
545 548 );
546 549 }
547 - $collection = 'allowlist';
550 + $collection = 'allowlist';
551 + $model = wd_di()->get( \WP_Defender\Model\Setting\Blacklist_Lockout::class );
552 + $already_in_list = $model->is_ip_in_list( $ip, $collection );
553 +
548 554 // Add to Local allowlist.
549 - $model = wd_di()->get( \WP_Defender\Model\Setting\Blacklist_Lockout::class );
550 - if ( ! $model->is_ip_in_list( $ip, $collection ) ) {
555 + if ( ! $already_in_list ) {
551 556 $model->add_to_list( $ip, $collection );
552 557 }
553 558 // Add to Custom IP allowlist.
554 559 $global_ip_service = wd_di()->get( Global_IP::class );
555 - if ( $global_ip_service->can_central_ip_autosync() ) {
560 + if ( ! $already_in_list && $global_ip_service->can_central_ip_autosync() ) {
556 561 $data = array(
557 562 'allow_list' => array( $ip ),
558 563 );
559 564
@@ -567,22 +572,40 @@
567 572 );
568 573 }
569 574 }
570 575
576 + $manage_link_open = '<a href="' . network_admin_url( 'admin.php?page=wdf-ip-lockout&view=blocklist#tab-ip-allowlist' ) . '">';
577 + $manage_link_close = '</a>';
578 +
579 + if ( $already_in_list ) {
580 + $message = sprintf(
581 + /* translators: 1: IP address. 2: Opening anchor tag. 3: Closing anchor tag. */
582 + esc_html__(
583 + 'IP %1$s is already in your Site\'s allowlist. You can manage it in %2$sIP Lockouts%3$s.',
584 + 'defender-security'
585 + ),
586 + $ip,
587 + $manage_link_open,
588 + $manage_link_close
589 + );
590 + } else {
591 + $message = sprintf(
592 + /* translators: 1: IP address. 2: Opening anchor tag. 3: Closing anchor tag. */
593 + esc_html__(
594 + 'IP %1$s has been added to your Site\'s allowlist. You can manage it in %2$sIP Lockouts%3$s.',
595 + 'defender-security'
596 + ),
597 + $ip,
598 + $manage_link_open,
599 + $manage_link_close
600 + );
601 + }
602 +
571 603 return new Response(
572 604 true,
573 605 array(
574 - 'message' => sprintf(
575 - /* translators: 1: IP address. 2: Opening anchor tag. 3: Closing anchor tag. */
576 - esc_html__(
577 - 'IP %1$s has been added to your Site\'s allowlist. You can manage it in %2$sIP Lockouts%3$s.',
578 - 'defender-security'
579 - ),
580 - $ip,
581 - '<a href="' . network_admin_url( 'admin.php?page=wdf-ip-lockout&view=blocklist#tab-ip-allowlist' ) . '">',
582 - '</a>'
583 - ),
584 - 'interval' => 5,
606 + 'message' => $message,
607 + 'already_in_list' => $already_in_list,
585 608 )
586 609 );
587 610 }
588 611
@@ -665,9 +688,9 @@
665 688 *
666 689 * @return void
667 690 */
668 691 public function handle_expired_membership(): void {
669 - if ( $this->is_expired_membership_type() && $this->model->enabled ) {
692 + if ( $this->model->enabled && $this->is_expired_membership_type() ) {
670 693 $this->service->managed_by_plugin_action( false );
671 694 $this->log( 'AntiBot Global Firewall automatically disabled due to expired membership.', Antibot_Global_Firewall_Component::LOG_FILE_NAME );
672 695 }
673 696 }
@@ -695,10 +718,8 @@
695 718 'Feedback' => $data['feedback'],
696 719 )
697 720 );
698 721 }
699 - // Dismiss the global notice.
700 - $this->service->dismiss_global_notice();
701 722
702 723 $message = sprintf(
703 724 /* translators: 1: Open tag, 2: Close tag */
704 725 __( '%1$sThanks for your feedback!%2$s It helps us make Defender even better.', 'defender-security' ),
@@ -710,27 +731,8 @@
710 731 true,
711 732 array(
712 733 'message' => $message,
713 734 'auto_close' => true,
714 - )
715 - );
716 - }
717 -
718 - /**
719 - * Dismiss the global notice.
720 - *
721 - * @defender_route
722 - * @return Response
723 - */
724 - public function dismiss_global_notice(): Response {
725 - $this->service->dismiss_global_notice();
726 -
727 - return new Response(
728 - true,
729 - array(
730 - 'message' => __( 'The global notice has been dismissed.', 'defender-security' ),
731 - 'success' => true,
732 - 'show_notice' => false,
733 735 )
734 736 );
735 737 }
736 738 }