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/component/class-user-agent.php +21 -19 5.4.0 → 6.3.0 View file →
@@ -12,8 +12,9 @@
12 12 use WP_Defender\Model\Lockout_Ip;
13 13 use WP_Defender\Model\Lockout_Log;
14 14 use WP_Defender\Model\Setting\User_Agent_Lockout;
15 15 use WP_Defender\Model\Notification\Firewall_Notification;
16 +use WP_Filesystem_Base;
16 17
17 18 /**
18 19 * Handles User-Agent based operations including lockouts and logging for security purposes.
19 20 *
@@ -91,13 +92,10 @@
91 92 $model->log = esc_html__( 'Locked out due to attempted login with banned user agent', 'defender-security' );
92 93 break;
93 94 }
94 95 $model->save();
95 - // The 'defender_notify' hook doesn't work, so send notify directly.
96 - $module = wd_di()->get( Firewall_Notification::class );
97 - if ( $module->check_options( $model ) ) {
98 - $module->send( $model );
99 - }
96 + // Notify directly because the 'defender_notify' hook isn't registered yet at firewall-time.
97 + wd_di()->get( Firewall_Notification::class )->notify_lockout( $model );
100 98 }
101 99
102 100 /**
103 101 * Queue hooks when this class init.
@@ -125,9 +123,9 @@
125 123 $allowlist = str_replace( '#', '\#', $this->model->get_lockout_list( 'allowlist' ) );
126 124 $allowlist_regex_pattern = '#' . implode( '|', $allowlist ) . '#i';
127 125 $allowlist_match = preg_match( $allowlist_regex_pattern, $user_agent );
128 126
129 - if ( count( $allowlist ) > 0 && ! empty( $allowlist_match ) ) {
127 + if ( count( $allowlist ) > 0 && $allowlist_match > 0 ) {
130 128 return false;
131 129 }
132 130
133 131 $blocklist = str_replace( '#', '\#', $this->model->get_all_selected_blocklist_ua() );
@@ -133,9 +131,9 @@
133 131 $blocklist = str_replace( '#', '\#', $this->model->get_all_selected_blocklist_ua() );
134 132 $blocklist_regex_pattern = '#' . implode( '|', $blocklist ) . '#i';
135 133 $blocklist_match = preg_match( $blocklist_regex_pattern, $user_agent );
136 134
137 - if ( count( $blocklist ) > 0 && ! empty( $blocklist_match ) ) {
135 + if ( count( $blocklist ) > 0 && $blocklist_match > 0 ) {
138 136 return true;
139 137 }
140 138
141 139 return false;
@@ -146,9 +144,9 @@
146 144 *
147 145 * @return string The block message.
148 146 */
149 147 public function get_message(): string {
150 - return ! empty( $this->model->message )
148 + return '' !== $this->model->message
151 149 ? $this->model->message
152 150 : esc_html__( 'You have been blocked from accessing this website.', 'defender-security' );
153 151 }
154 152
@@ -164,8 +162,11 @@
164 162 do_action( 'wd_user_agent_before_block', $user_agent, $ip, $reason );
165 163 $this->log_event( $ip, $user_agent, $reason );
166 164 do_action( 'wd_user_agent_lockout', $this->model, self::SCENARIO_USER_AGENT_LOCKOUT );
167 165 // Shouldn't block IP via hook 'wd_blacklist_this_ip', block only when the button 'Ban IP' is clicked.
166 + if ( defender_is_wp_org_version() ) {
167 + Rate::run_counter_of_ua_lockouts();
168 + }
168 169 }
169 170
170 171 /**
171 172 * Cleans a user agent string quickly.
@@ -184,9 +185,9 @@
184 185 * @return string
185 186 */
186 187 public function sanitize_user_agent(): string {
187 188 $user_agent = defender_get_data_from_request( 'HTTP_USER_AGENT', 's' );
188 - if ( empty( $user_agent ) ) {
189 + if ( '' === $user_agent ) {
189 190 return '';
190 191 }
191 192
192 193 $user_agent = apply_filters( 'wd_current_user_agent', $user_agent );
@@ -202,15 +203,15 @@
202 203 * @param string $user_agent The user agent of the request.
203 204 *
204 205 * @return bool Returns true if the headers are considered bad, false otherwise.
205 206 */
206 - public function is_bad_post( $user_agent ): bool {
207 + public function is_bad_post( string $user_agent ): bool {
207 208 $server = defender_get_data_from_request( null, 's' );
208 209
209 210 return true === $this->model->empty_headers
210 211 && 'POST' === $server['REQUEST_METHOD']
211 - && empty( $user_agent )
212 - && empty( $server['HTTP_REFERER'] );
212 + && '' === $user_agent
213 + && ( ! isset( $server['HTTP_REFERER'] ) || '' === $server['HTTP_REFERER'] );
213 214 }
214 215
215 216 /**
216 217 * Verifies the format and usability of an import file for User Agent Lockout settings.
@@ -221,9 +222,9 @@
221 222 */
222 223 public function verify_import_file( $file ) {
223 224 global $wp_filesystem;
224 225 // Initialize the WP filesystem, no more using 'file-put-contents' function.
225 - if ( empty( $wp_filesystem ) ) {
226 + if ( ! $wp_filesystem instanceof WP_Filesystem_Base ) {
226 227 require_once ABSPATH . '/wp-admin/includes/file.php';
227 228 WP_Filesystem();
228 229 }
229 230 $contents = $wp_filesystem->get_contents( $file );
@@ -262,9 +263,9 @@
262 263 *
263 264 * @return string Human-readable text if log_type is UA else empty string.
264 265 */
265 266 public function get_status_text( $log_type, $user_agent ): string {
266 - if ( Lockout_Log::LOCKOUT_UA !== $log_type ) {
267 + if ( ! in_array( $log_type, Lockout_Log::get_ua_lockout_types(), true ) ) {
267 268 return '';
268 269 }
269 270
270 271 $status_text = self::EMPTY_USER_AGENT_TEXT;
@@ -274,9 +275,9 @@
274 275 }
275 276
276 277 $user_agent_key = $this->model->get_access_status( $user_agent );
277 278
278 - if ( ! empty( $user_agent_key[0] ) ) {
279 + if ( isset( $user_agent_key[0] ) && '' !== $user_agent_key[0] ) {
279 280 $status_text = $this->lockout_ip_model->get_access_status_text( $user_agent_key[0] );
280 281 }
281 282
282 283 return $status_text;
@@ -301,8 +302,9 @@
301 302 'dotbot' => 'DotBot (Moz)',
302 303 'mj12bot' => 'MJ12Bot (Majestic)',
303 304 'ahrefsbot' => 'AhrefsBot',
304 305 'semrushbot' => 'SEMrushBot',
306 + 'thinkbot' => 'Thinkbot',
305 307 ),
306 308 );
307 309 }
308 310
@@ -342,13 +344,13 @@
342 344 public static function get_script_presets(): array {
343 345 return array(
344 346 self::PYTHON_REQUESTS_KEY => array(
345 347 'label' => 'Python Script',
346 - 'desc' => __( '( This will block all requests from python-requests/* agent )', 'defender-security' ),
348 + 'desc' => __( '(blocks python-requests/* agent)', 'defender-security' ),
347 349 ),
348 350 self::GO_HTTP_CLIENT_KEY => array(
349 - 'label' => 'Go Http Clients',
350 - 'desc' => __( '( This will block all requests from Go-http-client/* agent )', 'defender-security' ),
351 + 'label' => 'Go HTTP Clients',
352 + 'desc' => __( '(blocks Go-http-client/* agent)', 'defender-security' ),
351 353 ),
352 354 );
353 355 }
354 356
@@ -378,7 +380,7 @@
378 380 unset( $arr_source[ $key ] );
379 381 }
380 382 }
381 383
382 - return ! empty( $arr_source ) ? array_values( $arr_source ) : array();
384 + return is_array( $arr_source ) && array() !== $arr_source ? array_values( $arr_source ) : array();
383 385 }
384 386 }