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-blacklist.php +116 -51 5.4.0 → 6.3.0 View file →
@@ -17,11 +17,11 @@
17 17 use WP_Defender\Traits\Country;
18 18 use WP_Defender\Behavior\WPMUDEV;
19 19 use WP_Defender\Model\Lockout_Ip;
20 20 use WP_Defender\Traits\Continent;
21 -use WP_Defender\Controller\Firewall;
22 21 use WP_Defender\Component\Blacklist_Lockout;
23 -use MaxMind\Db\Reader\InvalidDatabaseException;
22 +use WP_DEFENDER_VENDOR\MaxMind\Db\Reader\InvalidDatabaseException;
23 +use WP_Defender\Component\Network_Cron_Manager;
24 24 use WP_Defender\Integrations\MaxMind_Geolocation;
25 25 use WP_Defender\Component\Config\Config_Hub_Helper;
26 26 use WP_Defender\Model\Setting\Blacklist_Lockout as Model_Blacklist_Lockout;
27 27
@@ -64,17 +64,26 @@
64 64 $this->model = wd_di()->get( Model_Blacklist_Lockout::class );
65 65 $this->service = wd_di()->get( Blacklist_Lockout::class );
66 66 add_action( 'wd_blacklist_this_ip', array( $this, 'blacklist_an_ip' ) );
67 67 // Update MaxMind's DB.
68 - if ( ! empty( $this->model->maxmind_license_key ) ) {
69 - if ( ! wp_next_scheduled( 'wpdef_update_geoip' ) ) {
70 - wp_schedule_event( strtotime( 'next Thursday' ), 'weekly', 'wpdef_update_geoip' );
71 - }
68 + if ( '' !== $this->model->maxmind_license_key ) {
72 69 // @since 2.8.0 Allows update or remove the database of MaxMind automatic and periodically (MaxMind's TOS).
73 - $bind_updater = (bool) apply_filters( 'wd_update_maxmind_database', true );
74 - // Bind to the scheduled updater action.
70 + $bind_updater = apply_filters( 'wd_update_maxmind_database', true );
71 + $bind_updater = is_bool( $bind_updater ) ? $bind_updater : (bool) $bind_updater;
72 +
75 73 if ( $bind_updater ) {
76 - add_action( 'wpdef_update_geoip', array( $this, 'update_database' ) );
74 + /**
75 + * Network Cron Manager
76 + *
77 + * @var Network_Cron_Manager $network_cron_manager
78 + */
79 + $network_cron_manager = wd_di()->get( Network_Cron_Manager::class );
80 + $network_cron_manager->register_callback(
81 + 'wpdef_update_geoip',
82 + array( $this, 'update_database' ),
83 + WEEK_IN_SECONDS,
84 + 'next Thursday'
85 + );
77 86 }
78 87 }
79 88 }
80 89
@@ -86,8 +95,11 @@
86 95 * @return void
87 96 */
88 97 public function blacklist_an_ip( string $ip ): void {
89 98 $this->model->add_to_list( $ip, 'blocklist' );
99 + if ( defender_is_wp_org_version() ) {
100 + \WP_Defender\Component\Rate::run_counter_of_ip_lockouts();
101 + }
90 102 }
91 103
92 104 /**
93 105 * Enqueues scripts and styles for this page.
@@ -98,9 +110,8 @@
98 110 public function enqueue_assets() {
99 111 if ( ! $this->is_page_active() ) {
100 112 return;
101 113 }
102 - wp_localize_script( 'def-iplockout', 'blacklist', $this->data_frontend() );
103 114 }
104 115
105 116 /**
106 117 * Provides data for the frontend.
@@ -134,22 +145,24 @@
134 145 foreach ( $user_ip as $ip ) {
135 146 $current_country[] = $this->get_current_country( $ip );
136 147 }
137 148
149 + $misc = array(
150 + 'user_ip' => implode( ', ', $user_ip ),
151 + 'is_geodb_downloaded' => $exist_geodb,
152 + 'blacklist_countries' => $blacklist_countries,
153 + 'whitelist_countries' => $whitelist_countries,
154 + 'current_country' => $current_country,
155 + 'no_ips' => '' === $arr_model['ip_blacklist'] && '' === $arr_model['ip_whitelist'],
156 + 'countries_with_continents_list' => $countries_with_continents_list,
157 + 'geodb_license_key' => $this->mask_license_key( $this->model->maxmind_license_key ),
158 + 'module_name' => Model_Blacklist_Lockout::get_module_name(),
159 + );
160 +
138 161 return array_merge(
139 162 array(
140 163 'model' => $arr_model,
141 - 'misc' => array(
142 - 'user_ip' => implode( ',', $user_ip ),
143 - 'is_geodb_downloaded' => $exist_geodb,
144 - 'blacklist_countries' => $blacklist_countries,
145 - 'whitelist_countries' => $whitelist_countries,
146 - 'current_country' => $current_country,
147 - 'no_ips' => '' === $arr_model['ip_blacklist'] && '' === $arr_model['ip_whitelist'],
148 - 'countries_with_continents_list' => $countries_with_continents_list,
149 - 'geodb_license_key' => $this->mask_license_key( $this->model->maxmind_license_key ),
150 - 'module_name' => Model_Blacklist_Lockout::get_module_name(),
151 - ),
164 + 'misc' => $misc,
152 165 ),
153 166 $this->dump_routes_and_nonces()
154 167 );
155 168 }
@@ -161,9 +174,9 @@
161 174 *
162 175 * @return string The masked license key.
163 176 */
164 177 private function mask_license_key( $maxmind_license_key ): string {
165 - if ( ! is_string( $maxmind_license_key ) || empty( $maxmind_license_key ) ) {
178 + if ( ! is_string( $maxmind_license_key ) || '' === $maxmind_license_key ) {
166 179 return $maxmind_license_key;
167 180 }
168 181 // Get the length of the license key.
169 182 $key_length = strlen( $maxmind_license_key );
@@ -215,8 +228,10 @@
215 228 'sanitize' => 'sanitize_textarea_field',
216 229 ),
217 230 )
218 231 );
232 + $data = $this->remove_country_list_conflicts( $data );
233 +
219 234 $this->model->import( $data );
220 235 if ( $this->model->validate() ) {
221 236 $this->model->save();
222 237 Config_Hub_Helper::set_clear_active_flag();
@@ -242,10 +257,8 @@
242 257 $this->model->save();
243 258 Config_Hub_Helper::set_clear_active_flag();
244 259 }
245 260
246 - $this->model->import( $data );
247 -
248 261 return new Response(
249 262 false,
250 263 array_merge(
251 264 array( 'message' => $this->model->get_formatted_errors() ),
@@ -254,8 +267,44 @@
254 267 );
255 268 }
256 269
257 270 /**
271 + * Prevent the same country from being saved in both blocked and allowed lists.
272 + *
273 + * @param array $data Settings data.
274 + *
275 + * @return array
276 + */
277 + private function remove_country_list_conflicts( array $data ): array {
278 + if ( ! isset( $data['country_blacklist'], $data['country_whitelist'] ) ) {
279 + return $data;
280 + }
281 +
282 + $country_blacklist = array_values( array_unique( $data['country_blacklist'] ) );
283 + $country_whitelist = array_values( array_unique( $data['country_whitelist'] ) );
284 + $added_blacklist = array_diff( $country_blacklist, $this->model->country_blacklist );
285 + $added_whitelist = array_diff( $country_whitelist, $this->model->country_whitelist );
286 +
287 + if ( array() !== $added_blacklist ) {
288 + $country_whitelist = array_values( array_diff( $country_whitelist, $added_blacklist ) );
289 + }
290 +
291 + if ( array() !== $added_whitelist ) {
292 + $country_blacklist = array_values( array_diff( $country_blacklist, $added_whitelist ) );
293 + }
294 +
295 + $remaining_conflicts = array_intersect( $country_blacklist, $country_whitelist );
296 + if ( array() !== $remaining_conflicts ) {
297 + $country_whitelist = array_values( array_diff( $country_whitelist, $remaining_conflicts ) );
298 + }
299 +
300 + $data['country_blacklist'] = $country_blacklist;
301 + $data['country_whitelist'] = $country_whitelist;
302 +
303 + return $data;
304 + }
305 +
306 + /**
258 307 * Download the GEODB IP from Maxmind.
259 308 *
260 309 * @param Request $request The request object containing the license key.
261 310 *
@@ -292,9 +341,9 @@
292 341 }
293 342
294 343 foreach ( $this->get_user_ip() as $ip ) {
295 344 $country = $this->get_current_country( $ip );
296 - if ( ! empty( $country ) && ! empty( $country['iso'] ) ) {
345 + if ( isset( $country['iso'] ) && '' !== (string) $country['iso'] ) {
297 346 $this->model = $this->service->add_default_whitelisted_country( $this->model, $country['iso'] );
298 347 }
299 348 }
300 349 $this->model->maxmind_license_key = $license_key;
@@ -311,19 +360,23 @@
311 360 )
312 361 );
313 362 } else {
314 363 $this->log( 'Error from MaxMind: ' . $tmp->get_error_message(), Firewall::FIREWALL_LOG );
315 - $string = sprintf(
316 - /* translators: 1. License key with link. */
317 - esc_html__(
318 - 'You have entered an invalid %1$s. If you just created the key, please wait 5 minutes before trying to activate it.',
319 - 'defender-security'
320 - ),
321 - '<a target="_blank" href="https://www.maxmind.com/en/accounts/current/license-key">' . esc_html__( 'license key', 'defender-security' ) . '</a>'
364 + $string = esc_html__(
365 + 'The license key you entered isn\'t valid. If you recently created it, allow up to 5 minutes for activation before trying again.',
366 + 'defender-security'
322 367 );
323 368
324 369 if ( ( new WPMUDEV() )->show_support_links() ) {
325 - $string .= defender_support_ticket_text();
370 + $string = sprintf(
371 + /* translators: 1. Opening support link, 2. Closing support link. */
372 + esc_html__(
373 + 'The license key you entered isn\'t valid. If you recently created it, allow up to 5 minutes for activation before trying again. Need help? %1$sContact support%2$s.',
374 + 'defender-security'
375 + ),
376 + '<a target="_blank" href="' . WP_DEFENDER_SUPPORT_LINK . '">',
377 + '</a>'
378 + );
326 379 }
327 380
328 381 return new Response( false, array( 'invalid_text' => $string ) );
329 382 }
@@ -456,9 +509,9 @@
456 509 $ips = null;
457 510 $bulk_ips = null;
458 511 $limit = 50;
459 512
460 - if ( ! empty( $data['ips'] ) ) {
513 + if ( isset( $data['ips'] ) && is_string( $data['ips'] ) && '' !== $data['ips'] ) {
461 514 $ips = json_decode( $data['ips'] );
462 515 $first_nth_ips = array_slice( $ips, 0, $limit );
463 516 $bulk_ips = wp_list_pluck( $first_nth_ips, 'ip' );
464 517 }
@@ -508,9 +561,9 @@
508 561 */
509 562 public function query_locked_ips() {
510 563 $results = Lockout_Ip::query_locked_ip();
511 564 $locked_ips = array();
512 - if ( ! empty( $results ) ) {
565 + if ( array() !== $results ) {
513 566 foreach ( $results as $key => $locked_ip ) {
514 567 $locked_ips[] = array(
515 568 'id' => $locked_ip['id'],
516 569 'ip' => $locked_ip['ip'],
@@ -559,9 +612,9 @@
559 612 'ip_blacklist' => $data['ip_blacklist'],
560 613 'ip_whitelist' => $data['ip_whitelist'],
561 614 'ip_lockout_message' => $data['ip_lockout_message'],
562 615 );
563 - if ( isset( $data['geoIP_db'] ) && file_exists( $data['geoIP_db'] ) ) {
616 + if ( isset( $data['geoIP_db'] ) && is_string( $data['geoIP_db'] ) && file_exists( $data['geoIP_db'] ) ) {
564 617 $adapted_data['geodb_path'] = $data['geoIP_db'];
565 618 if ( isset( $data['country_blacklist'] ) ) {
566 619 $adapted_data['country_blacklist'] = $data['country_blacklist'];
567 620 }
@@ -580,9 +633,9 @@
580 633 *
581 634 * @throws Exception If table is not defined.
582 635 */
583 636 public function import_data( array $data ) {
584 - if ( ! empty( $data ) ) {
637 + if ( array() !== $data ) {
585 638 // Upgrade for old versions.
586 639 $data = $this->adapt_data( $data );
587 640 $model = $this->model;
588 641 $model->import( $data );
@@ -628,20 +681,29 @@
628 681 'type' => 'int',
629 682 ),
630 683 )
631 684 );
632 - $attached_id = $data['id'];
633 - if ( ! is_object( get_post( $attached_id ) ) ) {
634 - return new Response(
635 - false,
636 - array(
637 - 'message' => esc_html__( 'Your file is invalid!', 'defender-security' ),
638 - )
639 - );
685 + $file = '';
686 + $attached_id = $data['id'] ?? 0;
687 + if ( 0 < $attached_id ) {
688 + if ( ! is_object( get_post( $attached_id ) ) ) {
689 + return new Response(
690 + false,
691 + array(
692 + 'message' => esc_html__( 'Your file is invalid!', 'defender-security' ),
693 + )
694 + );
695 + }
696 +
697 + $file = get_attached_file( $attached_id );
698 + } else {
699 + $file_data = defender_get_data_from_request( 'file', 'f' );
700 + if ( is_array( $file_data ) && isset( $file_data['tmp_name'] ) && is_uploaded_file( $file_data['tmp_name'] ) ) {
701 + $file = $file_data['tmp_name'];
702 + }
640 703 }
641 704
642 - $file = get_attached_file( $attached_id );
643 - if ( ! is_file( $file ) ) {
705 + if ( ! is_string( $file ) || '' === $file || ! is_file( $file ) ) {
644 706 return new Response(
645 707 false,
646 708 array(
647 709 'message' => esc_html__( 'Your file is invalid!', 'defender-security' ),
@@ -665,11 +727,14 @@
665 727 }
666 728
667 729 return new Response(
668 730 true,
669 - array(
670 - 'message' => esc_html__( 'Your allowlist/blocklist has been successfully imported.', 'defender-security' ),
671 - 'interval' => 1,
731 + array_merge(
732 + array(
733 + 'message' => esc_html__( 'Your allowlist/blocklist has been successfully imported.', 'defender-security' ),
734 + 'auto_close' => true,
735 + ),
736 + $this->data_frontend()
672 737 )
673 738 );
674 739 }
675 740
@@ -680,9 +745,9 @@
680 745 * @throws Exception If table is not defined.
681 746 * @since 2.8.0
682 747 */
683 748 public function update_database() {
684 - if ( empty( $this->model->maxmind_license_key ) ) {
749 + if ( '' === $this->model->maxmind_license_key ) {
685 750 return;
686 751 }
687 752
688 753 $service_geo = wd_di()->get( MaxMind_Geolocation::class );