Version Description
- Enhancement: Added logging for failed two-factor, OAuth, and REST API authentications.
- Enhancement: Added logging details about the source of login failures and the type of authentication that failed.
- Enhancement: Due to improvements in tracking authentication failures, brute force attempts using alternate authentication methods are more reliably found and blocked.
- Enhancement: The server's IP is treated as whitelisted and will not be considered for lockouts or bans.
- Enhancement: Reduced memory usage when creating a backup.
- Enhancement: Changed log entry description of "IP Flagged as bad by iThemes IPCheck" to "IP Flagged by Network Brute Force Protection". This should help clarify the meaning of the log entry.
- Enhancement: Improved efficiency of the Network Brute Force Protection feature.
- Bug Fix: Fixed bug that prevented Network Brute Force Protection from working properly on some sites.
Download this release
Release Info
Developer | chrisjean |
Plugin | iThemes Security (formerly Better WP Security) |
Version | 6.1.0 |
Comparing to | |
See all releases |
Code changes from version 6.0.0 to 6.1.0
- better-wp-security.php +1 -1
- core/admin-pages/css/style.css +11 -1
- core/class-ithemes-sync-verb-itsec-get-everything.php +0 -69
- core/class-itsec-core.php +23 -33
- core/class-itsec-lib.php +50 -0
- core/class-itsec-lockout.php +24 -21
- core/class-itsec-sync.php +0 -89
- core/history.txt +9 -0
- core/modules/away-mode/class-itsec-away-mode.php +22 -17
- core/modules/away-mode/sync-verbs/index.php +1 -0
- core/modules/away-mode/{class-ithemes-sync-verb-itsec-get-away-mode.php → sync-verbs/itsec-get-away-mode.php} +0 -0
- core/modules/away-mode/{class-ithemes-sync-verb-itsec-override-away-mode.php → sync-verbs/itsec-override-away-mode.php} +0 -0
- core/modules/backup/class-itsec-backup.php +126 -164
- core/modules/brute-force/class-itsec-brute-force.php +13 -77
- core/modules/file-change/class-ithemes-sync-verb-itsec-perform-file-scan.php +0 -53
- core/modules/file-change/class-itsec-file-change.php +8 -22
- core/modules/file-change/sync-verbs/index.php +1 -0
- core/modules/file-change/sync-verbs/itsec-perform-file-scan.php +12 -0
- core/modules/ipcheck/class-itsec-ipcheck.php +106 -241
- core/modules/ipcheck/setup.php +4 -0
- core/modules/malware/class-itsec-malware.php +24 -18
- core/modules/malware/sync-verbs/index.php +1 -0
- core/modules/malware/{class-ithemes-sync-verb-itsec-do-malware-scan.php → sync-verbs/itsec-do-malware-scan.php} +3 -8
- core/modules/malware/{class-ithemes-sync-verb-itsec-get-malware-scan-log.php → sync-verbs/itsec-get-malware-scan-log.php} +0 -0
- core/modules/security-check/scanner.php +4 -49
- core/sync-verbs/index.php +1 -0
- core/sync-verbs/itsec-get-everything.php +23 -0
- core/{class-ithemes-sync-verb-itsec-get-lockouts.php → sync-verbs/itsec-get-lockouts.php} +0 -0
- core/{class-ithemes-sync-verb-itsec-get-temp-whitelist.php → sync-verbs/itsec-get-temp-whitelist.php} +0 -0
- core/{class-ithemes-sync-verb-itsec-release-lockout.php → sync-verbs/itsec-release-lockout.php} +0 -0
- core/{class-ithemes-sync-verb-itsec-set-temp-whitelist.php → sync-verbs/itsec-set-temp-whitelist.php} +0 -0
- history.txt +9 -0
- readme.txt +14 -4
better-wp-security.php
CHANGED
@@ -6,7 +6,7 @@
|
|
6 |
* Description: Take the guesswork out of WordPress security. iThemes Security offers 30+ ways to lock down WordPress in an easy-to-use WordPress security plugin.
|
7 |
* Author: iThemes
|
8 |
* Author URI: https://ithemes.com
|
9 |
-
* Version: 6.
|
10 |
* Text Domain: better-wp-security
|
11 |
* Network: True
|
12 |
* License: GPLv2
|
6 |
* Description: Take the guesswork out of WordPress security. iThemes Security offers 30+ ways to lock down WordPress in an easy-to-use WordPress security plugin.
|
7 |
* Author: iThemes
|
8 |
* Author URI: https://ithemes.com
|
9 |
+
* Version: 6.1.0
|
10 |
* Text Domain: better-wp-security
|
11 |
* Network: True
|
12 |
* License: GPLv2
|
core/admin-pages/css/style.css
CHANGED
@@ -578,6 +578,16 @@ body.itsec-modal-open {
|
|
578 |
color: #9c3e3e;
|
579 |
}
|
580 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
581 |
/*
|
582 |
* Security Check
|
583 |
*/
|
@@ -672,4 +682,4 @@ body.itsec-modal-open {
|
|
672 |
.itsec-password-strength.strong {
|
673 |
background-color: #c1e1b9;
|
674 |
border-color: #83c373;
|
675 |
-
}
|
578 |
color: #9c3e3e;
|
579 |
}
|
580 |
|
581 |
+
.itsec-notice-message {
|
582 |
+
display: block;
|
583 |
+
clear: both;
|
584 |
+
font-size: 1.125em;
|
585 |
+
margin: 1.5em 0;
|
586 |
+
padding: 1em;
|
587 |
+
border-left: 4px solid #e8e4a7;
|
588 |
+
background: #fff9ec;
|
589 |
+
}
|
590 |
+
|
591 |
/*
|
592 |
* Security Check
|
593 |
*/
|
682 |
.itsec-password-strength.strong {
|
683 |
background-color: #c1e1b9;
|
684 |
border-color: #83c373;
|
685 |
+
}
|
core/class-ithemes-sync-verb-itsec-get-everything.php
DELETED
@@ -1,69 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
class Ithemes_Sync_Verb_ITSEC_Get_Everything extends Ithemes_Sync_Verb {
|
4 |
-
|
5 |
-
public static $name = 'itsec-get-everything';
|
6 |
-
public static $description = 'Retrieve iThemes Security Status and other information.';
|
7 |
-
|
8 |
-
private $default_arguments = array();
|
9 |
-
|
10 |
-
public function run( $arguments ) {
|
11 |
-
|
12 |
-
$itsec_sync = ITSEC_Core::get_itsec_sync();
|
13 |
-
|
14 |
-
$modules = $itsec_sync->get_modules();
|
15 |
-
$module_results = array();
|
16 |
-
|
17 |
-
//return $modules;
|
18 |
-
|
19 |
-
foreach ( $modules as $name => $module ) {
|
20 |
-
|
21 |
-
if ( isset( $module['verbs'] ) && isset( $module['path'] ) && isset( $module['everything'] ) ) {
|
22 |
-
|
23 |
-
$everything = array();
|
24 |
-
|
25 |
-
if ( is_array( $module['everything'] ) ) {
|
26 |
-
|
27 |
-
foreach ( $module['everything'] as $item ) {
|
28 |
-
|
29 |
-
if ( isset( $module['verbs'][ $item ] ) ) {
|
30 |
-
$everything[] = $item;
|
31 |
-
}
|
32 |
-
|
33 |
-
}
|
34 |
-
|
35 |
-
} elseif ( isset( $module['verbs'][ $module['everything'] ] ) ) {
|
36 |
-
|
37 |
-
$everything[] = $module['everything'];
|
38 |
-
|
39 |
-
}
|
40 |
-
|
41 |
-
foreach ( $everything as $verb ) {
|
42 |
-
|
43 |
-
$class = $module['verbs'][ $verb ];
|
44 |
-
|
45 |
-
if ( ! class_exists( $class ) ) {
|
46 |
-
|
47 |
-
require( trailingslashit( $module['path'] ) . 'class-ithemes-sync-verb-' . $verb . '.php' );
|
48 |
-
|
49 |
-
}
|
50 |
-
|
51 |
-
$obj = new $class;
|
52 |
-
|
53 |
-
$module_results[ $name ][ $verb ] = $obj->run( array() );
|
54 |
-
|
55 |
-
}
|
56 |
-
|
57 |
-
}
|
58 |
-
|
59 |
-
}
|
60 |
-
|
61 |
-
return array_merge( array(
|
62 |
-
'api' => '1',
|
63 |
-
),
|
64 |
-
$module_results
|
65 |
-
);
|
66 |
-
|
67 |
-
}
|
68 |
-
|
69 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
core/class-itsec-core.php
CHANGED
@@ -25,7 +25,7 @@ if ( ! class_exists( 'ITSEC_Core' ) ) {
|
|
25 |
private
|
26 |
$itsec_files,
|
27 |
$itsec_notify,
|
28 |
-
$
|
29 |
$plugin_build,
|
30 |
$plugin_file,
|
31 |
$plugin_dir,
|
@@ -74,7 +74,7 @@ if ( ! class_exists( 'ITSEC_Core' ) ) {
|
|
74 |
public function init( $plugin_file, $plugin_name ) {
|
75 |
global $itsec_globals, $itsec_logger, $itsec_lockout;
|
76 |
|
77 |
-
$this->plugin_build =
|
78 |
$this->plugin_file = $plugin_file;
|
79 |
$this->plugin_dir = dirname( $plugin_file ) . '/';
|
80 |
$this->current_time = current_time( 'timestamp' );
|
@@ -156,7 +156,7 @@ if ( ! class_exists( 'ITSEC_Core' ) ) {
|
|
156 |
|
157 |
//Admin bar links
|
158 |
if ( ! ITSEC_Modules::get_setting( 'global', 'hide_admin_bar' ) ) {
|
159 |
-
add_action( 'admin_bar_menu', array( $this, '
|
160 |
}
|
161 |
|
162 |
//See if they're upgrade from Better WP Security
|
@@ -179,6 +179,9 @@ if ( ! class_exists( 'ITSEC_Core' ) ) {
|
|
179 |
}
|
180 |
|
181 |
|
|
|
|
|
|
|
182 |
do_action( 'itsec_initialized' );
|
183 |
}
|
184 |
|
@@ -192,20 +195,16 @@ if ( ! class_exists( 'ITSEC_Core' ) ) {
|
|
192 |
return $self->itsec_notify;
|
193 |
}
|
194 |
|
195 |
-
public static function
|
196 |
$self = self::get_instance();
|
197 |
-
|
198 |
-
if ( ! isset( $self->itsec_sync ) ) {
|
199 |
-
require( dirname( __FILE__ ) . '/class-itsec-sync.php' );
|
200 |
-
$self->itsec_sync = new ITSEC_Sync();
|
201 |
-
}
|
202 |
-
|
203 |
-
return $self->itsec_sync;
|
204 |
}
|
205 |
|
206 |
public function register_sync_verbs( $sync_api ) {
|
207 |
-
|
208 |
-
$
|
|
|
|
|
209 |
}
|
210 |
|
211 |
public function register_modules() {
|
@@ -257,8 +256,6 @@ if ( ! class_exists( 'ITSEC_Core' ) ) {
|
|
257 |
|
258 |
static $this_plugin;
|
259 |
|
260 |
-
global $itsec_globals;
|
261 |
-
|
262 |
if ( empty( $this_plugin ) ) {
|
263 |
$this_plugin = str_replace( WP_PLUGIN_DIR . '/', '', self::get_plugin_file() );
|
264 |
}
|
@@ -283,7 +280,6 @@ if ( ! class_exists( 'ITSEC_Core' ) ) {
|
|
283 |
*/
|
284 |
public function add_plugin_meta_links( $meta, $plugin_file ) {
|
285 |
|
286 |
-
global $itsec_globals;
|
287 |
$plugin_base = str_replace( WP_PLUGIN_DIR . '/', '', self::get_plugin_file() );
|
288 |
|
289 |
if ( $plugin_base == $plugin_file ) {
|
@@ -302,16 +298,14 @@ if ( ! class_exists( 'ITSEC_Core' ) ) {
|
|
302 |
*
|
303 |
* @return void
|
304 |
*/
|
305 |
-
public function
|
306 |
-
|
307 |
-
global $wp_admin_bar, $itsec_globals;
|
308 |
|
309 |
if ( ! ITSEC_Core::current_user_can_manage() ) {
|
310 |
return;
|
311 |
}
|
312 |
|
313 |
// Add the Parent link.
|
314 |
-
$wp_admin_bar->
|
315 |
array(
|
316 |
'title' => __( 'Security', 'better-wp-security' ),
|
317 |
'href' => self::get_settings_page_url(),
|
@@ -319,30 +313,30 @@ if ( ! class_exists( 'ITSEC_Core' ) ) {
|
|
319 |
)
|
320 |
);
|
321 |
|
322 |
-
$wp_admin_bar->
|
323 |
array(
|
324 |
-
'
|
325 |
'title' => __( 'Settings', 'better-wp-security' ),
|
326 |
'href' => self::get_settings_page_url(),
|
327 |
-
'
|
328 |
)
|
329 |
);
|
330 |
|
331 |
-
$wp_admin_bar->
|
332 |
array(
|
333 |
-
'
|
334 |
'title' => __( 'Security Check', 'better-wp-security' ),
|
335 |
'href' => self::get_security_check_page_url(),
|
336 |
-
'
|
337 |
)
|
338 |
);
|
339 |
|
340 |
-
$wp_admin_bar->
|
341 |
array(
|
342 |
-
'
|
343 |
'title' => __( 'Logs', 'better-wp-security' ),
|
344 |
'href' => self::get_logs_page_url(),
|
345 |
-
'
|
346 |
)
|
347 |
);
|
348 |
}
|
@@ -356,8 +350,6 @@ if ( ! class_exists( 'ITSEC_Core' ) ) {
|
|
356 |
*/
|
357 |
public function do_upgrade() {
|
358 |
|
359 |
-
global $itsec_globals;
|
360 |
-
|
361 |
//require plugin setup information
|
362 |
if ( ! class_exists( 'ITSEC_Setup' ) ) {
|
363 |
require( self::get_core_dir() . '/class-itsec-setup.php' );
|
@@ -476,8 +468,6 @@ if ( ! class_exists( 'ITSEC_Core' ) ) {
|
|
476 |
*/
|
477 |
public function save_plugin_data() {
|
478 |
|
479 |
-
global $itsec_globals;
|
480 |
-
|
481 |
$save_data = false; //flag to avoid saving data if we don't have to
|
482 |
|
483 |
$plugin_data = get_site_option( 'itsec_data' );
|
25 |
private
|
26 |
$itsec_files,
|
27 |
$itsec_notify,
|
28 |
+
$sync_api,
|
29 |
$plugin_build,
|
30 |
$plugin_file,
|
31 |
$plugin_dir,
|
74 |
public function init( $plugin_file, $plugin_name ) {
|
75 |
global $itsec_globals, $itsec_logger, $itsec_lockout;
|
76 |
|
77 |
+
$this->plugin_build = 4056; // used to trigger updates
|
78 |
$this->plugin_file = $plugin_file;
|
79 |
$this->plugin_dir = dirname( $plugin_file ) . '/';
|
80 |
$this->current_time = current_time( 'timestamp' );
|
156 |
|
157 |
//Admin bar links
|
158 |
if ( ! ITSEC_Modules::get_setting( 'global', 'hide_admin_bar' ) ) {
|
159 |
+
add_action( 'admin_bar_menu', array( $this, 'modify_admin_bar' ), 99 );
|
160 |
}
|
161 |
|
162 |
//See if they're upgrade from Better WP Security
|
179 |
}
|
180 |
|
181 |
|
182 |
+
add_action( 'wp_login_failed', array( 'ITSEC_Lib', 'handle_wp_login_failed' ) );
|
183 |
+
|
184 |
+
|
185 |
do_action( 'itsec_initialized' );
|
186 |
}
|
187 |
|
195 |
return $self->itsec_notify;
|
196 |
}
|
197 |
|
198 |
+
public static function get_sync_api() {
|
199 |
$self = self::get_instance();
|
200 |
+
return $self->sync_api;
|
|
|
|
|
|
|
|
|
|
|
|
|
201 |
}
|
202 |
|
203 |
public function register_sync_verbs( $sync_api ) {
|
204 |
+
// For use by the itsec-get-everything verb as it has to run other verbs to get their details.
|
205 |
+
$this->sync_api = $sync_api;
|
206 |
+
|
207 |
+
$sync_api->register( 'itsec-get-everything', 'Ithemes_Sync_Verb_ITSEC_Get_Everything', dirname( __FILE__ ) . '/sync-verbs/itsec-get-everything.php' );
|
208 |
}
|
209 |
|
210 |
public function register_modules() {
|
256 |
|
257 |
static $this_plugin;
|
258 |
|
|
|
|
|
259 |
if ( empty( $this_plugin ) ) {
|
260 |
$this_plugin = str_replace( WP_PLUGIN_DIR . '/', '', self::get_plugin_file() );
|
261 |
}
|
280 |
*/
|
281 |
public function add_plugin_meta_links( $meta, $plugin_file ) {
|
282 |
|
|
|
283 |
$plugin_base = str_replace( WP_PLUGIN_DIR . '/', '', self::get_plugin_file() );
|
284 |
|
285 |
if ( $plugin_base == $plugin_file ) {
|
298 |
*
|
299 |
* @return void
|
300 |
*/
|
301 |
+
public function modify_admin_bar( $wp_admin_bar ) {
|
|
|
|
|
302 |
|
303 |
if ( ! ITSEC_Core::current_user_can_manage() ) {
|
304 |
return;
|
305 |
}
|
306 |
|
307 |
// Add the Parent link.
|
308 |
+
$wp_admin_bar->add_node(
|
309 |
array(
|
310 |
'title' => __( 'Security', 'better-wp-security' ),
|
311 |
'href' => self::get_settings_page_url(),
|
313 |
)
|
314 |
);
|
315 |
|
316 |
+
$wp_admin_bar->add_node(
|
317 |
array(
|
318 |
+
'parent' => 'itsec_admin_bar_menu',
|
319 |
'title' => __( 'Settings', 'better-wp-security' ),
|
320 |
'href' => self::get_settings_page_url(),
|
321 |
+
'id' => 'itsec_admin_bar_settings',
|
322 |
)
|
323 |
);
|
324 |
|
325 |
+
$wp_admin_bar->add_node(
|
326 |
array(
|
327 |
+
'parent' => 'itsec_admin_bar_menu',
|
328 |
'title' => __( 'Security Check', 'better-wp-security' ),
|
329 |
'href' => self::get_security_check_page_url(),
|
330 |
+
'id' => 'itsec_admin_bar_security_check',
|
331 |
)
|
332 |
);
|
333 |
|
334 |
+
$wp_admin_bar->add_node(
|
335 |
array(
|
336 |
+
'parent' => 'itsec_admin_bar_menu',
|
337 |
'title' => __( 'Logs', 'better-wp-security' ),
|
338 |
'href' => self::get_logs_page_url(),
|
339 |
+
'id' => 'itsec_admin_bar_logs',
|
340 |
)
|
341 |
);
|
342 |
}
|
350 |
*/
|
351 |
public function do_upgrade() {
|
352 |
|
|
|
|
|
353 |
//require plugin setup information
|
354 |
if ( ! class_exists( 'ITSEC_Setup' ) ) {
|
355 |
require( self::get_core_dir() . '/class-itsec-setup.php' );
|
468 |
*/
|
469 |
public function save_plugin_data() {
|
470 |
|
|
|
|
|
471 |
$save_data = false; //flag to avoid saving data if we don't have to
|
472 |
|
473 |
$plugin_data = get_site_option( 'itsec_data' );
|
core/class-itsec-lib.php
CHANGED
@@ -517,6 +517,14 @@ final class ITSEC_Lib {
|
|
517 |
$whitelisted_ips[] = ITSEC_Lib::get_ip(); //add current user ip to whitelist
|
518 |
}
|
519 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
520 |
foreach ( $whitelisted_ips as $whitelisted_ip ) {
|
521 |
if ( ITSEC_Lib_IP_Tools::intersect( $ip, ITSEC_Lib_IP_Tools::ip_wild_to_ip_cidr( $whitelisted_ip ) ) ) {
|
522 |
return true;
|
@@ -899,4 +907,46 @@ final class ITSEC_Lib {
|
|
899 |
return 'http://www.traceip.net/?query=' . urlencode( $ip );
|
900 |
}
|
901 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
902 |
}
|
517 |
$whitelisted_ips[] = ITSEC_Lib::get_ip(); //add current user ip to whitelist
|
518 |
}
|
519 |
|
520 |
+
if ( ! empty( $_SERVER['SERVER_ADDR'] ) ) {
|
521 |
+
$whitelisted_ips[] = $_SERVER['SERVER_ADDR'];
|
522 |
+
}
|
523 |
+
|
524 |
+
if ( ! empty( $_SERVER['LOCAL_ADDR'] ) ) {
|
525 |
+
$whitelisted_ips[] = $_SERVER['LOCAL_ADDR'];
|
526 |
+
}
|
527 |
+
|
528 |
foreach ( $whitelisted_ips as $whitelisted_ip ) {
|
529 |
if ( ITSEC_Lib_IP_Tools::intersect( $ip, ITSEC_Lib_IP_Tools::ip_wild_to_ip_cidr( $whitelisted_ip ) ) ) {
|
530 |
return true;
|
907 |
return 'http://www.traceip.net/?query=' . urlencode( $ip );
|
908 |
}
|
909 |
}
|
910 |
+
|
911 |
+
public static function handle_wp_login_failed( $username ) {
|
912 |
+
$authentication_types = array();
|
913 |
+
|
914 |
+
if ( isset( $_SERVER['HTTP_AUTHORIZATION'] ) ) {
|
915 |
+
$http_auth_type = substr( $_SERVER['HTTP_AUTHORIZATION'], 0, 6 );
|
916 |
+
|
917 |
+
if ( 'Basic ' === $http_auth_type ) {
|
918 |
+
$authentication_types[] = 'header_http_basic_auth';
|
919 |
+
} else if ( 'OAuth ' === $http_auth_type ) {
|
920 |
+
$authentication_types[] = 'header_http_oauth';
|
921 |
+
}
|
922 |
+
}
|
923 |
+
|
924 |
+
if ( isset( $_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW'] ) ) {
|
925 |
+
$authentication_types[] = 'header_http_basic_auth';
|
926 |
+
}
|
927 |
+
|
928 |
+
if ( ! empty( $_GET['oauth_consumer_key'] ) ) {
|
929 |
+
$authentication_types[] = 'query_oauth';
|
930 |
+
}
|
931 |
+
|
932 |
+
if ( ! empty( $_POST['oauth_consumer_key'] ) ) {
|
933 |
+
$authentication_types[] = 'post_oauth';
|
934 |
+
}
|
935 |
+
|
936 |
+
if ( defined('XMLRPC_REQUEST') && XMLRPC_REQUEST ) {
|
937 |
+
$source = 'xmlrpc';
|
938 |
+
$authentication_types = array( 'username_and_password' );
|
939 |
+
} else if ( defined( 'REST_REQUEST' ) && REST_REQUEST ) {
|
940 |
+
$source = 'rest_api';
|
941 |
+
$authentication_types[] = 'cookie';
|
942 |
+
} else {
|
943 |
+
$source = 'wp-login.php';
|
944 |
+
$authentication_types = array( 'username_and_password' );
|
945 |
+
}
|
946 |
+
|
947 |
+
$details = compact( 'source', 'authentication_types' );
|
948 |
+
$details = apply_filters( 'itsec-filter-failed-login-details', $details );
|
949 |
+
|
950 |
+
do_action( 'itsec-handle-failed-login', $username, $details );
|
951 |
+
}
|
952 |
}
|
core/class-itsec-lockout.php
CHANGED
@@ -45,8 +45,8 @@ final class ITSEC_Lockout {
|
|
45 |
//Register Logger
|
46 |
add_filter( 'itsec_logger_modules', array( $this, 'register_logger' ) );
|
47 |
|
48 |
-
|
49 |
-
add_filter( '
|
50 |
|
51 |
add_action( 'itsec-settings-page-init', array( $this, 'init_settings_page' ) );
|
52 |
add_action( 'itsec-logs-page-init', array( $this, 'init_settings_page' ) );
|
@@ -785,30 +785,33 @@ final class ITSEC_Lockout {
|
|
785 |
}
|
786 |
|
787 |
/**
|
788 |
-
* Register
|
789 |
*
|
790 |
-
* @
|
791 |
*
|
792 |
-
* @
|
793 |
*/
|
794 |
-
public function
|
795 |
-
|
796 |
-
$
|
797 |
-
|
798 |
-
|
799 |
-
|
800 |
-
'itsec-get-temp-whitelist' => 'Ithemes_Sync_Verb_ITSEC_Get_Temp_Whitelist',
|
801 |
-
'itsec-set-temp-whitelist' => 'Ithemes_Sync_Verb_ITSEC_Set_Temp_Whitelist',
|
802 |
-
),
|
803 |
-
'everything' => array(
|
804 |
-
'itsec-get-lockouts',
|
805 |
-
'itsec-get-temp-whitelist',
|
806 |
-
),
|
807 |
-
'path' => dirname( __FILE__ ),
|
808 |
-
);
|
809 |
|
810 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
811 |
|
|
|
812 |
}
|
813 |
|
814 |
/**
|
45 |
//Register Logger
|
46 |
add_filter( 'itsec_logger_modules', array( $this, 'register_logger' ) );
|
47 |
|
48 |
+
add_action( 'ithemes_sync_register_verbs', array( $this, 'register_sync_verbs' ) );
|
49 |
+
add_filter( 'itsec-filter-itsec-get-everything-verbs', array( $this, 'register_sync_get_everything_verbs' ) );
|
50 |
|
51 |
add_action( 'itsec-settings-page-init', array( $this, 'init_settings_page' ) );
|
52 |
add_action( 'itsec-logs-page-init', array( $this, 'init_settings_page' ) );
|
785 |
}
|
786 |
|
787 |
/**
|
788 |
+
* Register verbs for Sync.
|
789 |
*
|
790 |
+
* @since 3.6.0
|
791 |
*
|
792 |
+
* @param Ithemes_Sync_API Sync API object.
|
793 |
*/
|
794 |
+
public function register_sync_verbs( $api ) {
|
795 |
+
$api->register( 'itsec-get-lockouts', 'Ithemes_Sync_Verb_ITSEC_Get_Lockouts', dirname( __FILE__ ) . '/sync-verbs/itsec-get-lockouts.php' );
|
796 |
+
$api->register( 'itsec-release-lockout', 'Ithemes_Sync_Verb_ITSEC_Release_Lockout', dirname( __FILE__ ) . '/sync-verbs/itsec-release-lockout.php' );
|
797 |
+
$api->register( 'itsec-get-temp-whitelist', 'Ithemes_Sync_Verb_ITSEC_Get_Temp_Whitelist', dirname( __FILE__ ) . '/sync-verbs/itsec-get-temp-whitelist.php' );
|
798 |
+
$api->register( 'itsec-set-temp-whitelist', 'Ithemes_Sync_Verb_ITSEC_Set_Temp_Whitelist', dirname( __FILE__ ) . '/sync-verbs/itsec-set-temp-whitelist.php' );
|
799 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
800 |
|
801 |
+
/**
|
802 |
+
* Filter to add verbs to the response for the itsec-get-everything verb.
|
803 |
+
*
|
804 |
+
* @since 3.6.0
|
805 |
+
*
|
806 |
+
* @param array Array of verbs.
|
807 |
+
*
|
808 |
+
* @return array Array of verbs.
|
809 |
+
*/
|
810 |
+
public function register_sync_get_everything_verbs( $verbs ) {
|
811 |
+
$verbs['lockout'][] = 'itsec-get-lockouts';
|
812 |
+
$verbs['lockout'][] = 'itsec-get-temp-whitelist';
|
813 |
|
814 |
+
return $verbs;
|
815 |
}
|
816 |
|
817 |
/**
|
core/class-itsec-sync.php
DELETED
@@ -1,89 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* Handles the abstraction of sync integration.
|
4 |
-
*
|
5 |
-
* Registers modules with sync verbs and loads appropriate verb classes where applicable.
|
6 |
-
*
|
7 |
-
* @package iThemes_Security
|
8 |
-
*
|
9 |
-
* @since 4.0.0
|
10 |
-
*/
|
11 |
-
final class ITSEC_Sync {
|
12 |
-
|
13 |
-
/**
|
14 |
-
* The module's that have registered with sync
|
15 |
-
*
|
16 |
-
* @since 4.1.0
|
17 |
-
* @access private
|
18 |
-
* @var array
|
19 |
-
*/
|
20 |
-
private $sync_modules = false;
|
21 |
-
|
22 |
-
/**
|
23 |
-
* Loads sync modules
|
24 |
-
*
|
25 |
-
* Executes primary file actions at plugins_loaded.
|
26 |
-
*
|
27 |
-
* @since 4.1.0
|
28 |
-
*
|
29 |
-
* @return ITSEC_Sync
|
30 |
-
*/
|
31 |
-
public function __construct() {}
|
32 |
-
|
33 |
-
/**
|
34 |
-
* Returns all modules registered with Sync.
|
35 |
-
*
|
36 |
-
* Returns an array of all modules containing sync verbs.
|
37 |
-
*
|
38 |
-
* @since 4.1.0
|
39 |
-
*
|
40 |
-
* @return array sync module registrations
|
41 |
-
*/
|
42 |
-
public function get_modules() {
|
43 |
-
if ( is_array( $this->sync_modules ) ) {
|
44 |
-
return $this->sync_modules;
|
45 |
-
}
|
46 |
-
|
47 |
-
$this->sync_modules = apply_filters( 'itsec_sync_modules', array() );
|
48 |
-
|
49 |
-
if ( ! is_array( $this->sync_modules ) ) {
|
50 |
-
$this->sync_modules = array();
|
51 |
-
}
|
52 |
-
|
53 |
-
return $this->sync_modules;
|
54 |
-
|
55 |
-
}
|
56 |
-
|
57 |
-
/**
|
58 |
-
* Register verbs for iThemes Sync.
|
59 |
-
*
|
60 |
-
* Registers all verbs for a given module.
|
61 |
-
*
|
62 |
-
* @since 4.1.0
|
63 |
-
*
|
64 |
-
* @param object $api iThemes Sync Object
|
65 |
-
*
|
66 |
-
* @return void
|
67 |
-
*/
|
68 |
-
public function register_verbs( $api ) {
|
69 |
-
$modules = $this->get_modules();
|
70 |
-
|
71 |
-
foreach ( $modules as $module ) {
|
72 |
-
|
73 |
-
if ( isset( $module['verbs'] ) && isset( $module['path'] ) ) {
|
74 |
-
|
75 |
-
foreach ( $module['verbs'] as $name => $class ) {
|
76 |
-
|
77 |
-
$api->register( $name, $class, trailingslashit( $module['path'] ) . 'class-ithemes-sync-verb-' . $name . '.php' );
|
78 |
-
|
79 |
-
}
|
80 |
-
|
81 |
-
}
|
82 |
-
|
83 |
-
}
|
84 |
-
|
85 |
-
$api->register( 'itsec-get-everything', 'Ithemes_Sync_Verb_ITSEC_Get_Everything', dirname( __FILE__ ) . '/class-ithemes-sync-verb-itsec-get-everything.php' );
|
86 |
-
|
87 |
-
}
|
88 |
-
|
89 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
core/history.txt
CHANGED
@@ -481,3 +481,12 @@
|
|
481 |
2.9.0 - 2016-12-28 - Chris Jean
|
482 |
Updated Feature: Updated the "REST API" feature in the WordPress Tweaks section. The feature now has proper support for protecting privacy on your site without preventing the REST API from functioning.
|
483 |
Enhancement: Updated Security Check to enforce setting the "REST API" setting to "Restricted Access".
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
481 |
2.9.0 - 2016-12-28 - Chris Jean
|
482 |
Updated Feature: Updated the "REST API" feature in the WordPress Tweaks section. The feature now has proper support for protecting privacy on your site without preventing the REST API from functioning.
|
483 |
Enhancement: Updated Security Check to enforce setting the "REST API" setting to "Restricted Access".
|
484 |
+
3.0.0 - 2017-02-07 - Chris Jean
|
485 |
+
Enhancement: Added logging for failed two-factor, OAuth, and REST API authentications.
|
486 |
+
Enhancement: Added logging details about the source of login failures and the type of authentication that failed.
|
487 |
+
Enhancement: Due to improvements in tracking authentication failures, brute force attempts using alternate authentication methods are more reliably found and blocked.
|
488 |
+
Enhancement: The server's IP is treated as whitelisted and will not be considered for lockouts or bans.
|
489 |
+
Enhancement: Reduced memory usage when creating a backup.
|
490 |
+
Enhancement: Changed log entry description of "IP Flagged as bad by iThemes IPCheck" to "IP Flagged by Network Brute Force Protection". This should help clarify the meaning of the log entry.
|
491 |
+
Enhancement: Improved efficiency of the Network Brute Force Protection feature.
|
492 |
+
Bug Fix: Fixed bug that prevented Network Brute Force Protection from working properly on some sites.
|
core/modules/away-mode/class-itsec-away-mode.php
CHANGED
@@ -3,14 +3,15 @@
|
|
3 |
final class ITSEC_Away_Mode {
|
4 |
|
5 |
public function run() {
|
|
|
6 |
|
7 |
//Execute away mode functions on admin init
|
8 |
add_filter( 'itsec_logger_modules', array( $this, 'register_logger' ) );
|
9 |
add_action( 'itsec_admin_init', array( $this, 'run_active_check' ) );
|
10 |
add_action( 'login_init', array( $this, 'run_active_check' ) );
|
11 |
|
12 |
-
|
13 |
-
add_filter( '
|
14 |
|
15 |
}
|
16 |
|
@@ -122,25 +123,29 @@ final class ITSEC_Away_Mode {
|
|
122 |
}
|
123 |
|
124 |
/**
|
125 |
-
* Register
|
126 |
*
|
127 |
-
* @
|
128 |
*
|
129 |
-
* @
|
130 |
*/
|
131 |
-
public function
|
132 |
-
|
133 |
-
$
|
134 |
-
|
135 |
-
'itsec-get-away-mode' => 'Ithemes_Sync_Verb_ITSEC_Get_Away_Mode',
|
136 |
-
'itsec-override-away-mode' => 'Ithemes_Sync_Verb_ITSEC_Override_Away_Mode'
|
137 |
-
),
|
138 |
-
'everything' => 'itsec-get-away-mode',
|
139 |
-
'path' => dirname( __FILE__ ),
|
140 |
-
);
|
141 |
|
142 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
143 |
|
|
|
144 |
}
|
145 |
-
|
146 |
}
|
3 |
final class ITSEC_Away_Mode {
|
4 |
|
5 |
public function run() {
|
6 |
+
return;
|
7 |
|
8 |
//Execute away mode functions on admin init
|
9 |
add_filter( 'itsec_logger_modules', array( $this, 'register_logger' ) );
|
10 |
add_action( 'itsec_admin_init', array( $this, 'run_active_check' ) );
|
11 |
add_action( 'login_init', array( $this, 'run_active_check' ) );
|
12 |
|
13 |
+
add_action( 'ithemes_sync_register_verbs', array( $this, 'register_sync_verbs' ) );
|
14 |
+
add_filter( 'itsec-filter-itsec-get-everything-verbs', array( $this, 'register_sync_get_everything_verbs' ) );
|
15 |
|
16 |
}
|
17 |
|
123 |
}
|
124 |
|
125 |
/**
|
126 |
+
* Register verbs for Sync.
|
127 |
*
|
128 |
+
* @since 3.6.0
|
129 |
*
|
130 |
+
* @param Ithemes_Sync_API Sync API object.
|
131 |
*/
|
132 |
+
public function register_sync_verbs( $api ) {
|
133 |
+
$api->register( 'itsec-get-away-mode', 'Ithemes_Sync_Verb_ITSEC_Get_Away_Mode', dirname( __FILE__ ) . '/sync-verbs/itsec-get-away-mode.php' );
|
134 |
+
$api->register( 'itsec-override-away-mode', 'Ithemes_Sync_Verb_ITSEC_Override_Away_Mode', dirname( __FILE__ ) . '/sync-verbs/itsec-override-away-mode.php' );
|
135 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
136 |
|
137 |
+
/**
|
138 |
+
* Filter to add verbs to the response for the itsec-get-everything verb.
|
139 |
+
*
|
140 |
+
* @since 3.6.0
|
141 |
+
*
|
142 |
+
* @param array Array of verbs.
|
143 |
+
*
|
144 |
+
* @return array Array of verbs.
|
145 |
+
*/
|
146 |
+
public function register_sync_get_everything_verbs( $verbs ) {
|
147 |
+
$verbs['away_mode'][] = 'itsec-get-away-mode';
|
148 |
|
149 |
+
return $verbs;
|
150 |
}
|
|
|
151 |
}
|
core/modules/away-mode/sync-verbs/index.php
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
<?php // Silence is golden.
|
core/modules/away-mode/{class-ithemes-sync-verb-itsec-get-away-mode.php → sync-verbs/itsec-get-away-mode.php}
RENAMED
File without changes
|
core/modules/away-mode/{class-ithemes-sync-verb-itsec-override-away-mode.php → sync-verbs/itsec-override-away-mode.php}
RENAMED
File without changes
|
core/modules/backup/class-itsec-backup.php
CHANGED
@@ -83,28 +83,26 @@ class ITSEC_Backup {
|
|
83 |
* @return mixed false on error or nothing
|
84 |
*/
|
85 |
public function do_backup( $one_time = false ) {
|
86 |
-
ITSEC_Lib::set_minimum_memory_limit( '256M' );
|
87 |
-
|
88 |
$itsec_files = ITSEC_Core::get_itsec_files();
|
89 |
|
90 |
-
if ( $itsec_files->get_file_lock( 'backup' ) ) {
|
|
|
|
|
91 |
|
92 |
-
$this->execute_backup( $one_time );
|
93 |
|
94 |
-
|
|
|
|
|
95 |
|
96 |
-
|
97 |
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
|
105 |
-
}
|
106 |
-
} else {
|
107 |
-
return new WP_Error( 'itsec-backup-do-backup-already-running', __( 'Unable to create a backup at this time since a backup is currently being created. If you wish to create an additional backup, please wait a few minutes before trying again.', 'better-wp-security' ) );
|
108 |
}
|
109 |
}
|
110 |
|
@@ -120,229 +118,193 @@ class ITSEC_Backup {
|
|
120 |
* @return void
|
121 |
*/
|
122 |
private function execute_backup( $one_time = false ) {
|
|
|
123 |
|
124 |
-
global $wpdb, $itsec_globals, $itsec_logger;
|
125 |
|
126 |
-
//get all of the tables
|
127 |
-
if ( isset( $this->settings['all_sites'] ) && true === $this->settings['all_sites'] ) {
|
128 |
|
129 |
-
|
130 |
-
|
131 |
-
} else {
|
132 |
|
133 |
-
|
|
|
134 |
|
|
|
|
|
|
|
|
|
135 |
}
|
136 |
|
137 |
-
$
|
138 |
|
139 |
-
|
140 |
-
|
|
|
141 |
|
142 |
-
$num_fields = sizeof( $wpdb->get_results( 'DESCRIBE `' . $table[0] . '`;' ) );
|
143 |
|
144 |
-
|
|
|
|
|
145 |
|
146 |
-
$row2 = $wpdb->get_row( 'SHOW CREATE TABLE `' . $table[0] . '`;', ARRAY_N );
|
147 |
|
148 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
149 |
|
150 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
151 |
|
152 |
-
$result = $wpdb->get_results( 'SELECT * FROM `' . $table[0] . '`;', ARRAY_N );
|
153 |
|
154 |
-
|
155 |
|
156 |
-
|
|
|
157 |
|
158 |
-
|
|
|
159 |
|
160 |
-
|
161 |
-
|
162 |
|
|
|
163 |
if ( isset( $row[$j] ) ) {
|
|
|
164 |
|
165 |
-
|
|
|
|
|
166 |
|
|
|
167 |
} else {
|
168 |
-
|
169 |
-
$return .= '""';
|
170 |
-
|
171 |
}
|
172 |
|
173 |
if ( $j < ( $num_fields - 1 ) ) {
|
174 |
-
$
|
175 |
}
|
176 |
-
|
177 |
}
|
178 |
|
179 |
-
$
|
180 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
181 |
}
|
182 |
|
183 |
}
|
184 |
|
185 |
-
$
|
186 |
|
187 |
}
|
188 |
|
189 |
-
$
|
190 |
-
|
191 |
-
//save file
|
192 |
-
$file = 'backup-' . substr( sanitize_title( get_bloginfo( 'name' ) ), 0, 20 ) . '-' . current_time( 'Ymd-His' ) . '-' . wp_generate_password( 30, false );
|
193 |
-
|
194 |
-
require_once( ITSEC_Core::get_core_dir() . 'lib/class-itsec-lib-directory.php' );
|
195 |
-
|
196 |
-
$dir = $this->settings['location'];
|
197 |
-
ITSEC_Lib_Directory::create( $dir );
|
198 |
-
|
199 |
-
|
200 |
-
$fileext = '.sql';
|
201 |
-
|
202 |
-
$handle = @fopen( $dir . '/' . $file . '.sql', 'w+' );
|
203 |
-
|
204 |
-
@fwrite( $handle, $return );
|
205 |
-
@fclose( $handle );
|
206 |
-
|
207 |
-
//zip the file
|
208 |
-
if ( true === $this->settings['zip'] ) {
|
209 |
|
|
|
210 |
if ( ! class_exists( 'PclZip' ) ) {
|
211 |
require( ABSPATH . 'wp-admin/includes/class-pclzip.php' );
|
212 |
}
|
213 |
|
214 |
-
$
|
215 |
-
|
216 |
-
if ( 0 != $zip->create( $dir . '/' . $file . '.sql', PCLZIP_OPT_REMOVE_PATH, $dir ) ) {
|
217 |
-
|
218 |
-
//delete .sql and keep zip
|
219 |
-
@unlink( $dir . '/' . $file . '.sql' );
|
220 |
-
|
221 |
-
$fileext = '.zip';
|
222 |
|
|
|
|
|
|
|
223 |
}
|
224 |
-
|
225 |
}
|
226 |
|
227 |
if ( 2 !== $this->settings['method'] || true === $one_time ) {
|
228 |
-
|
229 |
-
$mail = new ITSEC_Mail();
|
230 |
-
$mail->add_header( esc_html__( 'Database Backup', 'better-wp-security' ), sprintf( wp_kses( __( 'Site Database Backup for <b>%s</b>', 'better-wp-security' ), array( 'b' => array() ) ), date_i18n( get_option( 'date_format' ) ) ) );
|
231 |
-
$mail->add_info_box( esc_html__( 'Attached is the database backup file for your site.', 'better-wp-security' ), 'attachment' );
|
232 |
-
|
233 |
-
|
234 |
-
$mail->add_section_heading( esc_html__( 'Website', 'better-wp-security' ) );
|
235 |
-
$mail->add_text( esc_html( network_home_url() ) );
|
236 |
-
|
237 |
-
$mail->add_section_heading( esc_html__( 'Date', 'better-wp-security' ) );
|
238 |
-
$mail->add_text( esc_html( date_i18n( get_option( 'date_format' ) ) ) );
|
239 |
-
|
240 |
-
$mail->add_footer();
|
241 |
-
|
242 |
-
|
243 |
-
$recipients = ITSEC_Modules::get_setting( 'global', 'backup_email' );
|
244 |
-
$mail->set_recipients( $recipients );
|
245 |
-
|
246 |
-
$subject = sprintf( esc_html__( '[%s] Database Backup', 'better-wp-security' ), esc_url( network_home_url() ) );
|
247 |
-
$subject = apply_filters( 'itsec_backup_email_subject', $subject );
|
248 |
-
$mail->set_subject( $subject, false );
|
249 |
-
|
250 |
-
$mail->add_attachment( "$dir/$file$fileext" );
|
251 |
-
|
252 |
-
$mail_success = $mail->send();
|
253 |
}
|
254 |
|
255 |
if ( 1 === $this->settings['method'] ) {
|
|
|
|
|
|
|
256 |
|
257 |
-
|
258 |
-
|
259 |
-
} else {
|
260 |
-
|
261 |
-
$retain = isset( $this->settings['retain'] ) ? absint( $this->settings['retain'] ) : 0;
|
262 |
-
|
263 |
-
//delete extra files
|
264 |
-
if ( 0 < $retain ) {
|
265 |
-
|
266 |
-
$files = scandir( $dir, 1 );
|
267 |
-
|
268 |
$count = 0;
|
269 |
|
270 |
-
|
271 |
-
|
272 |
-
|
273 |
-
|
274 |
-
if ( strstr( $file, 'backup' ) ) {
|
275 |
-
|
276 |
-
if ( $count >= $retain ) {
|
277 |
-
@unlink( trailingslashit( $dir ) . $file );
|
278 |
-
}
|
279 |
-
|
280 |
-
$count ++;
|
281 |
-
}
|
282 |
|
|
|
|
|
283 |
}
|
284 |
|
|
|
285 |
}
|
286 |
-
|
287 |
}
|
288 |
-
|
289 |
-
}
|
290 |
-
|
291 |
-
if ( false === $one_time ) {
|
292 |
-
ITSEC_Modules::set_setting( 'backup', 'last_run', ITSEC_Core::get_current_time_gmt() );
|
293 |
}
|
294 |
|
295 |
-
switch ( $this->settings['method'] ) {
|
296 |
-
|
297 |
-
case 0:
|
298 |
-
|
299 |
-
if ( false === $mail_success ) {
|
300 |
|
301 |
-
|
302 |
-
|
303 |
-
'details' => __( 'saved locally but email to backup recipients could not be sent.', 'better-wp-security' ),
|
304 |
-
);
|
305 |
|
306 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
307 |
|
308 |
-
|
309 |
-
|
310 |
-
|
311 |
-
);
|
312 |
|
313 |
-
|
|
|
314 |
|
315 |
-
|
316 |
-
|
|
|
317 |
|
318 |
-
if ( false === $mail_success ) {
|
319 |
|
320 |
-
|
321 |
-
|
322 |
-
'details' => __( 'email to backup recipients could not be sent.', 'better-wp-security' ),
|
323 |
-
);
|
324 |
|
325 |
-
|
|
|
326 |
|
327 |
-
|
328 |
-
'status' => __( 'Success', 'better-wp-security' ),
|
329 |
-
'details' => __( 'emailed to backup recipients', 'better-wp-security' ),
|
330 |
-
);
|
331 |
|
332 |
-
}
|
333 |
|
334 |
-
|
335 |
-
|
336 |
-
$status = array(
|
337 |
-
'status' => __( 'Success', 'better-wp-security' ),
|
338 |
-
'details' => __( 'saved locally', 'better-wp-security' ),
|
339 |
-
);
|
340 |
-
break;
|
341 |
|
342 |
-
|
|
|
|
|
343 |
|
344 |
-
$
|
345 |
|
|
|
346 |
}
|
347 |
|
348 |
/**
|
83 |
* @return mixed false on error or nothing
|
84 |
*/
|
85 |
public function do_backup( $one_time = false ) {
|
|
|
|
|
86 |
$itsec_files = ITSEC_Core::get_itsec_files();
|
87 |
|
88 |
+
if ( ! $itsec_files->get_file_lock( 'backup' ) ) {
|
89 |
+
return new WP_Error( 'itsec-backup-do-backup-already-running', __( 'Unable to create a backup at this time since a backup is currently being created. If you wish to create an additional backup, please wait a few minutes before trying again.', 'better-wp-security' ) );
|
90 |
+
}
|
91 |
|
|
|
92 |
|
93 |
+
ITSEC_Lib::set_minimum_memory_limit( '256M' );
|
94 |
+
$this->execute_backup( $one_time );
|
95 |
+
$itsec_files->release_file_lock( 'backup' );
|
96 |
|
97 |
+
switch ( $this->settings['method'] ) {
|
98 |
|
99 |
+
case 0:
|
100 |
+
return __( 'Backup complete. The backup was sent to the selected email recipients and was saved locally.', 'better-wp-security' );
|
101 |
+
case 1:
|
102 |
+
return __( 'Backup complete. The backup was sent to the selected email recipients.', 'better-wp-security' );
|
103 |
+
default:
|
104 |
+
return __( 'Backup complete. The backup was saved locally.', 'better-wp-security' );
|
105 |
|
|
|
|
|
|
|
106 |
}
|
107 |
}
|
108 |
|
118 |
* @return void
|
119 |
*/
|
120 |
private function execute_backup( $one_time = false ) {
|
121 |
+
global $wpdb, $itsec_logger;
|
122 |
|
|
|
123 |
|
|
|
|
|
124 |
|
125 |
+
require_once( ITSEC_Core::get_core_dir() . 'lib/class-itsec-lib-directory.php' );
|
|
|
|
|
126 |
|
127 |
+
$dir = $this->settings['location'];
|
128 |
+
$result = ITSEC_Lib_Directory::create( $dir );
|
129 |
|
130 |
+
if ( is_wp_error( $result ) ) {
|
131 |
+
return $result;
|
132 |
+
} else if ( ! $result ) {
|
133 |
+
return new WP_Error( 'itsec-backup-failed-to-create-backup-dir', esc_html__( 'Unable to create the backup directory due to an unknown error.', 'better-wp-security' ) );
|
134 |
}
|
135 |
|
136 |
+
$file = "$dir/backup-" . substr( sanitize_title( get_bloginfo( 'name' ) ), 0, 20 ) . '-' . current_time( 'Ymd-His' ) . '-' . wp_generate_password( 30, false ) . '.sql';
|
137 |
|
138 |
+
if ( false === ( $fh = @fopen( $file, 'w' ) ) ) {
|
139 |
+
return new WP_Error( 'itsec-backup-failed-to-write-backup-file', esc_html__( 'Unable to write the backup file. This may be due to a permissions or disk space issue.', 'better-wp-security' ) );
|
140 |
+
}
|
141 |
|
|
|
142 |
|
143 |
+
if ( false === $one_time ) {
|
144 |
+
ITSEC_Modules::set_setting( 'backup', 'last_run', ITSEC_Core::get_current_time_gmt() );
|
145 |
+
}
|
146 |
|
|
|
147 |
|
148 |
+
if ( $this->settings['all_sites'] ) {
|
149 |
+
$tables = $wpdb->get_col( 'SHOW TABLES' );
|
150 |
+
} else {
|
151 |
+
$tables = $wpdb->get_col( 'SHOW TABLES LIKE "' . $wpdb->base_prefix . '%"' );
|
152 |
+
}
|
153 |
+
|
154 |
+
$max_rows_per_query = 1000;
|
155 |
|
156 |
+
foreach ( $tables as $table ) {
|
157 |
+
$create_table = $wpdb->get_var( "SHOW CREATE TABLE `$table`;", 1 ) . ';' . PHP_EOL . PHP_EOL;
|
158 |
+
$create_table = preg_replace( '/^CREATE TABLE /', 'CREATE TABLE IF NOT EXISTS ', $create_table );
|
159 |
+
@fwrite( $fh, $create_table );
|
160 |
+
|
161 |
+
if ( in_array( substr( $table, strlen( $wpdb->prefix ) ), $this->settings['exclude'] ) ) {
|
162 |
+
// User selected to exclude the data from this table.
|
163 |
+
fwrite( $fh, PHP_EOL . PHP_EOL );
|
164 |
+
continue;
|
165 |
+
}
|
166 |
|
|
|
167 |
|
168 |
+
$num_fields = count( $wpdb->get_results( "DESCRIBE `$table`;" ) );
|
169 |
|
170 |
+
$offset = 0;
|
171 |
+
$has_more_rows = true;
|
172 |
|
173 |
+
while ( $has_more_rows ) {
|
174 |
+
$rows = $wpdb->get_results( "SELECT * FROM `$table` LIMIT $offset, $max_rows_per_query;", ARRAY_N );
|
175 |
|
176 |
+
foreach ( $rows as $row ) {
|
177 |
+
$sql = "INSERT INTO `$table` VALUES (";
|
178 |
|
179 |
+
for ( $j = 0; $j < $num_fields; $j ++ ) {
|
180 |
if ( isset( $row[$j] ) ) {
|
181 |
+
$row[$j] = addslashes( $row[$j] );
|
182 |
|
183 |
+
if ( PHP_EOL !== "\n" ) {
|
184 |
+
$row[$j] = preg_replace( '#' . PHP_EOL . '#', "\n", $row[$j] );
|
185 |
+
}
|
186 |
|
187 |
+
$sql .= '"' . $row[$j] . '"';
|
188 |
} else {
|
189 |
+
$sql .= '""';
|
|
|
|
|
190 |
}
|
191 |
|
192 |
if ( $j < ( $num_fields - 1 ) ) {
|
193 |
+
$sql .= ',';
|
194 |
}
|
|
|
195 |
}
|
196 |
|
197 |
+
$sql .= ");" . PHP_EOL;
|
198 |
|
199 |
+
@fwrite( $fh, $sql );
|
200 |
+
}
|
201 |
+
|
202 |
+
if ( count( $rows ) < $max_rows_per_query ) {
|
203 |
+
$has_more_rows = false;
|
204 |
+
} else {
|
205 |
+
$offset += $max_rows_per_query;
|
206 |
}
|
207 |
|
208 |
}
|
209 |
|
210 |
+
@fwrite( $fh, PHP_EOL . PHP_EOL );
|
211 |
|
212 |
}
|
213 |
|
214 |
+
@fwrite( $fh, PHP_EOL . PHP_EOL );
|
215 |
+
@fclose( $fh );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
216 |
|
217 |
+
if ( $this->settings['zip'] ) {
|
218 |
if ( ! class_exists( 'PclZip' ) ) {
|
219 |
require( ABSPATH . 'wp-admin/includes/class-pclzip.php' );
|
220 |
}
|
221 |
|
222 |
+
$zip_file = substr( $file, 0, -4 ) . '.zip';
|
223 |
+
$pclzip = new PclZip( $zip_file );
|
|
|
|
|
|
|
|
|
|
|
|
|
224 |
|
225 |
+
if ( 0 != $pclzip->create( $file, PCLZIP_OPT_REMOVE_PATH, $dir ) ) {
|
226 |
+
@unlink( $file );
|
227 |
+
$file = $zip_file;
|
228 |
}
|
|
|
229 |
}
|
230 |
|
231 |
if ( 2 !== $this->settings['method'] || true === $one_time ) {
|
232 |
+
$mail_success = $this->send_mail( $file );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
233 |
}
|
234 |
|
235 |
if ( 1 === $this->settings['method'] ) {
|
236 |
+
@unlink( $file );
|
237 |
+
} else if ( $this->settings['retain'] > 0 ) {
|
238 |
+
$files = scandir( $dir, SCANDIR_SORT_DESCENDING );
|
239 |
|
240 |
+
if ( is_array( $files ) && count( $files ) > 0 ) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
241 |
$count = 0;
|
242 |
|
243 |
+
foreach ( $files as $file ) {
|
244 |
+
if ( ! strstr( $file, 'backup' ) ) {
|
245 |
+
continue;
|
246 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
247 |
|
248 |
+
if ( $count >= $this->settings['retain'] ) {
|
249 |
+
@unlink( trailingslashit( $dir ) . $file );
|
250 |
}
|
251 |
|
252 |
+
$count++;
|
253 |
}
|
|
|
254 |
}
|
|
|
|
|
|
|
|
|
|
|
255 |
}
|
256 |
|
|
|
|
|
|
|
|
|
|
|
257 |
|
258 |
+
$status = __( 'Success', 'better-wp-security' );
|
259 |
+
$details = __( 'saved locally', 'better-wp-security' );
|
|
|
|
|
260 |
|
261 |
+
if ( 0 === $this->settings['method'] ) {
|
262 |
+
if ( false === $mail_success ) {
|
263 |
+
$status = __( 'Error', 'better-wp-security' );
|
264 |
+
$details = __( 'saved locally but email to backup recipients could not be sent.', 'better-wp-security' );
|
265 |
+
} else {
|
266 |
+
$details = __( 'emailed to backup recipients and saved locally', 'better-wp-security' );
|
267 |
+
}
|
268 |
+
} else if ( 1 === $this->settings['method'] ) {
|
269 |
+
if ( false === $mail_success ) {
|
270 |
+
$status = __( 'Error', 'better-wp-security' );
|
271 |
+
$details = __( 'email to backup recipients could not be sent.', 'better-wp-security' );
|
272 |
+
} else {
|
273 |
+
$details = __( 'emailed to backup recipients', 'better-wp-security' );
|
274 |
+
}
|
275 |
+
}
|
276 |
|
277 |
+
$data = compact( 'status', 'details' );
|
278 |
+
$itsec_logger->log_event( 'backup', 3, array( $data ) );
|
279 |
+
}
|
|
|
280 |
|
281 |
+
private function send_mail( $file ) {
|
282 |
+
require_once( ITSEC_Core::get_core_dir() . 'lib/class-itsec-mail.php' );
|
283 |
|
284 |
+
$mail = new ITSEC_Mail();
|
285 |
+
$mail->add_header( esc_html__( 'Database Backup', 'better-wp-security' ), sprintf( wp_kses( __( 'Site Database Backup for <b>%s</b>', 'better-wp-security' ), array( 'b' => array() ) ), date_i18n( get_option( 'date_format' ) ) ) );
|
286 |
+
$mail->add_info_box( esc_html__( 'Attached is the database backup file for your site.', 'better-wp-security' ), 'attachment' );
|
287 |
|
|
|
288 |
|
289 |
+
$mail->add_section_heading( esc_html__( 'Website', 'better-wp-security' ) );
|
290 |
+
$mail->add_text( esc_html( network_home_url() ) );
|
|
|
|
|
291 |
|
292 |
+
$mail->add_section_heading( esc_html__( 'Date', 'better-wp-security' ) );
|
293 |
+
$mail->add_text( esc_html( date_i18n( get_option( 'date_format' ) ) ) );
|
294 |
|
295 |
+
$mail->add_footer();
|
|
|
|
|
|
|
296 |
|
|
|
297 |
|
298 |
+
$recipients = ITSEC_Modules::get_setting( 'global', 'backup_email' );
|
299 |
+
$mail->set_recipients( $recipients );
|
|
|
|
|
|
|
|
|
|
|
300 |
|
301 |
+
$subject = sprintf( esc_html__( '[%s] Database Backup', 'better-wp-security' ), esc_url( network_home_url() ) );
|
302 |
+
$subject = apply_filters( 'itsec_backup_email_subject', $subject );
|
303 |
+
$mail->set_subject( $subject, false );
|
304 |
|
305 |
+
$mail->add_attachment( $file );
|
306 |
|
307 |
+
return $mail->send();
|
308 |
}
|
309 |
|
310 |
/**
|
core/modules/brute-force/class-itsec-brute-force.php
CHANGED
@@ -9,18 +9,15 @@ class ITSEC_Brute_Force {
|
|
9 |
function run() {
|
10 |
|
11 |
$this->settings = ITSEC_Modules::get_settings( 'brute-force' );
|
12 |
-
|
13 |
-
$this->username = null;
|
14 |
|
15 |
add_action( 'wp_login', array( $this, 'wp_login' ), 10, 2 );
|
16 |
-
add_action( '
|
17 |
|
18 |
add_filter( 'itsec_logger_displays', array( $this, 'itsec_logger_displays' ) ); //adds logs metaboxes
|
19 |
|
20 |
add_filter( 'authenticate', array( $this, 'authenticate' ), 10, 3 );
|
21 |
add_filter( 'itsec_lockout_modules', array( $this, 'itsec_lockout_modules' ) );
|
22 |
add_filter( 'itsec_logger_modules', array( $this, 'itsec_logger_modules' ) );
|
23 |
-
add_filter( 'xmlrpc_login_error', array( $this, 'xmlrpc_login_error' ), 10, 2 );
|
24 |
add_filter( 'jetpack_get_default_modules', array( $this, 'jetpack_get_default_modules' ) ); //disable jetpack protect via Geoge Stephanis
|
25 |
|
26 |
}
|
@@ -70,13 +67,6 @@ class ITSEC_Brute_Force {
|
|
70 |
|
71 |
}
|
72 |
|
73 |
-
//Set username for xml_rpc block
|
74 |
-
if ( defined( 'XMLRPC_REQUEST' ) && XMLRPC_REQUEST === true ) {
|
75 |
-
|
76 |
-
$this->username = $username;
|
77 |
-
|
78 |
-
}
|
79 |
-
|
80 |
return $user;
|
81 |
|
82 |
}
|
@@ -186,80 +176,26 @@ class ITSEC_Brute_Force {
|
|
186 |
*
|
187 |
* @return void
|
188 |
*/
|
189 |
-
public function
|
190 |
-
|
191 |
global $itsec_lockout, $itsec_logger;
|
192 |
|
193 |
-
|
194 |
-
|
195 |
-
$itsec_logger->log_event( 'brute_force', 5, array(), ITSEC_Lib::get_ip(), sanitize_text_field( $username ) );
|
196 |
-
|
197 |
-
$itsec_lockout->do_lockout( 'brute_force_admin_user', sanitize_text_field( $username ) );
|
198 |
-
|
199 |
-
}
|
200 |
-
|
201 |
-
if ( isset( $_POST['log'] ) && $_POST['log'] != '' && isset( $_POST['pwd'] ) && $_POST['pwd'] != '' ) {
|
202 |
-
|
203 |
-
$user_id = username_exists( sanitize_text_field( $username ) );
|
204 |
-
|
205 |
-
if ( $user_id === false || $user_id === null ) {
|
206 |
-
|
207 |
-
$itsec_lockout->check_lockout( false, $username );
|
208 |
-
|
209 |
-
} else {
|
210 |
-
|
211 |
-
$itsec_lockout->check_lockout( $user_id );
|
212 |
-
|
213 |
-
};
|
214 |
-
|
215 |
-
$itsec_logger->log_event( 'brute_force', 5, array(), ITSEC_Lib::get_ip(), sanitize_text_field( $username ), intval( $user_id ) );
|
216 |
|
217 |
-
|
|
|
|
|
218 |
|
|
|
219 |
}
|
220 |
|
221 |
-
|
222 |
-
|
223 |
-
/**
|
224 |
-
* Execute brute force against xml_rpc login
|
225 |
-
*
|
226 |
-
* @Since 4.4
|
227 |
-
*
|
228 |
-
* @param mixed $error WordPress error
|
229 |
-
*
|
230 |
-
* @return mixed WordPress error
|
231 |
-
*/
|
232 |
-
public function xmlrpc_login_error( $error ) {
|
233 |
-
|
234 |
-
global $itsec_lockout, $itsec_logger;
|
235 |
-
|
236 |
-
if ( isset( $this->settings['auto_ban_admin'] ) && $this->settings['auto_ban_admin'] === true && trim( sanitize_text_field( $this->username ) ) == 'admin' ) {
|
237 |
-
|
238 |
-
$itsec_logger->log_event( 'brute_force', 5, array(), ITSEC_Lib::get_ip(), $this->username );
|
239 |
-
|
240 |
-
$itsec_lockout->do_lockout( 'brute_force_admin_user', $this->username );
|
241 |
-
|
242 |
} else {
|
|
|
|
|
243 |
|
244 |
-
|
245 |
-
|
246 |
-
if ( $user_id === false || $user_id === null ) {
|
247 |
-
|
248 |
-
$itsec_lockout->check_lockout( false, $this->username );
|
249 |
-
|
250 |
-
} else {
|
251 |
-
|
252 |
-
$itsec_lockout->check_lockout( $user_id );
|
253 |
-
|
254 |
-
};
|
255 |
-
|
256 |
-
$itsec_logger->log_event( 'brute_force', 5, array(), ITSEC_Lib::get_ip(), $this->username, intval( $user_id ) );
|
257 |
-
|
258 |
-
$itsec_lockout->do_lockout( 'brute_force', $this->username );
|
259 |
-
|
260 |
-
}
|
261 |
-
|
262 |
-
return $error;
|
263 |
}
|
264 |
|
265 |
/**
|
9 |
function run() {
|
10 |
|
11 |
$this->settings = ITSEC_Modules::get_settings( 'brute-force' );
|
|
|
|
|
12 |
|
13 |
add_action( 'wp_login', array( $this, 'wp_login' ), 10, 2 );
|
14 |
+
add_action( 'itsec-handle-failed-login', array( $this, 'handle_failed_login' ), 10, 2 );
|
15 |
|
16 |
add_filter( 'itsec_logger_displays', array( $this, 'itsec_logger_displays' ) ); //adds logs metaboxes
|
17 |
|
18 |
add_filter( 'authenticate', array( $this, 'authenticate' ), 10, 3 );
|
19 |
add_filter( 'itsec_lockout_modules', array( $this, 'itsec_lockout_modules' ) );
|
20 |
add_filter( 'itsec_logger_modules', array( $this, 'itsec_logger_modules' ) );
|
|
|
21 |
add_filter( 'jetpack_get_default_modules', array( $this, 'jetpack_get_default_modules' ) ); //disable jetpack protect via Geoge Stephanis
|
22 |
|
23 |
}
|
67 |
|
68 |
}
|
69 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
70 |
return $user;
|
71 |
|
72 |
}
|
176 |
*
|
177 |
* @return void
|
178 |
*/
|
179 |
+
public function handle_failed_login( $username, $details ) {
|
|
|
180 |
global $itsec_lockout, $itsec_logger;
|
181 |
|
182 |
+
$user_id = username_exists( $username );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
183 |
|
184 |
+
if ( 'admin' === $username && $this->settings['auto_ban_admin'] && empty( $user_id ) ) {
|
185 |
+
$itsec_logger->log_event( 'brute_force', 5, $details, ITSEC_Lib::get_ip(), $username );
|
186 |
+
$itsec_lockout->do_lockout( 'brute_force_admin_user', $username );
|
187 |
|
188 |
+
return;
|
189 |
}
|
190 |
|
191 |
+
if ( empty( $user_id ) ) {
|
192 |
+
$itsec_lockout->check_lockout( false, $username );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
193 |
} else {
|
194 |
+
$itsec_lockout->check_lockout( $user_id );
|
195 |
+
};
|
196 |
|
197 |
+
$itsec_logger->log_event( 'brute_force', 5, $details, ITSEC_Lib::get_ip(), $username, intval( $user_id ) );
|
198 |
+
$itsec_lockout->do_lockout( 'brute_force', $username );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
199 |
}
|
200 |
|
201 |
/**
|
core/modules/file-change/class-ithemes-sync-verb-itsec-perform-file-scan.php
DELETED
@@ -1,53 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* Sync verb for file change detection
|
4 |
-
*
|
5 |
-
* Allows for file scanning to be performed remotely via iThemes Sync.
|
6 |
-
*
|
7 |
-
* @since 4.0.0
|
8 |
-
*
|
9 |
-
* @package iThemes_Security
|
10 |
-
*/
|
11 |
-
class Ithemes_Sync_Verb_ITSEC_Perform_File_Scan extends Ithemes_Sync_Verb {
|
12 |
-
/**
|
13 |
-
* The name of the verb that can be called via Sync.
|
14 |
-
*
|
15 |
-
* @since 4.0.0
|
16 |
-
* @access public
|
17 |
-
* @var string
|
18 |
-
*/
|
19 |
-
public static $name = 'itsec-perform-file-scan';
|
20 |
-
|
21 |
-
/**
|
22 |
-
* A description of the verb for use in Sync.
|
23 |
-
*
|
24 |
-
* @since 4.0.0
|
25 |
-
* @access public
|
26 |
-
* @var string
|
27 |
-
*/
|
28 |
-
public static $description = 'Perform a one-time file scan';
|
29 |
-
|
30 |
-
/**
|
31 |
-
* Array of default arguments to process
|
32 |
-
*
|
33 |
-
* @since 4.0.0
|
34 |
-
* @access public
|
35 |
-
* @var array
|
36 |
-
*/
|
37 |
-
public $default_arguments = array();
|
38 |
-
|
39 |
-
/**
|
40 |
-
* Functionaly to execute when calling the verb
|
41 |
-
*
|
42 |
-
* Functionality to execute when calling this verb VIA Sync.
|
43 |
-
*
|
44 |
-
* @since 4.0.0
|
45 |
-
*
|
46 |
-
* @return array response indicating result of the file scan
|
47 |
-
*/
|
48 |
-
public function run( $arguments ) {
|
49 |
-
require_once( dirname( __FILE__ ) . '/scanner.php' );
|
50 |
-
|
51 |
-
return ITSEC_File_Change_Scanner::run_scan( false, true );
|
52 |
-
}
|
53 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
core/modules/file-change/class-itsec-file-change.php
CHANGED
@@ -38,7 +38,7 @@ class ITSEC_File_Change {
|
|
38 |
|
39 |
add_filter( 'itsec_logger_displays', array( $this, 'itsec_logger_displays' ) ); //adds logs metaboxes
|
40 |
add_filter( 'itsec_logger_modules', array( $this, 'itsec_logger_modules' ) );
|
41 |
-
|
42 |
|
43 |
|
44 |
if (
|
@@ -58,10 +58,10 @@ class ITSEC_File_Change {
|
|
58 |
}
|
59 |
|
60 |
}
|
61 |
-
|
62 |
public function run_scan() {
|
63 |
require_once( dirname( __FILE__ ) . '/scanner.php' );
|
64 |
-
|
65 |
return ITSEC_File_Change_Scanner::run_scan();
|
66 |
}
|
67 |
|
@@ -164,27 +164,13 @@ class ITSEC_File_Change {
|
|
164 |
}
|
165 |
|
166 |
/**
|
167 |
-
* Register
|
168 |
-
*
|
169 |
-
* Reigsters iThemes Sync verbs for the file change detection module.
|
170 |
-
*
|
171 |
-
* @since 4.0.0
|
172 |
*
|
173 |
-
* @
|
174 |
*
|
175 |
-
* @
|
176 |
*/
|
177 |
-
public function
|
178 |
-
|
179 |
-
$sync_modules['file-change'] = array(
|
180 |
-
'verbs' => array(
|
181 |
-
'itsec-perform-file-scan' => 'Ithemes_Sync_Verb_ITSEC_Perform_File_Scan',
|
182 |
-
),
|
183 |
-
'path' => dirname( __FILE__ ),
|
184 |
-
);
|
185 |
-
|
186 |
-
return $sync_modules;
|
187 |
-
|
188 |
}
|
189 |
-
|
190 |
}
|
38 |
|
39 |
add_filter( 'itsec_logger_displays', array( $this, 'itsec_logger_displays' ) ); //adds logs metaboxes
|
40 |
add_filter( 'itsec_logger_modules', array( $this, 'itsec_logger_modules' ) );
|
41 |
+
add_action( 'ithemes_sync_register_verbs', array( $this, 'register_sync_verbs' ) );
|
42 |
|
43 |
|
44 |
if (
|
58 |
}
|
59 |
|
60 |
}
|
61 |
+
|
62 |
public function run_scan() {
|
63 |
require_once( dirname( __FILE__ ) . '/scanner.php' );
|
64 |
+
|
65 |
return ITSEC_File_Change_Scanner::run_scan();
|
66 |
}
|
67 |
|
164 |
}
|
165 |
|
166 |
/**
|
167 |
+
* Register verbs for Sync.
|
|
|
|
|
|
|
|
|
168 |
*
|
169 |
+
* @since 3.6.0
|
170 |
*
|
171 |
+
* @param Ithemes_Sync_API Sync API object.
|
172 |
*/
|
173 |
+
public function register_sync_verbs( $api ) {
|
174 |
+
$api->register( 'itsec-perform-file-scan', 'Ithemes_Sync_Verb_ITSEC_Perform_File_Scan', dirname( __FILE__ ) . '/sync-verbs/itsec-perform-file-scan.php' );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
175 |
}
|
|
|
176 |
}
|
core/modules/file-change/sync-verbs/index.php
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
<?php // Silence is golden.
|
core/modules/file-change/sync-verbs/itsec-perform-file-scan.php
ADDED
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class Ithemes_Sync_Verb_ITSEC_Perform_File_Scan extends Ithemes_Sync_Verb {
|
4 |
+
public static $name = 'itsec-perform-file-scan';
|
5 |
+
public static $description = 'Perform a one-time file scan';
|
6 |
+
|
7 |
+
public function run( $arguments ) {
|
8 |
+
require_once( dirname( dirname( __FILE__ ) ) . '/scanner.php' );
|
9 |
+
|
10 |
+
return ITSEC_File_Change_Scanner::run_scan( false, true );
|
11 |
+
}
|
12 |
+
}
|
core/modules/ipcheck/class-itsec-ipcheck.php
CHANGED
@@ -11,178 +11,168 @@
|
|
11 |
*
|
12 |
*/
|
13 |
class ITSEC_IPCheck {
|
14 |
-
|
15 |
private $endpoint = 'http://ipcheck-api.ithemes.com/?action=';
|
16 |
private $settings;
|
17 |
|
18 |
-
function run() {
|
19 |
-
|
20 |
-
|
21 |
|
22 |
-
|
23 |
-
|
24 |
|
25 |
-
|
26 |
-
|
|
|
|
|
|
|
27 |
|
28 |
-
|
29 |
-
|
|
|
30 |
|
|
|
|
|
31 |
}
|
32 |
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
* @since 4.5
|
39 |
-
*
|
40 |
-
* @param object $user user or wordpress error
|
41 |
-
* @param string $username username attempted
|
42 |
-
* @param string $password password attempted
|
43 |
-
*
|
44 |
-
* @return user object or WordPress error
|
45 |
-
*/
|
46 |
-
public function authenticate( $user, $username = '', $password = '' ) {
|
47 |
|
48 |
-
|
|
|
|
|
49 |
|
50 |
-
|
51 |
-
if ( isset( $_POST['wp-submit'] ) && ( empty( $username ) || empty( $password ) ) ) {
|
52 |
|
53 |
-
if ( $this->report_ip() === 1 ) {
|
54 |
|
55 |
-
|
|
|
56 |
|
57 |
-
|
|
|
58 |
|
59 |
-
|
|
|
|
|
|
|
|
|
60 |
|
|
|
|
|
61 |
}
|
62 |
|
63 |
-
return $
|
64 |
-
|
65 |
}
|
66 |
|
67 |
/**
|
68 |
-
*
|
69 |
-
*
|
70 |
-
* @since 4.5
|
71 |
*
|
72 |
-
* @
|
73 |
-
* @param bool $status if the IP is blocked or not
|
74 |
-
* @param int $time length, in seconds, to cache
|
75 |
*
|
76 |
-
* @return
|
77 |
*/
|
78 |
-
private function
|
79 |
-
|
80 |
-
//@todo one size fits all is too long. Need to adjust time
|
81 |
-
set_site_transient( 'itsec_ip_cache_' . esc_sql( $ip ), $status, $time );
|
82 |
-
|
83 |
}
|
84 |
|
85 |
/**
|
86 |
-
*
|
87 |
-
*
|
88 |
-
* @since 4.5
|
89 |
*
|
90 |
-
* @
|
91 |
*
|
92 |
-
* @return bool true if
|
93 |
*/
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
//get current IP if needed
|
99 |
-
if ( $ip === null ) {
|
100 |
-
|
101 |
-
$ip = ITSEC_Lib::get_ip();
|
102 |
|
103 |
-
|
|
|
104 |
|
105 |
-
$ip = trim( sanitize_text_field( $ip ) );
|
106 |
|
107 |
-
|
108 |
|
109 |
-
if (
|
110 |
return false;
|
111 |
}
|
112 |
|
113 |
-
//See if we've checked this IP in the last hour
|
114 |
-
$cache_check = get_site_transient( 'itsec_ip_cache_' . esc_sql( $ip ) );
|
115 |
|
116 |
-
if (
|
117 |
-
|
118 |
}
|
119 |
|
120 |
-
|
121 |
|
122 |
-
if ( ITSEC_Lib_IP_Tools::validate( $ip )
|
123 |
-
|
124 |
-
|
125 |
-
return false; //invalid key or secret
|
126 |
-
}
|
127 |
-
|
128 |
-
$args = json_encode(
|
129 |
-
array(
|
130 |
-
'apikey' => $this->settings['api_key'], //the api key
|
131 |
-
'behavior' => 'brute-force-login', //type of behanvior we're reporting
|
132 |
-
'ip' => $ip, //the ip to report
|
133 |
-
'site' => home_url( '', 'http' ), //the current site URL
|
134 |
-
'timestamp' => $itsec_globals['current_time_gmt'], //current time (GMT)
|
135 |
-
)
|
136 |
-
);
|
137 |
|
138 |
-
//Build the request parameters
|
139 |
-
$request = array(
|
140 |
-
'body' => array(
|
141 |
-
'request' => $args,
|
142 |
-
'signature' => $this->hmac_sha1( $this->settings['api_secret'], $action . $args ),
|
143 |
-
),
|
144 |
-
);
|
145 |
|
146 |
-
|
147 |
|
148 |
-
|
149 |
-
if (
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
150 |
|
151 |
-
$response = json_decode( $response['body'], true );
|
152 |
|
153 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
154 |
|
155 |
-
|
|
|
|
|
|
|
|
|
|
|
156 |
|
157 |
-
if ( isset( $response['block'] ) && $response['block'] == true ) {
|
158 |
|
159 |
-
|
160 |
-
$expiration_gmt = date( 'Y-m-d H:i:s', $itsec_globals['current_time_gmt'] + $cache );
|
161 |
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
|
166 |
-
$this->cache_ip( $ip, array( 'status' => true ), $cache );
|
167 |
|
168 |
-
|
169 |
|
170 |
-
|
|
|
|
|
171 |
|
172 |
-
$this->cache_ip( $ip, array( 'status' => false ), $cache );
|
173 |
|
174 |
-
|
175 |
|
176 |
-
|
177 |
|
178 |
-
|
|
|
|
|
|
|
|
|
|
|
179 |
|
180 |
-
|
181 |
|
|
|
182 |
}
|
183 |
|
184 |
return false;
|
185 |
-
|
186 |
}
|
187 |
|
188 |
/**
|
@@ -198,21 +188,16 @@ class ITSEC_IPCheck {
|
|
198 |
* @return string base64 encoded hmac
|
199 |
*/
|
200 |
private function hmac_sha1( $key, $data ) {
|
201 |
-
|
202 |
if ( strlen( $key ) > 64 ) {
|
203 |
$key = pack( 'H*', sha1( $key ) );
|
204 |
}
|
205 |
|
206 |
$key = str_pad( $key, 64, chr( 0x00 ) );
|
207 |
-
|
208 |
$ipad = str_repeat( chr( 0x36 ), 64 );
|
209 |
-
|
210 |
$opad = str_repeat( chr( 0x5c ), 64 );
|
211 |
-
|
212 |
$hmac = pack( 'H*', sha1( ( $key ^ $opad ) . pack( 'H*', sha1( ( $key ^ $ipad ) . $data ) ) ) );
|
213 |
|
214 |
return base64_encode( $hmac );
|
215 |
-
|
216 |
}
|
217 |
|
218 |
/**
|
@@ -225,126 +210,12 @@ class ITSEC_IPCheck {
|
|
225 |
* @return array array of logger modules
|
226 |
*/
|
227 |
public function itsec_logger_modules( $logger_modules ) {
|
228 |
-
|
229 |
$logger_modules['ipcheck'] = array(
|
230 |
'type' => 'ipcheck',
|
231 |
-
'function' => __( 'IP Flagged
|
232 |
);
|
233 |
|
234 |
return $logger_modules;
|
235 |
-
|
236 |
-
}
|
237 |
-
|
238 |
-
/**
|
239 |
-
* Send offending IP to IPCheck API
|
240 |
-
*
|
241 |
-
* @since 4.5
|
242 |
-
*
|
243 |
-
* @param string|null $ip ip to report
|
244 |
-
* @param int $type type of behavior to report
|
245 |
-
*
|
246 |
-
* @return int -1 on failure, 0 if report successful and IP not blocked, 1 if IP successful and IP blocked
|
247 |
-
*/
|
248 |
-
public function report_ip( $ip = null, $type = 1 ) {
|
249 |
-
|
250 |
-
global $itsec_globals, $itsec_logger;
|
251 |
-
|
252 |
-
$action = 'report-ip';
|
253 |
-
|
254 |
-
/**
|
255 |
-
* Switch types or return false if no valid type
|
256 |
-
*
|
257 |
-
* Valid types:
|
258 |
-
* 1 = invalid/failed login
|
259 |
-
*
|
260 |
-
*/
|
261 |
-
switch ( $type ) {
|
262 |
-
|
263 |
-
case 1:
|
264 |
-
$behavior = 'brute-force-login';
|
265 |
-
break;
|
266 |
-
default:
|
267 |
-
return -1;
|
268 |
-
|
269 |
-
}
|
270 |
-
|
271 |
-
//get current IP if needed
|
272 |
-
if ( $ip === null ) {
|
273 |
-
|
274 |
-
$ip = ITSEC_Lib::get_ip();
|
275 |
-
|
276 |
-
} else {
|
277 |
-
|
278 |
-
$ip = trim( sanitize_text_field( $ip ) );
|
279 |
-
|
280 |
-
}
|
281 |
-
|
282 |
-
if ( ITSEC_Lib::is_ip_whitelisted( $ip ) ) {
|
283 |
-
return 0;
|
284 |
-
}
|
285 |
-
|
286 |
-
if ( ITSEC_Lib_IP_Tools::validate( $ip ) ) { //verify IP address is valid
|
287 |
-
|
288 |
-
if ( ! isset( $this->settings['api_key'] ) || ! isset( $this->settings['api_secret'] ) ) {
|
289 |
-
return -1; //invalid key or secret
|
290 |
-
}
|
291 |
-
|
292 |
-
$args = json_encode(
|
293 |
-
array(
|
294 |
-
'apikey' => $this->settings['api_key'], //the api key
|
295 |
-
'behavior' => $behavior, //type of behanvior we're reporting
|
296 |
-
'ip' => $ip, //the ip to report
|
297 |
-
'site' => home_url( '', 'http' ), //the current site URL
|
298 |
-
'timestamp' => $itsec_globals['current_time_gmt'], //current time (GMT)
|
299 |
-
)
|
300 |
-
);
|
301 |
-
|
302 |
-
//Build the request parameters
|
303 |
-
$request = array(
|
304 |
-
'body' => array(
|
305 |
-
'request' => $args,
|
306 |
-
'signature' => $this->hmac_SHA1( $this->settings['api_secret'], $action . $args ),
|
307 |
-
),
|
308 |
-
);
|
309 |
-
|
310 |
-
$response = wp_remote_post( $this->endpoint . $action, $request );
|
311 |
-
|
312 |
-
//Make sure the request was valid and has a valid body
|
313 |
-
if ( ! is_wp_error( $response ) && isset( $response['body'] ) ) {
|
314 |
-
|
315 |
-
$response = json_decode( $response['body'], true );
|
316 |
-
|
317 |
-
if ( is_array( $response ) && isset( $response['success'] ) && $response['success'] == true ) {
|
318 |
-
|
319 |
-
if ( isset( $response['block'] ) && $response['block'] == true ) {
|
320 |
-
|
321 |
-
$cache = isset( $response['cache_ttl'] ) ? absint( $response['cache_ttl'] ) : 3600;
|
322 |
-
|
323 |
-
$expiration = date( 'Y-m-d H:i:s', $itsec_globals['current_time'] + $cache );
|
324 |
-
$expiration_gmt = date( 'Y-m-d H:i:s', $itsec_globals['current_time_gmt'] + $cache );
|
325 |
-
|
326 |
-
$itsec_logger->log_event( 'lockout', 10, array(
|
327 |
-
'expires' => $expiration, 'expires_gmt' => $expiration_gmt, 'type' => 'host'
|
328 |
-
), $ip );
|
329 |
-
|
330 |
-
$this->cache_ip( $ip, array( 'status' => true ), $cache );
|
331 |
-
|
332 |
-
return 1; //ip report success. Just return true for now
|
333 |
-
|
334 |
-
} else {
|
335 |
-
|
336 |
-
return 0;
|
337 |
-
|
338 |
-
}
|
339 |
-
|
340 |
-
}
|
341 |
-
|
342 |
-
}
|
343 |
-
|
344 |
-
}
|
345 |
-
|
346 |
-
return -1;
|
347 |
-
|
348 |
}
|
349 |
|
350 |
/**
|
@@ -355,17 +226,14 @@ class ITSEC_IPCheck {
|
|
355 |
* @return void
|
356 |
*/
|
357 |
public function wp_login() {
|
358 |
-
|
359 |
global $itsec_logger, $itsec_lockout;
|
360 |
|
361 |
-
|
362 |
|
|
|
363 |
$itsec_logger->log_event( 'ipcheck', 10, array(), ITSEC_Lib::get_ip() );
|
364 |
-
|
365 |
$itsec_lockout->execute_lock( false, true );
|
366 |
-
|
367 |
}
|
368 |
-
|
369 |
}
|
370 |
|
371 |
/**
|
@@ -375,18 +243,15 @@ class ITSEC_IPCheck {
|
|
375 |
*
|
376 |
* @return void
|
377 |
*/
|
378 |
-
public function
|
379 |
-
|
380 |
global $itsec_logger, $itsec_lockout;
|
381 |
|
382 |
-
|
383 |
|
|
|
384 |
$itsec_logger->log_event( 'ipcheck', 10, array(), ITSEC_Lib::get_ip() );
|
385 |
-
|
386 |
$itsec_lockout->execute_lock( false, true );
|
387 |
-
|
388 |
}
|
389 |
-
|
390 |
}
|
391 |
|
392 |
}
|
11 |
*
|
12 |
*/
|
13 |
class ITSEC_IPCheck {
|
|
|
14 |
private $endpoint = 'http://ipcheck-api.ithemes.com/?action=';
|
15 |
private $settings;
|
16 |
|
17 |
+
public function run() {
|
18 |
+
add_action( 'wp_login', array( $this, 'wp_login' ), 10, 2 );
|
19 |
+
add_action( 'itsec-handle-failed-login', array( $this, 'handle_failed_login' ), 10, 2 );
|
20 |
|
21 |
+
add_filter( 'itsec_logger_modules', array( $this, 'itsec_logger_modules' ) );
|
22 |
+
}
|
23 |
|
24 |
+
private function load_settings() {
|
25 |
+
if ( ! isset( $this->settings ) ) {
|
26 |
+
$this->settings = ITSEC_Modules::get_settings( 'network-brute-force' );
|
27 |
+
}
|
28 |
+
}
|
29 |
|
30 |
+
private function set_cache( $ip, $response ) {
|
31 |
+
$cache = $this->get_cache( $ip );
|
32 |
+
$time = ITSEC_Core::get_current_time_gmt();
|
33 |
|
34 |
+
if ( isset( $response['block'] ) ) {
|
35 |
+
$cache['block'] = (boolean) $response['block'];
|
36 |
}
|
37 |
|
38 |
+
if ( isset( $response['cache_ttl'] ) ) {
|
39 |
+
$cache['cache_ttl'] = intval( $response['cache_ttl'] ) + $time;
|
40 |
+
} else if ( 0 === $cache['cache_ttl'] ) {
|
41 |
+
$cache['cache_ttl'] = $time + HOUR_IN_SECONDS;
|
42 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
43 |
|
44 |
+
if ( isset( $response['report_ttl'] ) ) {
|
45 |
+
$cache['report_ttl'] = intval( $response['report_ttl'] ) + $time;
|
46 |
+
}
|
47 |
|
48 |
+
$transient_time = max( $cache['cache_ttl'], $cache['report_ttl'] ) - $time;
|
|
|
49 |
|
|
|
50 |
|
51 |
+
set_site_transient( "itsec_ipcheck_$ip", $cache, $transient_time );
|
52 |
+
}
|
53 |
|
54 |
+
private function get_cache( $ip ) {
|
55 |
+
$cache = get_site_transient( "itsec_ipcheck_$ip" );
|
56 |
|
57 |
+
$defaults = array(
|
58 |
+
'block' => false,
|
59 |
+
'cache_ttl' => 0,
|
60 |
+
'report_ttl' => 0,
|
61 |
+
);
|
62 |
|
63 |
+
if ( ! is_array( $cache ) ) {
|
64 |
+
return $defaults;
|
65 |
}
|
66 |
|
67 |
+
return array_merge( $defaults, $cache );
|
|
|
68 |
}
|
69 |
|
70 |
/**
|
71 |
+
* Check visitor IP to see if it is banned by IPCheck.
|
|
|
|
|
72 |
*
|
73 |
+
* @since 3.0.0
|
|
|
|
|
74 |
*
|
75 |
+
* @return bool true if banned, false otherwise.
|
76 |
*/
|
77 |
+
private function is_ip_banned( $ip = false ) {
|
78 |
+
return $this->get_server_response( 'check-ip', $ip );
|
|
|
|
|
|
|
79 |
}
|
80 |
|
81 |
/**
|
82 |
+
* Report visitor IP for blacklistable-offense to IPCheck.
|
|
|
|
|
83 |
*
|
84 |
+
* @since 3.0.0
|
85 |
*
|
86 |
+
* @return bool true if banned, false otherwise.
|
87 |
*/
|
88 |
+
private function report_ip( $ip = false ) {
|
89 |
+
return $this->get_server_response( 'report-ip', $ip );
|
90 |
+
}
|
|
|
|
|
|
|
|
|
|
|
91 |
|
92 |
+
private function get_server_response( $action, $ip = false ) {
|
93 |
+
global $itsec_logger;
|
94 |
|
|
|
95 |
|
96 |
+
$this->load_settings();
|
97 |
|
98 |
+
if ( empty( $this->settings['api_key'] ) || empty( $this->settings['api_secret'] ) ) {
|
99 |
return false;
|
100 |
}
|
101 |
|
|
|
|
|
102 |
|
103 |
+
if ( false === $ip ) {
|
104 |
+
$ip = ITSEC_Lib::get_ip();
|
105 |
}
|
106 |
|
107 |
+
require_once( ITSEC_Core::get_core_dir() . '/lib/class-itsec-lib-ip-tools.php' );
|
108 |
|
109 |
+
if ( ! ITSEC_Lib_IP_Tools::validate( $ip ) || ITSEC_Lib::is_ip_whitelisted( $ip ) ) {
|
110 |
+
return false;
|
111 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
112 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
113 |
|
114 |
+
$cache = $this->get_cache( $ip );
|
115 |
|
116 |
+
if ( 'check-ip' === $action ) {
|
117 |
+
if ( $cache['cache_ttl'] >= ITSEC_Core::get_current_time_gmt() ) {
|
118 |
+
return $cache['block'];
|
119 |
+
}
|
120 |
+
} else if ( 'report-ip' === $action ) {
|
121 |
+
if ( $cache['report_ttl'] >= ITSEC_Core::get_current_time_gmt() ) {
|
122 |
+
return $cache['block'];
|
123 |
+
}
|
124 |
+
}
|
125 |
|
|
|
126 |
|
127 |
+
$args = json_encode(
|
128 |
+
array(
|
129 |
+
'apikey' => $this->settings['api_key'],
|
130 |
+
'behavior' => 'brute-force-login',
|
131 |
+
'ip' => $ip,
|
132 |
+
'site' => home_url( '', 'http' ),
|
133 |
+
'timestamp' => ITSEC_Core::get_current_time_gmt(),
|
134 |
+
)
|
135 |
+
);
|
136 |
|
137 |
+
$request = array(
|
138 |
+
'body' => array(
|
139 |
+
'request' => $args,
|
140 |
+
'signature' => $this->hmac_sha1( $this->settings['api_secret'], $action . $args ),
|
141 |
+
),
|
142 |
+
);
|
143 |
|
|
|
144 |
|
145 |
+
$response = wp_remote_post( $this->endpoint . $action, $request );
|
|
|
146 |
|
147 |
+
if ( is_wp_error( $response ) || ! isset( $response['body'] ) ) {
|
148 |
+
return false;
|
149 |
+
}
|
150 |
|
|
|
151 |
|
152 |
+
$response = json_decode( $response['body'], true );
|
153 |
|
154 |
+
if ( ! is_array( $response ) || ! isset( $response['success'] ) || ! $response['success'] ) {
|
155 |
+
return false;
|
156 |
+
}
|
157 |
|
|
|
158 |
|
159 |
+
$this->set_cache( $ip, $response );
|
160 |
|
161 |
+
$cache_seconds = isset( $response['cache_ttl'] ) ? absint( $response['cache_ttl'] ) : 3600;
|
162 |
|
163 |
+
if ( isset( $response['block'] ) && $response['block'] ) {
|
164 |
+
$data = array(
|
165 |
+
'expires' => date( 'Y-m-d H:i:s', ITSEC_Core::get_current_time() + $cache_seconds ),
|
166 |
+
'expires_gmt' => date( 'Y-m-d H:i:s', ITSEC_Core::get_current_time_gmt() + $cache_seconds ),
|
167 |
+
'type' => 'host',
|
168 |
+
);
|
169 |
|
170 |
+
$itsec_logger->log_event( 'lockout', 10, $data, $ip );
|
171 |
|
172 |
+
return true;
|
173 |
}
|
174 |
|
175 |
return false;
|
|
|
176 |
}
|
177 |
|
178 |
/**
|
188 |
* @return string base64 encoded hmac
|
189 |
*/
|
190 |
private function hmac_sha1( $key, $data ) {
|
|
|
191 |
if ( strlen( $key ) > 64 ) {
|
192 |
$key = pack( 'H*', sha1( $key ) );
|
193 |
}
|
194 |
|
195 |
$key = str_pad( $key, 64, chr( 0x00 ) );
|
|
|
196 |
$ipad = str_repeat( chr( 0x36 ), 64 );
|
|
|
197 |
$opad = str_repeat( chr( 0x5c ), 64 );
|
|
|
198 |
$hmac = pack( 'H*', sha1( ( $key ^ $opad ) . pack( 'H*', sha1( ( $key ^ $ipad ) . $data ) ) ) );
|
199 |
|
200 |
return base64_encode( $hmac );
|
|
|
201 |
}
|
202 |
|
203 |
/**
|
210 |
* @return array array of logger modules
|
211 |
*/
|
212 |
public function itsec_logger_modules( $logger_modules ) {
|
|
|
213 |
$logger_modules['ipcheck'] = array(
|
214 |
'type' => 'ipcheck',
|
215 |
+
'function' => __( 'IP Flagged by Network Brute Force Protection', 'better-wp-security' ),
|
216 |
);
|
217 |
|
218 |
return $logger_modules;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
219 |
}
|
220 |
|
221 |
/**
|
226 |
* @return void
|
227 |
*/
|
228 |
public function wp_login() {
|
|
|
229 |
global $itsec_logger, $itsec_lockout;
|
230 |
|
231 |
+
$this->load_settings();
|
232 |
|
233 |
+
if ( $this->settings['enable_ban'] && $this->is_ip_banned() ) {
|
234 |
$itsec_logger->log_event( 'ipcheck', 10, array(), ITSEC_Lib::get_ip() );
|
|
|
235 |
$itsec_lockout->execute_lock( false, true );
|
|
|
236 |
}
|
|
|
237 |
}
|
238 |
|
239 |
/**
|
243 |
*
|
244 |
* @return void
|
245 |
*/
|
246 |
+
public function handle_failed_login( $username, $details ) {
|
|
|
247 |
global $itsec_logger, $itsec_lockout;
|
248 |
|
249 |
+
$this->load_settings();
|
250 |
|
251 |
+
if ( $this->settings['enable_ban'] && $this->report_ip() ) {
|
252 |
$itsec_logger->log_event( 'ipcheck', 10, array(), ITSEC_Lib::get_ip() );
|
|
|
253 |
$itsec_lockout->execute_lock( false, true );
|
|
|
254 |
}
|
|
|
255 |
}
|
256 |
|
257 |
}
|
core/modules/ipcheck/setup.php
CHANGED
@@ -93,6 +93,10 @@ if ( ! class_exists( 'ITSEC_IPCheck_Setup' ) ) {
|
|
93 |
ITSEC_Modules::set_settings( 'network-brute-force', $settings );
|
94 |
}
|
95 |
}
|
|
|
|
|
|
|
|
|
96 |
}
|
97 |
|
98 |
}
|
93 |
ITSEC_Modules::set_settings( 'network-brute-force', $settings );
|
94 |
}
|
95 |
}
|
96 |
+
|
97 |
+
if ( $itsec_old_version < 4056 ) {
|
98 |
+
delete_site_option( 'itsec_ipcheck' );
|
99 |
+
}
|
100 |
}
|
101 |
|
102 |
}
|
core/modules/malware/class-itsec-malware.php
CHANGED
@@ -3,7 +3,8 @@
|
|
3 |
class ITSEC_Malware {
|
4 |
|
5 |
function run() {
|
6 |
-
|
|
|
7 |
|
8 |
add_filter( 'itsec_logger_displays', array( $this, 'itsec_logger_displays' ) );
|
9 |
add_filter( 'itsec_logger_modules', array( $this, 'itsec_logger_modules' ) );
|
@@ -11,25 +12,30 @@ class ITSEC_Malware {
|
|
11 |
}
|
12 |
|
13 |
/**
|
14 |
-
* Register
|
15 |
*
|
16 |
-
* @
|
17 |
*
|
18 |
-
* @
|
19 |
*/
|
20 |
-
public function
|
21 |
-
|
22 |
-
$
|
23 |
-
|
24 |
-
'itsec-do-malware-scan' => 'Ithemes_Sync_Verb_ITSEC_Malware_Do_Scan',
|
25 |
-
'itsec-get-malware-scan-log' => 'Ithemes_Sync_Verb_ITSEC_Get_Malware_Scan_Log',
|
26 |
-
),
|
27 |
-
'everything' => 'itsec-get-malware-scan-log',
|
28 |
-
'path' => dirname( __FILE__ ),
|
29 |
-
);
|
30 |
|
31 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
32 |
|
|
|
33 |
}
|
34 |
|
35 |
/**
|
@@ -91,14 +97,14 @@ class ITSEC_Malware {
|
|
91 |
public function filter_logger_data_column_details( $details, $data ) {
|
92 |
if ( is_wp_error( $data ) || ( ! empty( $data ) && ! empty( $data['SCAN']['SITE'] ) ) ) {
|
93 |
// Results for Sucuri scans.
|
94 |
-
|
95 |
require_once( dirname( __FILE__ ) . '/class-itsec-malware-scan-results-template.php' );
|
96 |
-
|
97 |
$details = "<div class='itsec-malware-scan-results-wrapper'>\n";
|
98 |
$details .= ITSEC_Malware_Scan_Results_Template::get_html( $data, true );
|
99 |
$details .= "</div>\n";
|
100 |
}
|
101 |
-
|
102 |
return $details;
|
103 |
}
|
104 |
|
3 |
class ITSEC_Malware {
|
4 |
|
5 |
function run() {
|
6 |
+
add_action( 'ithemes_sync_register_verbs', array( $this, 'register_sync_verbs' ) );
|
7 |
+
add_filter( 'itsec-filter-itsec-get-everything-verbs', array( $this, 'register_sync_get_everything_verbs' ) );
|
8 |
|
9 |
add_filter( 'itsec_logger_displays', array( $this, 'itsec_logger_displays' ) );
|
10 |
add_filter( 'itsec_logger_modules', array( $this, 'itsec_logger_modules' ) );
|
12 |
}
|
13 |
|
14 |
/**
|
15 |
+
* Register verbs for Sync.
|
16 |
*
|
17 |
+
* @since 3.6.0
|
18 |
*
|
19 |
+
* @param Ithemes_Sync_API Sync API object.
|
20 |
*/
|
21 |
+
public function register_sync_verbs( $api ) {
|
22 |
+
$api->register( 'itsec-do-malware-scan', 'Ithemes_Sync_Verb_ITSEC_Malware_Do_Scan', dirname( __FILE__ ) . '/sync-verbs/itsec-do-malware-scan.php' );
|
23 |
+
$api->register( 'itsec-get-malware-scan-log', 'Ithemes_Sync_Verb_ITSEC_Get_Malware_Scan_Log', dirname( __FILE__ ) . '/sync-verbs/itsec-get-malware-scan-log.php' );
|
24 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
25 |
|
26 |
+
/**
|
27 |
+
* Filter to add verbs to the response for the itsec-get-everything verb.
|
28 |
+
*
|
29 |
+
* @since 3.6.0
|
30 |
+
*
|
31 |
+
* @param array Array of verbs.
|
32 |
+
*
|
33 |
+
* @return array Array of verbs.
|
34 |
+
*/
|
35 |
+
public function register_sync_get_everything_verbs( $verbs ) {
|
36 |
+
$verbs['malware'][] = 'itsec-get-malware-scan-log';
|
37 |
|
38 |
+
return $verbs;
|
39 |
}
|
40 |
|
41 |
/**
|
97 |
public function filter_logger_data_column_details( $details, $data ) {
|
98 |
if ( is_wp_error( $data ) || ( ! empty( $data ) && ! empty( $data['SCAN']['SITE'] ) ) ) {
|
99 |
// Results for Sucuri scans.
|
100 |
+
|
101 |
require_once( dirname( __FILE__ ) . '/class-itsec-malware-scan-results-template.php' );
|
102 |
+
|
103 |
$details = "<div class='itsec-malware-scan-results-wrapper'>\n";
|
104 |
$details .= ITSEC_Malware_Scan_Results_Template::get_html( $data, true );
|
105 |
$details .= "</div>\n";
|
106 |
}
|
107 |
+
|
108 |
return $details;
|
109 |
}
|
110 |
|
core/modules/malware/sync-verbs/index.php
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
<?php // Silence is golden.
|
core/modules/malware/{class-ithemes-sync-verb-itsec-do-malware-scan.php → sync-verbs/itsec-do-malware-scan.php}
RENAMED
@@ -3,15 +3,10 @@
|
|
3 |
class Ithemes_Sync_Verb_ITSEC_Malware_Do_Scan extends Ithemes_Sync_Verb {
|
4 |
public static $name = 'itsec-do-malware-scan';
|
5 |
public static $description = '';
|
6 |
-
|
7 |
-
public $default_arguments = array();
|
8 |
-
|
9 |
public function run( $arguments ) {
|
10 |
-
|
11 |
-
|
12 |
-
require_once( dirname( __FILE__ ) . '/class-itsec-malware-scanner.php' );
|
13 |
-
|
14 |
return ITSEC_Malware_Scanner::scan();
|
15 |
}
|
16 |
-
|
17 |
}
|
3 |
class Ithemes_Sync_Verb_ITSEC_Malware_Do_Scan extends Ithemes_Sync_Verb {
|
4 |
public static $name = 'itsec-do-malware-scan';
|
5 |
public static $description = '';
|
6 |
+
|
|
|
|
|
7 |
public function run( $arguments ) {
|
8 |
+
require_once( dirname( dirname( __FILE__ ) ) . '/class-itsec-malware-scanner.php' );
|
9 |
+
|
|
|
|
|
10 |
return ITSEC_Malware_Scanner::scan();
|
11 |
}
|
|
|
12 |
}
|
core/modules/malware/{class-ithemes-sync-verb-itsec-get-malware-scan-log.php → sync-verbs/itsec-get-malware-scan-log.php}
RENAMED
File without changes
|
core/modules/security-check/scanner.php
CHANGED
@@ -22,7 +22,10 @@ final class ITSEC_Security_Check_Scanner {
|
|
22 |
|
23 |
self::enforce_activation( 'strong-passwords', __( 'Strong Password Enforcement', 'better-wp-security' ) );
|
24 |
self::enforce_activation( 'two-factor', __( 'Two-Factor Authentication', 'better-wp-security' ) );
|
25 |
-
self::
|
|
|
|
|
|
|
26 |
|
27 |
self::enforce_activation( 'user-logging', __( 'User Logging', 'better-wp-security' ) );
|
28 |
self::enforce_activation( 'wordpress-tweaks', __( 'WordPress Tweaks', 'better-wp-security' ) );
|
@@ -89,54 +92,6 @@ final class ITSEC_Security_Check_Scanner {
|
|
89 |
self::$calls_to_action[] = ob_get_clean();
|
90 |
}
|
91 |
|
92 |
-
private static function enable_all_two_factor_providers() {
|
93 |
-
if ( ! in_array( 'two-factor', self::$available_modules ) ) {
|
94 |
-
return;
|
95 |
-
}
|
96 |
-
|
97 |
-
|
98 |
-
$two_factor_providers = ITSEC_Modules::get_setting( 'two-factor', 'enabled-providers' );
|
99 |
-
$added_provider = false;
|
100 |
-
|
101 |
-
ob_start();
|
102 |
-
|
103 |
-
if ( ! in_array( 'Two_Factor_Totp', $two_factor_providers ) ) {
|
104 |
-
$two_factor_providers[] = 'Two_Factor_Totp';
|
105 |
-
$added_provider = true;
|
106 |
-
|
107 |
-
self::open_container();
|
108 |
-
echo '<p>' . __( 'Enabled the Time-Based One-Time Password (TOTP) provider for Two-Factor Authentication.', 'better-wp-security' ) . '</p>';
|
109 |
-
echo '</div>';
|
110 |
-
}
|
111 |
-
|
112 |
-
if ( ! in_array( 'Two_Factor_Email', $two_factor_providers ) ) {
|
113 |
-
$two_factor_providers[] = 'Two_Factor_Email';
|
114 |
-
$added_provider = true;
|
115 |
-
|
116 |
-
self::open_container();
|
117 |
-
echo '<p>' . __( 'Enabled the Email provider for Two-Factor Authentication.', 'better-wp-security' ) . '</p>';
|
118 |
-
echo '</div>';
|
119 |
-
}
|
120 |
-
|
121 |
-
if ( ! in_array( 'Two_Factor_Backup_Codes', $two_factor_providers ) ) {
|
122 |
-
$two_factor_providers[] = 'Two_Factor_Backup_Codes';
|
123 |
-
$added_provider = true;
|
124 |
-
|
125 |
-
self::open_container();
|
126 |
-
echo '<p>' . __( 'Enabled the Backup Verification Codes provider for Two-Factor Authentication.', 'better-wp-security' ) . '</p>';
|
127 |
-
echo '</div>';
|
128 |
-
}
|
129 |
-
|
130 |
-
|
131 |
-
if ( $added_provider ) {
|
132 |
-
self::$actions_taken[] = ob_get_clean();
|
133 |
-
|
134 |
-
ITSEC_Modules::set_setting( 'two-factor', 'enabled-providers', $two_factor_providers );
|
135 |
-
|
136 |
-
ITSEC_Response::reload_module( 'two-factor' );
|
137 |
-
}
|
138 |
-
}
|
139 |
-
|
140 |
private static function enforce_setting( $module, $setting_name, $setting_value, $description ) {
|
141 |
if ( ! in_array( $module, self::$available_modules ) ) {
|
142 |
return;
|
22 |
|
23 |
self::enforce_activation( 'strong-passwords', __( 'Strong Password Enforcement', 'better-wp-security' ) );
|
24 |
self::enforce_activation( 'two-factor', __( 'Two-Factor Authentication', 'better-wp-security' ) );
|
25 |
+
self::enforce_setting( 'two-factor', 'available_methods', 'all', esc_html__( 'Changed the Authentication Methods Available to Users setting in Two-Factor Authentication to "All Methods".', 'better-wp-security' ) );
|
26 |
+
self::enforce_setting( 'two-factor', 'protect_user_type', 'privileged_users', esc_html__( 'Changed the User Type Protection setting in Two-Factor Authentication to "Privileged Users".', 'better-wp-security' ) );
|
27 |
+
self::enforce_setting( 'two-factor', 'protect_vulnerable_users', true, esc_html__( 'Enabled the Vulnerable User Protection setting in Two-Factor Authentication.', 'better-wp-security' ) );
|
28 |
+
self::enforce_setting( 'two-factor', 'protect_vulnerable_site', true, esc_html__( 'Enabled the Vulnerable Site Protection setting in Two-Factor Authentication.', 'better-wp-security' ) );
|
29 |
|
30 |
self::enforce_activation( 'user-logging', __( 'User Logging', 'better-wp-security' ) );
|
31 |
self::enforce_activation( 'wordpress-tweaks', __( 'WordPress Tweaks', 'better-wp-security' ) );
|
92 |
self::$calls_to_action[] = ob_get_clean();
|
93 |
}
|
94 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
95 |
private static function enforce_setting( $module, $setting_name, $setting_value, $description ) {
|
96 |
if ( ! in_array( $module, self::$available_modules ) ) {
|
97 |
return;
|
core/sync-verbs/index.php
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
<?php // Silence is golden.
|
core/sync-verbs/itsec-get-everything.php
ADDED
@@ -0,0 +1,23 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class Ithemes_Sync_Verb_ITSEC_Get_Everything extends Ithemes_Sync_Verb {
|
4 |
+
public static $name = 'itsec-get-everything';
|
5 |
+
public static $description = 'Retrieve iThemes Security Status and other information.';
|
6 |
+
|
7 |
+
public function run( $arguments ) {
|
8 |
+
$api = ITSEC_Core::get_sync_api();
|
9 |
+
$modules = apply_filters( 'itsec-filter-itsec-get-everything-verbs', array() );
|
10 |
+
|
11 |
+
$results = array(
|
12 |
+
'api' => '1',
|
13 |
+
);
|
14 |
+
|
15 |
+
foreach ( $modules as $name => $verbs ) {
|
16 |
+
foreach ( $verbs as $verb ) {
|
17 |
+
$results[$name][$verb] = $api->run( $verb );
|
18 |
+
}
|
19 |
+
}
|
20 |
+
|
21 |
+
return $results;
|
22 |
+
}
|
23 |
+
}
|
core/{class-ithemes-sync-verb-itsec-get-lockouts.php → sync-verbs/itsec-get-lockouts.php}
RENAMED
File without changes
|
core/{class-ithemes-sync-verb-itsec-get-temp-whitelist.php → sync-verbs/itsec-get-temp-whitelist.php}
RENAMED
File without changes
|
core/{class-ithemes-sync-verb-itsec-release-lockout.php → sync-verbs/itsec-release-lockout.php}
RENAMED
File without changes
|
core/{class-ithemes-sync-verb-itsec-set-temp-whitelist.php → sync-verbs/itsec-set-temp-whitelist.php}
RENAMED
File without changes
|
history.txt
CHANGED
@@ -600,3 +600,12 @@
|
|
600 |
Bug Fix: Removed "comodo" from the list of user agents blocked by the HackRepair.com blacklist. This ensures that Comodo's AutoSSL feature of cPanel/WHM is able to function.
|
601 |
Updated Feature: Updated the "REST API" feature in the WordPress Tweaks section. The feature now has proper support for protecting privacy on your site without preventing the REST API from functioning.
|
602 |
Enhancement: Updated Security Check to enforce setting the "REST API" setting to "Restricted Access".
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
600 |
Bug Fix: Removed "comodo" from the list of user agents blocked by the HackRepair.com blacklist. This ensures that Comodo's AutoSSL feature of cPanel/WHM is able to function.
|
601 |
Updated Feature: Updated the "REST API" feature in the WordPress Tweaks section. The feature now has proper support for protecting privacy on your site without preventing the REST API from functioning.
|
602 |
Enhancement: Updated Security Check to enforce setting the "REST API" setting to "Restricted Access".
|
603 |
+
6.1.0 - 2017-02-07 - Chris Jean
|
604 |
+
Enhancement: Added logging for failed two-factor, OAuth, and REST API authentications.
|
605 |
+
Enhancement: Added logging details about the source of login failures and the type of authentication that failed.
|
606 |
+
Enhancement: Due to improvements in tracking authentication failures, brute force attempts using alternate authentication methods are more reliably found and blocked.
|
607 |
+
Enhancement: The server's IP is treated as whitelisted and will not be considered for lockouts or bans.
|
608 |
+
Enhancement: Reduced memory usage when creating a backup.
|
609 |
+
Enhancement: Changed log entry description of "IP Flagged as bad by iThemes IPCheck" to "IP Flagged by Network Brute Force Protection". This should help clarify the meaning of the log entry.
|
610 |
+
Enhancement: Improved efficiency of the Network Brute Force Protection feature.
|
611 |
+
Bug Fix: Fixed bug that prevented Network Brute Force Protection from working properly on some sites.
|
readme.txt
CHANGED
@@ -2,8 +2,8 @@
|
|
2 |
Contributors: ithemes, chrisjean, gerroald, mattdanner
|
3 |
Tags: security, security plugin, malware, hack, secure, block, SSL, admin, htaccess, lockdown, login, protect, protection, anti virus, attack, injection, login security, maintenance, permissions, prevention, authentication, administration, password, brute force, ban, permissions, bots, user agents, xml rpc, security log
|
4 |
Requires at least: 4.5
|
5 |
-
Tested up to: 4.7
|
6 |
-
Stable tag: 6.
|
7 |
License: GPLv2 or later
|
8 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
9 |
|
@@ -188,6 +188,16 @@ Free support may be available with the help of the community in the <a href="htt
|
|
188 |
|
189 |
== Changelog ==
|
190 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
191 |
= 6.0.0 =
|
192 |
* Bug Fix: Removed "comodo" from the list of user agents blocked by the HackRepair.com blacklist. This ensures that Comodo's AutoSSL feature of cPanel/WHM is able to function.
|
193 |
* Updated Feature: Updated the "REST API" feature in the WordPress Tweaks section. The feature now has proper support for protecting privacy on your site without preventing the REST API from functioning.
|
@@ -1635,5 +1645,5 @@ This release is a complete rewrite from the ground up. Special thanks to Cory Mi
|
|
1635 |
|
1636 |
== Upgrade Notice ==
|
1637 |
|
1638 |
-
= 6.
|
1639 |
-
Version 6.
|
2 |
Contributors: ithemes, chrisjean, gerroald, mattdanner
|
3 |
Tags: security, security plugin, malware, hack, secure, block, SSL, admin, htaccess, lockdown, login, protect, protection, anti virus, attack, injection, login security, maintenance, permissions, prevention, authentication, administration, password, brute force, ban, permissions, bots, user agents, xml rpc, security log
|
4 |
Requires at least: 4.5
|
5 |
+
Tested up to: 4.7.2
|
6 |
+
Stable tag: 6.1.0
|
7 |
License: GPLv2 or later
|
8 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
9 |
|
188 |
|
189 |
== Changelog ==
|
190 |
|
191 |
+
= 6.1.0 =
|
192 |
+
* Enhancement: Added logging for failed two-factor, OAuth, and REST API authentications.
|
193 |
+
* Enhancement: Added logging details about the source of login failures and the type of authentication that failed.
|
194 |
+
* Enhancement: Due to improvements in tracking authentication failures, brute force attempts using alternate authentication methods are more reliably found and blocked.
|
195 |
+
* Enhancement: The server's IP is treated as whitelisted and will not be considered for lockouts or bans.
|
196 |
+
* Enhancement: Reduced memory usage when creating a backup.
|
197 |
+
* Enhancement: Changed log entry description of "IP Flagged as bad by iThemes IPCheck" to "IP Flagged by Network Brute Force Protection". This should help clarify the meaning of the log entry.
|
198 |
+
* Enhancement: Improved efficiency of the Network Brute Force Protection feature.
|
199 |
+
* Bug Fix: Fixed bug that prevented Network Brute Force Protection from working properly on some sites.
|
200 |
+
|
201 |
= 6.0.0 =
|
202 |
* Bug Fix: Removed "comodo" from the list of user agents blocked by the HackRepair.com blacklist. This ensures that Comodo's AutoSSL feature of cPanel/WHM is able to function.
|
203 |
* Updated Feature: Updated the "REST API" feature in the WordPress Tweaks section. The feature now has proper support for protecting privacy on your site without preventing the REST API from functioning.
|
1645 |
|
1646 |
== Upgrade Notice ==
|
1647 |
|
1648 |
+
= 6.1.0 =
|
1649 |
+
Version 6.1.0 adds various improvements to logging and brute force detection. It is recommended for all users.
|