Version Description
- New Feature: Added a new setting in WordPress Tweaks: "Login with Email Address or Username".
- Enhancement: Host email images from the plugin instead of relying on iThemes servers to help email clients marking messages as spam or blocking images.
- Bug Fix: Error when searching for modules preventing modules from appearing.
- Bug Fix: Use the wp_options table when acquiring locks in Multisite.
- Bug Fix: Prevent duplicate daily digest emails on sites with high load.
- Misc: Added Magic Links, a new Pro-only feature, to be activated by Security Check.
- Misc: Rearranged modules to be listed alphabetically.
Download this release
Release Info
Developer | TimothyBlynJacobs |
Plugin | iThemes Security (formerly Better WP Security) |
Version | 6.6.0 |
Comparing to | |
See all releases |
Code changes from version 6.5.1 to 6.6.0
- better-wp-security.php +1 -1
- core/admin-pages/js/script.js +1 -1
- core/admin-pages/page-settings.php +1 -1
- core/core.php +19 -11
- core/history.txt +8 -0
- core/img/mail/article_icon.png +0 -0
- core/img/mail/attachment_icon.png +0 -0
- core/img/mail/documentation_icon.png +0 -0
- core/img/mail/footer_logo.png +0 -0
- core/img/mail/icon_folder.png +0 -0
- core/img/mail/icon_lock.png +0 -0
- core/img/mail/icon_message.png +0 -0
- core/img/mail/index.php +1 -0
- core/img/mail/info_icon.png +0 -0
- core/img/mail/logo.png +0 -0
- core/img/mail/pro_logo.png +0 -0
- core/img/mail/pro_logo_no_text.png +0 -0
- core/img/mail/support_icon.png +0 -0
- core/img/mail/video_icon.png +0 -0
- core/img/mail/warning_icon_yellow.png +0 -0
- core/img/mail/wp_security_book.png +0 -0
- core/lib.php +120 -6
- core/lib/class-itsec-mail.php +20 -4
- core/lib/mail-templates/footer.html +6 -6
- core/lib/mail-templates/pro-callout.html +1 -1
- core/lockout.php +154 -45
- core/modules/brute-force/class-itsec-brute-force.php +3 -3
- core/modules/ipcheck/class-itsec-ipcheck.php +2 -2
- core/modules/pro/settings-page.php +40 -24
- core/modules/security-check/scanner.php +2 -0
- core/modules/wordpress-tweaks/class-itsec-wordpress-tweaks.php +54 -0
- core/modules/wordpress-tweaks/settings-page.php +18 -0
- core/modules/wordpress-tweaks/settings.php +1 -0
- core/modules/wordpress-tweaks/setup.php +29 -55
- core/modules/wordpress-tweaks/validator.php +1 -0
- core/notify.php +46 -8
- history.txt +8 -0
- readme.txt +12 -3
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.6.0
|
10 |
* Text Domain: better-wp-security
|
11 |
* Network: True
|
12 |
* License: GPLv2
|
core/admin-pages/js/script.js
CHANGED
@@ -571,7 +571,7 @@ var itsecSettingsPage = {
|
|
571 |
|
572 |
var $window = jQuery( window ), height = $window.height(), width = $window.width(), offset = $el.offset();
|
573 |
|
574 |
-
if ( ! $el ) {
|
575 |
return false;
|
576 |
}
|
577 |
|
571 |
|
572 |
var $window = jQuery( window ), height = $window.height(), width = $window.width(), offset = $el.offset();
|
573 |
|
574 |
+
if ( ! $el || ! offset ) {
|
575 |
return false;
|
576 |
}
|
577 |
|
core/admin-pages/page-settings.php
CHANGED
@@ -2,7 +2,7 @@
|
|
2 |
|
3 |
|
4 |
final class ITSEC_Settings_Page {
|
5 |
-
private $version = 1.
|
6 |
|
7 |
private static $instance;
|
8 |
|
2 |
|
3 |
|
4 |
final class ITSEC_Settings_Page {
|
5 |
+
private $version = 1.8;
|
6 |
|
7 |
private static $instance;
|
8 |
|
core/core.php
CHANGED
@@ -141,6 +141,12 @@ if ( ! class_exists( 'ITSEC_Core' ) ) {
|
|
141 |
add_action( 'wp_login_failed', array( 'ITSEC_Lib', 'handle_wp_login_failed' ) );
|
142 |
|
143 |
add_action( 'ithemes_sync_register_verbs', array( $this, 'register_sync_verbs' ) );
|
|
|
|
|
|
|
|
|
|
|
|
|
144 |
}
|
145 |
|
146 |
/**
|
@@ -217,32 +223,34 @@ if ( ! class_exists( 'ITSEC_Core' ) ) {
|
|
217 |
ITSEC_Modules::register_module( 'security-check', "$path/modules/security-check", 'always-active' );
|
218 |
ITSEC_Modules::register_module( 'global', "$path/modules/global", 'always-active' );
|
219 |
ITSEC_Modules::register_module( '404-detection', "$path/modules/404-detection" );
|
|
|
220 |
ITSEC_Modules::register_module( 'away-mode', "$path/modules/away-mode" );
|
221 |
ITSEC_Modules::register_module( 'ban-users', "$path/modules/ban-users", 'default-active' );
|
222 |
include( "$path/modules/ban-users/init.php" ); // Provides the itsec_ban_users_handle_new_blacklisted_ip function which is always needed.
|
223 |
-
ITSEC_Modules::register_module( '
|
224 |
-
ITSEC_Modules::register_module( '
|
225 |
ITSEC_Modules::register_module( 'backup', "$path/modules/backup", 'default-active' );
|
|
|
226 |
ITSEC_Modules::register_module( 'file-change', "$path/modules/file-change" );
|
227 |
ITSEC_Modules::register_module( 'file-permissions', "$path/modules/file-permissions", 'always-active' );
|
228 |
ITSEC_Modules::register_module( 'hide-backend', "$path/modules/hide-backend", 'always-active' );
|
229 |
-
ITSEC_Modules::register_module( '
|
230 |
-
ITSEC_Modules::register_module( 'malware', "$path/modules/malware", 'always-active' );
|
231 |
-
ITSEC_Modules::register_module( 'ssl', "$path/modules/ssl" );
|
232 |
-
ITSEC_Modules::register_module( 'strong-passwords', "$path/modules/strong-passwords", 'default-active' );
|
233 |
-
ITSEC_Modules::register_module( 'system-tweaks', "$path/modules/system-tweaks" );
|
234 |
-
ITSEC_Modules::register_module( 'wordpress-tweaks', "$path/modules/wordpress-tweaks", 'default-active' );
|
235 |
|
236 |
if ( is_multisite() ) {
|
237 |
ITSEC_Modules::register_module( 'multisite-tweaks', "$path/modules/multisite-tweaks" );
|
238 |
}
|
239 |
|
240 |
-
ITSEC_Modules::register_module( '
|
|
|
|
|
|
|
241 |
ITSEC_Modules::register_module( 'wordpress-salts', "$path/modules/salts", 'always-active' );
|
242 |
-
ITSEC_Modules::register_module( '
|
243 |
-
|
244 |
ITSEC_Modules::register_module( 'file-writing', "$path/modules/file-writing", 'always-active' );
|
245 |
|
|
|
|
|
246 |
if ( ! ITSEC_Core::is_pro() ) {
|
247 |
ITSEC_Modules::register_module( 'pro-module-upsells', "$path/modules/pro", 'always-active' );
|
248 |
}
|
141 |
add_action( 'wp_login_failed', array( 'ITSEC_Lib', 'handle_wp_login_failed' ) );
|
142 |
|
143 |
add_action( 'ithemes_sync_register_verbs', array( $this, 'register_sync_verbs' ) );
|
144 |
+
|
145 |
+
if ( ! wp_next_scheduled( 'itsec_clear_locks' ) ) {
|
146 |
+
wp_schedule_event( time(), 'daily', 'itsec_clear_locks' );
|
147 |
+
}
|
148 |
+
|
149 |
+
add_action( 'itsec_clear_locks', array( 'ITSEC_Lib', 'delete_expired_locks' ) );
|
150 |
}
|
151 |
|
152 |
/**
|
223 |
ITSEC_Modules::register_module( 'security-check', "$path/modules/security-check", 'always-active' );
|
224 |
ITSEC_Modules::register_module( 'global', "$path/modules/global", 'always-active' );
|
225 |
ITSEC_Modules::register_module( '404-detection', "$path/modules/404-detection" );
|
226 |
+
ITSEC_Modules::register_module( 'admin-user', "$path/modules/admin-user", 'always-active' );
|
227 |
ITSEC_Modules::register_module( 'away-mode', "$path/modules/away-mode" );
|
228 |
ITSEC_Modules::register_module( 'ban-users', "$path/modules/ban-users", 'default-active' );
|
229 |
include( "$path/modules/ban-users/init.php" ); // Provides the itsec_ban_users_handle_new_blacklisted_ip function which is always needed.
|
230 |
+
ITSEC_Modules::register_module( 'content-directory', "$path/modules/content-directory", 'always-active' );
|
231 |
+
ITSEC_Modules::register_module( 'database-prefix', "$path/modules/database-prefix", 'always-active' );
|
232 |
ITSEC_Modules::register_module( 'backup', "$path/modules/backup", 'default-active' );
|
233 |
+
ITSEC_Modules::register_module( 'core', "$path/modules/core", 'always-active' );
|
234 |
ITSEC_Modules::register_module( 'file-change', "$path/modules/file-change" );
|
235 |
ITSEC_Modules::register_module( 'file-permissions', "$path/modules/file-permissions", 'always-active' );
|
236 |
ITSEC_Modules::register_module( 'hide-backend', "$path/modules/hide-backend", 'always-active' );
|
237 |
+
ITSEC_Modules::register_module( 'brute-force', "$path/modules/brute-force", 'default-active' );
|
|
|
|
|
|
|
|
|
|
|
238 |
|
239 |
if ( is_multisite() ) {
|
240 |
ITSEC_Modules::register_module( 'multisite-tweaks', "$path/modules/multisite-tweaks" );
|
241 |
}
|
242 |
|
243 |
+
ITSEC_Modules::register_module( 'network-brute-force', "$path/modules/ipcheck", 'default-active' );
|
244 |
+
ITSEC_Modules::register_module( 'ssl', "$path/modules/ssl" );
|
245 |
+
ITSEC_Modules::register_module( 'strong-passwords', "$path/modules/strong-passwords", 'default-active' );
|
246 |
+
ITSEC_Modules::register_module( 'system-tweaks', "$path/modules/system-tweaks" );
|
247 |
ITSEC_Modules::register_module( 'wordpress-salts', "$path/modules/salts", 'always-active' );
|
248 |
+
ITSEC_Modules::register_module( 'wordpress-tweaks', "$path/modules/wordpress-tweaks", 'default-active' );
|
249 |
+
|
250 |
ITSEC_Modules::register_module( 'file-writing', "$path/modules/file-writing", 'always-active' );
|
251 |
|
252 |
+
ITSEC_Modules::register_module( 'malware', "$path/modules/malware", 'always-active' );
|
253 |
+
|
254 |
if ( ! ITSEC_Core::is_pro() ) {
|
255 |
ITSEC_Modules::register_module( 'pro-module-upsells', "$path/modules/pro", 'always-active' );
|
256 |
}
|
core/history.txt
CHANGED
@@ -567,3 +567,11 @@
|
|
567 |
3.7.1 - 2017-08-23 - Chris Jean & Timothy Jacobs
|
568 |
Bug Fix: Fixed logical error that prevented backups from executing.
|
569 |
Bug Fix: Fixed issue that could cause database locks to flood the database.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
567 |
3.7.1 - 2017-08-23 - Chris Jean & Timothy Jacobs
|
568 |
Bug Fix: Fixed logical error that prevented backups from executing.
|
569 |
Bug Fix: Fixed issue that could cause database locks to flood the database.
|
570 |
+
3.8.0 - 2017-08-31 - Chris Jean & Timothy Jacobs
|
571 |
+
New Feature: Added a new setting in WordPress Tweaks: "Login with Email Address or Username".
|
572 |
+
Enhancement: Host email images from the plugin instead of relying on iThemes servers to help email clients marking messages as spam or blocking images.
|
573 |
+
Bug Fix: Error when searching for modules preventing modules from appearing.
|
574 |
+
Bug Fix: Use the wp_options table when acquiring locks in Multisite.
|
575 |
+
Bug Fix: Prevent duplicate daily digest emails on sites with high load.
|
576 |
+
Misc: Added Magic Links, a new Pro-only feature, to be activated by Security Check.
|
577 |
+
Misc: Rearranged modules to be listed alphabetically.
|
core/img/mail/article_icon.png
ADDED
Binary file
|
core/img/mail/attachment_icon.png
ADDED
Binary file
|
core/img/mail/documentation_icon.png
ADDED
Binary file
|
core/img/mail/footer_logo.png
ADDED
Binary file
|
core/img/mail/icon_folder.png
ADDED
Binary file
|
core/img/mail/icon_lock.png
ADDED
Binary file
|
core/img/mail/icon_message.png
ADDED
Binary file
|
core/img/mail/index.php
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
<?php // Silence is golden
|
core/img/mail/info_icon.png
ADDED
Binary file
|
core/img/mail/logo.png
ADDED
Binary file
|
core/img/mail/pro_logo.png
ADDED
Binary file
|
core/img/mail/pro_logo_no_text.png
ADDED
Binary file
|
core/img/mail/support_icon.png
ADDED
Binary file
|
core/img/mail/video_icon.png
ADDED
Binary file
|
core/img/mail/warning_icon_yellow.png
ADDED
Binary file
|
core/img/mail/wp_security_book.png
ADDED
Binary file
|
core/lib.php
CHANGED
@@ -1033,21 +1033,26 @@ final class ITSEC_Lib {
|
|
1033 |
|
1034 |
/** @var \wpdb $wpdb */
|
1035 |
global $wpdb;
|
|
|
1036 |
|
1037 |
$lock = "itsec-lock-{$name}";
|
1038 |
$now = ITSEC_Core::get_current_time_gmt();
|
1039 |
$release_at = $now + $expires_in;
|
1040 |
|
1041 |
-
if (
|
1042 |
-
$result = $wpdb->query( $wpdb->prepare( "INSERT IGNORE INTO
|
1043 |
} else {
|
1044 |
-
$result = $wpdb->query( $wpdb->prepare( "INSERT IGNORE INTO `$wpdb->
|
1045 |
}
|
1046 |
|
1047 |
// The lock exists. See if it has expired.
|
1048 |
if ( ! $result ) {
|
1049 |
|
1050 |
-
|
|
|
|
|
|
|
|
|
1051 |
|
1052 |
if ( ! $locked_until ) {
|
1053 |
// Can't write or read the lock. Bail due to an unknown and hopefully temporary error.
|
@@ -1061,7 +1066,28 @@ final class ITSEC_Lib {
|
|
1061 |
}
|
1062 |
|
1063 |
// Ensure that the lock is set properly by triggering all the regular actions and filters.
|
1064 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1065 |
|
1066 |
return true;
|
1067 |
}
|
@@ -1074,7 +1100,95 @@ final class ITSEC_Lib {
|
|
1074 |
* @param string $name The lock name.
|
1075 |
*/
|
1076 |
public static function release_lock( $name ) {
|
1077 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1078 |
}
|
1079 |
|
1080 |
/**
|
1033 |
|
1034 |
/** @var \wpdb $wpdb */
|
1035 |
global $wpdb;
|
1036 |
+
$main_options = $wpdb->base_prefix . 'options';
|
1037 |
|
1038 |
$lock = "itsec-lock-{$name}";
|
1039 |
$now = ITSEC_Core::get_current_time_gmt();
|
1040 |
$release_at = $now + $expires_in;
|
1041 |
|
1042 |
+
if ( is_multisite() ) {
|
1043 |
+
$result = $wpdb->query( $wpdb->prepare( "INSERT IGNORE INTO `{$main_options}` (`option_name`, `option_value`, `autoload`) VALUES (%s, %s, 'no') /* LOCK */", $lock, $release_at ) );
|
1044 |
} else {
|
1045 |
+
$result = $wpdb->query( $wpdb->prepare( "INSERT IGNORE INTO `$wpdb->options` (`option_name`, `option_value`, `autoload`) VALUES (%s, %s, 'no') /* LOCK */", $lock, $release_at ) );
|
1046 |
}
|
1047 |
|
1048 |
// The lock exists. See if it has expired.
|
1049 |
if ( ! $result ) {
|
1050 |
|
1051 |
+
if ( is_multisite() && get_current_blog_id() !== 1 ) {
|
1052 |
+
$locked_until = $wpdb->get_var( $wpdb->prepare( "SELECT `option_value` FROM {$main_options} WHERE `option_name` = %s", $main_options ) );
|
1053 |
+
} else {
|
1054 |
+
$locked_until = get_option( $lock );
|
1055 |
+
}
|
1056 |
|
1057 |
if ( ! $locked_until ) {
|
1058 |
// Can't write or read the lock. Bail due to an unknown and hopefully temporary error.
|
1066 |
}
|
1067 |
|
1068 |
// Ensure that the lock is set properly by triggering all the regular actions and filters.
|
1069 |
+
if ( ! is_multisite() || get_current_blog_id() === 1 ) {
|
1070 |
+
update_option( $lock, $release_at );
|
1071 |
+
} else {
|
1072 |
+
$wpdb->update( $main_options, array( 'option_value' => $release_at ), array( 'option_name' => $lock ) );
|
1073 |
+
|
1074 |
+
if ( function_exists( 'wp_cache_switch_to_blog' ) ) {
|
1075 |
+
// Update persistent object caches
|
1076 |
+
$current = get_current_blog_id();
|
1077 |
+
wp_cache_switch_to_blog( 1 );
|
1078 |
+
|
1079 |
+
$alloptions = wp_cache_get( 'alloptions' );
|
1080 |
+
|
1081 |
+
if ( is_array( $alloptions ) && isset( $alloptions[ $lock ] ) ) {
|
1082 |
+
$alloptions[ $lock ] = $release_at;
|
1083 |
+
wp_cache_set( 'alloptions', $alloptions, 'options' );
|
1084 |
+
} else {
|
1085 |
+
wp_cache_set( $lock, $release_at, 'options' );
|
1086 |
+
}
|
1087 |
+
|
1088 |
+
wp_cache_switch_to_blog( $current );
|
1089 |
+
}
|
1090 |
+
}
|
1091 |
|
1092 |
return true;
|
1093 |
}
|
1100 |
* @param string $name The lock name.
|
1101 |
*/
|
1102 |
public static function release_lock( $name ) {
|
1103 |
+
|
1104 |
+
$lock = "itsec-lock-{$name}";
|
1105 |
+
|
1106 |
+
if ( is_multisite() && get_current_blog_id() !== 1 ) {
|
1107 |
+
|
1108 |
+
/** @var \wpdb $wpdb */
|
1109 |
+
global $wpdb;
|
1110 |
+
$main_options = $wpdb->base_prefix . 'options';
|
1111 |
+
|
1112 |
+
$wpdb->delete( $main_options, array( 'option_name' => $lock ) );
|
1113 |
+
|
1114 |
+
if ( function_exists( 'wp_cache_switch_to_blog' ) ) {
|
1115 |
+
// Update persistent object caches
|
1116 |
+
$current = get_current_blog_id();
|
1117 |
+
wp_cache_switch_to_blog( 1 );
|
1118 |
+
|
1119 |
+
$alloptions = wp_cache_get( 'alloptions' );
|
1120 |
+
|
1121 |
+
if ( is_array( $alloptions ) && isset( $alloptions[ $lock ] ) ) {
|
1122 |
+
unset( $alloptions[$lock] );
|
1123 |
+
wp_cache_set( 'alloptions', $alloptions, 'options' );
|
1124 |
+
} else {
|
1125 |
+
wp_cache_delete( $lock, 'options' );
|
1126 |
+
}
|
1127 |
+
|
1128 |
+
wp_cache_switch_to_blog( $current );
|
1129 |
+
}
|
1130 |
+
} else {
|
1131 |
+
delete_option( $lock );
|
1132 |
+
}
|
1133 |
+
}
|
1134 |
+
|
1135 |
+
/**
|
1136 |
+
* Clear any expired locks.
|
1137 |
+
*
|
1138 |
+
* The vast majority of locks should be cleared by the same process that acquires them, however, this will clear locks that remain
|
1139 |
+
* due to a time out or fatal error.
|
1140 |
+
*
|
1141 |
+
* @since 3.8.0
|
1142 |
+
*/
|
1143 |
+
public static function delete_expired_locks() {
|
1144 |
+
|
1145 |
+
/** @var \wpdb $wpdb */
|
1146 |
+
global $wpdb;
|
1147 |
+
$main_options = $wpdb->base_prefix . 'options';
|
1148 |
+
|
1149 |
+
$rows = $wpdb->get_results( $wpdb->prepare(
|
1150 |
+
"SELECT `option_name` FROM {$main_options} WHERE `option_name` LIKE %s AND `option_value` < %d",
|
1151 |
+
$wpdb->esc_like( 'itsec-lock-' ) . '%', ITSEC_Core::get_current_time_gmt()
|
1152 |
+
) );
|
1153 |
+
|
1154 |
+
if ( $rows ) {
|
1155 |
+
if ( is_multisite() && get_current_blog_id() !== 1 ) {
|
1156 |
+
if ( function_exists( 'wp_cache_switch_to_blog' ) ) {
|
1157 |
+
// Update persistent object caches
|
1158 |
+
$current = get_current_blog_id();
|
1159 |
+
wp_cache_switch_to_blog( 1 );
|
1160 |
+
|
1161 |
+
$alloptions = wp_cache_get( 'alloptions' );
|
1162 |
+
$set_all = false;
|
1163 |
+
|
1164 |
+
foreach ( $rows as $row ) {
|
1165 |
+
$lock = $row->option_name;
|
1166 |
+
|
1167 |
+
if ( is_array( $alloptions ) && isset( $alloptions[ $lock ] ) ) {
|
1168 |
+
unset( $alloptions[$lock] );
|
1169 |
+
$set_all = true;
|
1170 |
+
} else {
|
1171 |
+
wp_cache_delete( $lock, 'options' );
|
1172 |
+
}
|
1173 |
+
}
|
1174 |
+
|
1175 |
+
if ( $set_all ) {
|
1176 |
+
wp_cache_set( 'alloptions', $alloptions );
|
1177 |
+
}
|
1178 |
+
|
1179 |
+
wp_cache_switch_to_blog( $current );
|
1180 |
+
}
|
1181 |
+
|
1182 |
+
$wpdb->query( $wpdb->prepare(
|
1183 |
+
"DELETE FROM {$main_options} WHERE `option_name` LIKE %s AND `option_value` < %d",
|
1184 |
+
$wpdb->esc_like( 'itsec-lock-' ) . '%', ITSEC_Core::get_current_time_gmt()
|
1185 |
+
) );
|
1186 |
+
} else {
|
1187 |
+
foreach ( $rows as $row ) {
|
1188 |
+
delete_option( $row->option_name );
|
1189 |
+
}
|
1190 |
+
}
|
1191 |
+
}
|
1192 |
}
|
1193 |
|
1194 |
/**
|
core/lib/class-itsec-mail.php
CHANGED
@@ -19,7 +19,7 @@ final class ITSEC_Mail {
|
|
19 |
'charset' => esc_attr( get_bloginfo( 'charset' ) ),
|
20 |
'title_tag' => $title,
|
21 |
'banner_title' => $banner_title,
|
22 |
-
'logo' => ITSEC_Core::is_pro() ? '
|
23 |
'title' => $title,
|
24 |
);
|
25 |
|
@@ -38,6 +38,18 @@ final class ITSEC_Mail {
|
|
38 |
return $content;
|
39 |
}
|
40 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
41 |
public function add_footer() {
|
42 |
$footer = '';
|
43 |
|
@@ -100,7 +112,7 @@ final class ITSEC_Mail {
|
|
100 |
}
|
101 |
|
102 |
public function add_info_box( $content, $icon_type = 'info' ) {
|
103 |
-
$icon_url = "
|
104 |
|
105 |
$module = $this->get_template( 'info-box.html' );
|
106 |
$module = $this->replace_all( $module, compact( 'content', 'icon_url' ) );
|
@@ -120,7 +132,7 @@ final class ITSEC_Mail {
|
|
120 |
$heading = $this->get_template( 'section-heading.html' );
|
121 |
$heading = $this->replace_all( $heading, compact( 'content' ) );
|
122 |
} else {
|
123 |
-
$icon_url = "
|
124 |
|
125 |
$heading = $this->get_template( 'section-heading-with-icon.html' );
|
126 |
$heading = $this->replace_all( $heading, compact( 'content', 'icon_url' ) );
|
@@ -233,7 +245,11 @@ final class ITSEC_Mail {
|
|
233 |
}
|
234 |
|
235 |
private function get_template( $template ) {
|
236 |
-
return file_get_contents( $this->template_path . $template );
|
|
|
|
|
|
|
|
|
237 |
}
|
238 |
|
239 |
public static function filter_admin_page_url( $url ) {
|
19 |
'charset' => esc_attr( get_bloginfo( 'charset' ) ),
|
20 |
'title_tag' => $title,
|
21 |
'banner_title' => $banner_title,
|
22 |
+
'logo' => ITSEC_Core::is_pro() ? $this->get_image_url( 'pro_logo' ) : $this->get_image_url( 'logo' ),
|
23 |
'title' => $title,
|
24 |
);
|
25 |
|
38 |
return $content;
|
39 |
}
|
40 |
|
41 |
+
private function replace_images( $content ) {
|
42 |
+
return preg_replace_callback( '/{! \$([a-zA-Z_][\w]*) }}/', array( $this, 'replace_image_callback' ), $content );
|
43 |
+
}
|
44 |
+
|
45 |
+
private function replace_image_callback( $matches ) {
|
46 |
+
if ( empty( $matches ) || empty( $matches[1] ) ) {
|
47 |
+
return '';
|
48 |
+
}
|
49 |
+
|
50 |
+
return esc_url( $this->get_image_url( $matches[1] ) );
|
51 |
+
}
|
52 |
+
|
53 |
public function add_footer() {
|
54 |
$footer = '';
|
55 |
|
112 |
}
|
113 |
|
114 |
public function add_info_box( $content, $icon_type = 'info' ) {
|
115 |
+
$icon_url = $this->get_image_url( "{$icon_type}_icon" );
|
116 |
|
117 |
$module = $this->get_template( 'info-box.html' );
|
118 |
$module = $this->replace_all( $module, compact( 'content', 'icon_url' ) );
|
132 |
$heading = $this->get_template( 'section-heading.html' );
|
133 |
$heading = $this->replace_all( $heading, compact( 'content' ) );
|
134 |
} else {
|
135 |
+
$icon_url = $this->get_image_url( "icon_{$icon_type}" );
|
136 |
|
137 |
$heading = $this->get_template( 'section-heading-with-icon.html' );
|
138 |
$heading = $this->replace_all( $heading, compact( 'content', 'icon_url' ) );
|
245 |
}
|
246 |
|
247 |
private function get_template( $template ) {
|
248 |
+
return $this->replace_images( file_get_contents( $this->template_path . $template ) );
|
249 |
+
}
|
250 |
+
|
251 |
+
private function get_image_url( $name ) {
|
252 |
+
return plugin_dir_url( ITSEC_Core::get_core_dir() . 'img/mail/index.php' ) . "{$name}.png";
|
253 |
}
|
254 |
|
255 |
public static function filter_admin_page_url( $url ) {
|
core/lib/mail-templates/footer.html
CHANGED
@@ -32,7 +32,7 @@
|
|
32 |
<table class="container" align="left" border="0" cellpadding="0" cellspacing="0" width="260" style="border-collapse: collapse;border-spacing: 0;mso-table-lspace: 0pt;mso-table-rspace: 0pt;-ms-text-size-adjust: 100%;-webkit-text-size-adjust: 100%;">
|
33 |
<tr>
|
34 |
<td class="container-cell" valign="top" style="border-collapse: collapse;border-spacing: 0;mso-table-lspace: 0pt;mso-table-rspace: 0pt;-ms-text-size-adjust: 100%;-webkit-text-size-adjust: 100%;color: #404040;font-family: Helvetica;font-size: 16px;line-height: 150%;text-align: center;padding-bottom: 20px;">
|
35 |
-
<img class="preserve-ratio" src="
|
36 |
<br>
|
37 |
<h4 style="color: #202020;font-family: Helvetica;font-size: 20px;font-weight: bold;line-height: 150%;margin: 0;padding: 0;text-align: center;">
|
38 |
<a href="https://ithemes.com/category/wordpress-security/" target="_blank" style="-ms-text-size-adjust: 100%;-webkit-text-size-adjust: 100%;color: #0084CB;font-family: Helvetica;font-size: 16px;line-height: 150%;text-align: center;text-decoration: none;">{{ $articles }}</a>
|
@@ -45,7 +45,7 @@
|
|
45 |
<table class="container" align="right" border="0" cellpadding="0" cellspacing="0" width="260" style="border-collapse: collapse;border-spacing: 0;mso-table-lspace: 0pt;mso-table-rspace: 0pt;-ms-text-size-adjust: 100%;-webkit-text-size-adjust: 100%;">
|
46 |
<tr>
|
47 |
<td class="container-cell container-cell-bottom" valign="top" style="border-collapse: collapse;border-spacing: 0;mso-table-lspace: 0pt;mso-table-rspace: 0pt;-ms-text-size-adjust: 100%;-webkit-text-size-adjust: 100%;color: #404040;font-family: Helvetica;font-size: 16px;line-height: 150%;text-align: center;padding-bottom: 20px;">
|
48 |
-
<img class="preserve-ratio" src="
|
49 |
<br>
|
50 |
<h4 style="color: #202020;font-family: Helvetica;font-size: 20px;font-weight: bold;line-height: 150%;margin: 0;padding: 0;text-align: center;">
|
51 |
<a href="https://ithemes.com/tutorial/category/ithemes-security/" target="_blank" style="-ms-text-size-adjust: 100%;-webkit-text-size-adjust: 100%;color: #0084CB;font-family: Helvetica;font-size: 16px;line-height: 150%;text-align: center;text-decoration: none;">{{ $tutorials }}</a>
|
@@ -120,7 +120,7 @@
|
|
120 |
<table class="container" align="left" border="0" cellpadding="0" cellspacing="0" width="260" style="border-collapse: collapse;border-spacing: 0;mso-table-lspace: 0pt;mso-table-rspace: 0pt;-ms-text-size-adjust: 100%;-webkit-text-size-adjust: 100%;">
|
121 |
<tr>
|
122 |
<td class="container-cell" valign="top" style="border-collapse: collapse;border-spacing: 0;mso-table-lspace: 0pt;mso-table-rspace: 0pt;-ms-text-size-adjust: 100%;-webkit-text-size-adjust: 100%;color: #404040;font-family: Helvetica;font-size: 16px;line-height: 150%;text-align: center;padding-bottom: 20px;">
|
123 |
-
<img class="preserve-ratio" src="
|
124 |
<br>
|
125 |
<h4 style="color: #202020;font-family: Helvetica;font-size: 20px;font-weight: bold;line-height: 150%;margin: 0;padding: 0;text-align: center;">
|
126 |
<a href="http://ithemes.com/codex/page/IThemes_Security" target="_blank" style="-ms-text-size-adjust: 100%;-webkit-text-size-adjust: 100%;color: #0084CB;font-family: Helvetica;font-size: 16px;line-height: 150%;text-align: center;text-decoration: none;">{{ $documentation }}</a>
|
@@ -133,7 +133,7 @@
|
|
133 |
<table class="container" align="right" border="0" cellpadding="0" cellspacing="0" width="260" style="border-collapse: collapse;border-spacing: 0;mso-table-lspace: 0pt;mso-table-rspace: 0pt;-ms-text-size-adjust: 100%;-webkit-text-size-adjust: 100%;">
|
134 |
<tr>
|
135 |
<td class="container-cell container-cell-bottom" valign="top" style="border-collapse: collapse;border-spacing: 0;mso-table-lspace: 0pt;mso-table-rspace: 0pt;-ms-text-size-adjust: 100%;-webkit-text-size-adjust: 100%;color: #404040;font-family: Helvetica;font-size: 16px;line-height: 150%;text-align: center;padding-bottom: 20px;">
|
136 |
-
<img class="preserve-ratio" src="
|
137 |
<br>
|
138 |
<h4 style="color: #202020;font-family: Helvetica;font-size: 20px;font-weight: bold;line-height: 150%;margin: 0;padding: 0;text-align: center;">
|
139 |
<a href="https://members.ithemes.com/panel/helpdesk.php" target="_blank" style="-ms-text-size-adjust: 100%;-webkit-text-size-adjust: 100%;color: #0084CB;font-family: Helvetica;font-size: 16px;line-height: 150%;text-align: center;text-decoration: none;">{{ $support }}</a>
|
@@ -163,7 +163,7 @@
|
|
163 |
<table class="container" align="left" border="0" cellpadding="0" cellspacing="0" width="104" style="border-collapse: collapse;border-spacing: 0;mso-table-lspace: 0pt;mso-table-rspace: 0pt;-ms-text-size-adjust: 100%;-webkit-text-size-adjust: 100%;">
|
164 |
<tr>
|
165 |
<td class="section-padding-bottom" align="left" valign="top" style="border-collapse: collapse;border-spacing: 0;mso-table-lspace: 0pt;mso-table-rspace: 0pt;-ms-text-size-adjust: 100%;-webkit-text-size-adjust: 100%;padding-bottom: 20px;">
|
166 |
-
<img class="preserve-ratio" src="
|
167 |
</td>
|
168 |
</tr>
|
169 |
</table>
|
@@ -194,7 +194,7 @@
|
|
194 |
<table border="0" cellpadding="0" cellspacing="0" width="100%" style="border-collapse: collapse;border-spacing: 0;mso-table-lspace: 0pt;mso-table-rspace: 0pt;-ms-text-size-adjust: 100%;-webkit-text-size-adjust: 100%;">
|
195 |
<tr>
|
196 |
<td class="container-cell" valign="top" style="border-collapse: collapse;border-spacing: 0;mso-table-lspace: 0pt;mso-table-rspace: 0pt;-ms-text-size-adjust: 100%;-webkit-text-size-adjust: 100%;color: #404040;font-family: Helvetica;font-size: 16px;line-height: 200%;text-align: center;padding-bottom: 0;padding-top: 60px;">
|
197 |
-
<img class="preserve-ratio" src="
|
198 |
<br>
|
199 |
<a href="{{ $security_settings_link }}" style="-ms-text-size-adjust: 100%;-webkit-text-size-adjust: 100%;color: #0084CB;font-family: Helvetica;font-size: 11px;line-height: 200%;text-align: center;text-decoration: none;font-weight: bold;">{{ $unsubscribe_link_text }}</a>
|
200 |
</td>
|
32 |
<table class="container" align="left" border="0" cellpadding="0" cellspacing="0" width="260" style="border-collapse: collapse;border-spacing: 0;mso-table-lspace: 0pt;mso-table-rspace: 0pt;-ms-text-size-adjust: 100%;-webkit-text-size-adjust: 100%;">
|
33 |
<tr>
|
34 |
<td class="container-cell" valign="top" style="border-collapse: collapse;border-spacing: 0;mso-table-lspace: 0pt;mso-table-rspace: 0pt;-ms-text-size-adjust: 100%;-webkit-text-size-adjust: 100%;color: #404040;font-family: Helvetica;font-size: 16px;line-height: 150%;text-align: center;padding-bottom: 20px;">
|
35 |
+
<img class="preserve-ratio" src="{! $article_icon }}" style="max-width: 61px;border: 0;outline: none;text-decoration: none;-ms-interpolation-mode: bicubic;height: auto;" width="61" alt="" align="center">
|
36 |
<br>
|
37 |
<h4 style="color: #202020;font-family: Helvetica;font-size: 20px;font-weight: bold;line-height: 150%;margin: 0;padding: 0;text-align: center;">
|
38 |
<a href="https://ithemes.com/category/wordpress-security/" target="_blank" style="-ms-text-size-adjust: 100%;-webkit-text-size-adjust: 100%;color: #0084CB;font-family: Helvetica;font-size: 16px;line-height: 150%;text-align: center;text-decoration: none;">{{ $articles }}</a>
|
45 |
<table class="container" align="right" border="0" cellpadding="0" cellspacing="0" width="260" style="border-collapse: collapse;border-spacing: 0;mso-table-lspace: 0pt;mso-table-rspace: 0pt;-ms-text-size-adjust: 100%;-webkit-text-size-adjust: 100%;">
|
46 |
<tr>
|
47 |
<td class="container-cell container-cell-bottom" valign="top" style="border-collapse: collapse;border-spacing: 0;mso-table-lspace: 0pt;mso-table-rspace: 0pt;-ms-text-size-adjust: 100%;-webkit-text-size-adjust: 100%;color: #404040;font-family: Helvetica;font-size: 16px;line-height: 150%;text-align: center;padding-bottom: 20px;">
|
48 |
+
<img class="preserve-ratio" src="{! $video_icon }}" style="max-width: 61px;border: 0;outline: none;text-decoration: none;-ms-interpolation-mode: bicubic;height: auto;" width="61" alt="" align="center">
|
49 |
<br>
|
50 |
<h4 style="color: #202020;font-family: Helvetica;font-size: 20px;font-weight: bold;line-height: 150%;margin: 0;padding: 0;text-align: center;">
|
51 |
<a href="https://ithemes.com/tutorial/category/ithemes-security/" target="_blank" style="-ms-text-size-adjust: 100%;-webkit-text-size-adjust: 100%;color: #0084CB;font-family: Helvetica;font-size: 16px;line-height: 150%;text-align: center;text-decoration: none;">{{ $tutorials }}</a>
|
120 |
<table class="container" align="left" border="0" cellpadding="0" cellspacing="0" width="260" style="border-collapse: collapse;border-spacing: 0;mso-table-lspace: 0pt;mso-table-rspace: 0pt;-ms-text-size-adjust: 100%;-webkit-text-size-adjust: 100%;">
|
121 |
<tr>
|
122 |
<td class="container-cell" valign="top" style="border-collapse: collapse;border-spacing: 0;mso-table-lspace: 0pt;mso-table-rspace: 0pt;-ms-text-size-adjust: 100%;-webkit-text-size-adjust: 100%;color: #404040;font-family: Helvetica;font-size: 16px;line-height: 150%;text-align: center;padding-bottom: 20px;">
|
123 |
+
<img class="preserve-ratio" src="{! $documentation_icon }}" style="max-width: 62px;border: 0;outline: none;text-decoration: none;-ms-interpolation-mode: bicubic;height: auto;" width="62" alt="" align="center">
|
124 |
<br>
|
125 |
<h4 style="color: #202020;font-family: Helvetica;font-size: 20px;font-weight: bold;line-height: 150%;margin: 0;padding: 0;text-align: center;">
|
126 |
<a href="http://ithemes.com/codex/page/IThemes_Security" target="_blank" style="-ms-text-size-adjust: 100%;-webkit-text-size-adjust: 100%;color: #0084CB;font-family: Helvetica;font-size: 16px;line-height: 150%;text-align: center;text-decoration: none;">{{ $documentation }}</a>
|
133 |
<table class="container" align="right" border="0" cellpadding="0" cellspacing="0" width="260" style="border-collapse: collapse;border-spacing: 0;mso-table-lspace: 0pt;mso-table-rspace: 0pt;-ms-text-size-adjust: 100%;-webkit-text-size-adjust: 100%;">
|
134 |
<tr>
|
135 |
<td class="container-cell container-cell-bottom" valign="top" style="border-collapse: collapse;border-spacing: 0;mso-table-lspace: 0pt;mso-table-rspace: 0pt;-ms-text-size-adjust: 100%;-webkit-text-size-adjust: 100%;color: #404040;font-family: Helvetica;font-size: 16px;line-height: 150%;text-align: center;padding-bottom: 20px;">
|
136 |
+
<img class="preserve-ratio" src="{! $support_icon }}" style="max-width: 62px;border: 0;outline: none;text-decoration: none;-ms-interpolation-mode: bicubic;height: auto;" width="62" alt="" align="center">
|
137 |
<br>
|
138 |
<h4 style="color: #202020;font-family: Helvetica;font-size: 20px;font-weight: bold;line-height: 150%;margin: 0;padding: 0;text-align: center;">
|
139 |
<a href="https://members.ithemes.com/panel/helpdesk.php" target="_blank" style="-ms-text-size-adjust: 100%;-webkit-text-size-adjust: 100%;color: #0084CB;font-family: Helvetica;font-size: 16px;line-height: 150%;text-align: center;text-decoration: none;">{{ $support }}</a>
|
163 |
<table class="container" align="left" border="0" cellpadding="0" cellspacing="0" width="104" style="border-collapse: collapse;border-spacing: 0;mso-table-lspace: 0pt;mso-table-rspace: 0pt;-ms-text-size-adjust: 100%;-webkit-text-size-adjust: 100%;">
|
164 |
<tr>
|
165 |
<td class="section-padding-bottom" align="left" valign="top" style="border-collapse: collapse;border-spacing: 0;mso-table-lspace: 0pt;mso-table-rspace: 0pt;-ms-text-size-adjust: 100%;-webkit-text-size-adjust: 100%;padding-bottom: 20px;">
|
166 |
+
<img class="preserve-ratio" src="{! $wp_security_book }}" style="max-width: 84px;border: 0;outline: none;text-decoration: none;-ms-interpolation-mode: bicubic;height: auto;" width="84" alt="" align="center">
|
167 |
</td>
|
168 |
</tr>
|
169 |
</table>
|
194 |
<table border="0" cellpadding="0" cellspacing="0" width="100%" style="border-collapse: collapse;border-spacing: 0;mso-table-lspace: 0pt;mso-table-rspace: 0pt;-ms-text-size-adjust: 100%;-webkit-text-size-adjust: 100%;">
|
195 |
<tr>
|
196 |
<td class="container-cell" valign="top" style="border-collapse: collapse;border-spacing: 0;mso-table-lspace: 0pt;mso-table-rspace: 0pt;-ms-text-size-adjust: 100%;-webkit-text-size-adjust: 100%;color: #404040;font-family: Helvetica;font-size: 16px;line-height: 200%;text-align: center;padding-bottom: 0;padding-top: 60px;">
|
197 |
+
<img class="preserve-ratio" src="{! $footer_logo }}" style="max-width: 50px;border: 0;outline: none;text-decoration: none;-ms-interpolation-mode: bicubic;height: auto;" width="50" alt="" align="center"><br>
|
198 |
<br>
|
199 |
<a href="{{ $security_settings_link }}" style="-ms-text-size-adjust: 100%;-webkit-text-size-adjust: 100%;color: #0084CB;font-family: Helvetica;font-size: 11px;line-height: 200%;text-align: center;text-decoration: none;font-weight: bold;">{{ $unsubscribe_link_text }}</a>
|
200 |
</td>
|
core/lib/mail-templates/pro-callout.html
CHANGED
@@ -9,7 +9,7 @@
|
|
9 |
<table border="0" cellpadding="0" cellspacing="0" width="100%" style="border-collapse: collapse;border-spacing: 0;mso-table-lspace: 0pt;mso-table-rspace: 0pt;-ms-text-size-adjust: 100%;-webkit-text-size-adjust: 100%;">
|
10 |
<tr>
|
11 |
<td valign="top" class="container-cell" style="border-collapse: collapse;border-spacing: 0;mso-table-lspace: 0pt;mso-table-rspace: 0pt;-ms-text-size-adjust: 100%;-webkit-text-size-adjust: 100%;color: #404040;font-family: Helvetica;font-size: 16px;line-height: 150%;text-align: center;padding-bottom: 20px;">
|
12 |
-
<img class="preserve-ratio" src="
|
13 |
<p class="two-factor" style="-ms-text-size-adjust: 100%;-webkit-text-size-adjust: 100%;font-family: Helvetica;font-size: 16px;line-height: 150%;margin-top: 20px;margin-right: 0;margin-bottom: 20px;margin-left: 0;padding: 0;text-align: center;color: #FFFFFF;">{{ $two_factor }}</p>
|
14 |
<table width="100%" border="0" cellspacing="0" cellpadding="0" style="border-collapse: collapse;border-spacing: 0;mso-table-lspace: 0pt;mso-table-rspace: 0pt;-ms-text-size-adjust: 100%;-webkit-text-size-adjust: 100%;">
|
15 |
<tr>
|
9 |
<table border="0" cellpadding="0" cellspacing="0" width="100%" style="border-collapse: collapse;border-spacing: 0;mso-table-lspace: 0pt;mso-table-rspace: 0pt;-ms-text-size-adjust: 100%;-webkit-text-size-adjust: 100%;">
|
10 |
<tr>
|
11 |
<td valign="top" class="container-cell" style="border-collapse: collapse;border-spacing: 0;mso-table-lspace: 0pt;mso-table-rspace: 0pt;-ms-text-size-adjust: 100%;-webkit-text-size-adjust: 100%;color: #404040;font-family: Helvetica;font-size: 16px;line-height: 150%;text-align: center;padding-bottom: 20px;">
|
12 |
+
<img class="preserve-ratio" src="{! $pro_logo_no_text }}" style="max-width: 100px;border: 0;outline: none;text-decoration: none;-ms-interpolation-mode: bicubic;height: auto;" width="100" alt="" align="center">
|
13 |
<p class="two-factor" style="-ms-text-size-adjust: 100%;-webkit-text-size-adjust: 100%;font-family: Helvetica;font-size: 16px;line-height: 150%;margin-top: 20px;margin-right: 0;margin-bottom: 20px;margin-left: 0;padding: 0;text-align: center;color: #FFFFFF;">{{ $two_factor }}</p>
|
14 |
<table width="100%" border="0" cellspacing="0" cellpadding="0" style="border-collapse: collapse;border-spacing: 0;mso-table-lspace: 0pt;mso-table-rspace: 0pt;-ms-text-size-adjust: 100%;-webkit-text-size-adjust: 100%;">
|
15 |
<tr>
|
core/lockout.php
CHANGED
@@ -79,7 +79,7 @@ final class ITSEC_Lockout {
|
|
79 |
add_action( 'itsec_purge_lockouts', array( $this, 'purge_lockouts' ) );
|
80 |
|
81 |
//Check for host lockouts
|
82 |
-
add_action( 'init', array( $this, '
|
83 |
|
84 |
// Ensure that locked out users are prevented from checking logins.
|
85 |
add_filter( 'authenticate', array( $this, 'check_authenticate_lockout' ), 30 );
|
@@ -128,17 +128,40 @@ final class ITSEC_Lockout {
|
|
128 |
return $user;
|
129 |
}
|
130 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
131 |
/**
|
132 |
* Checks if the host or user is locked out and executes lockout
|
133 |
*
|
134 |
* @since 4.0
|
135 |
*
|
136 |
-
* @param mixed
|
137 |
-
* @param mixed
|
|
|
138 |
*
|
139 |
* @return void
|
140 |
*/
|
141 |
-
public function check_lockout( $user = false, $username = false ) {
|
142 |
global $wpdb, $itsec_globals;
|
143 |
|
144 |
$wpdb->hide_errors(); //Hide database errors in case the tables aren't there
|
@@ -160,16 +183,16 @@ final class ITSEC_Lockout {
|
|
160 |
$user_id = $user->ID;
|
161 |
|
162 |
if ( $username !== false && $username != '' ) {
|
163 |
-
$username_check = $wpdb->
|
164 |
}
|
165 |
|
166 |
-
$host_check = $wpdb->
|
167 |
|
168 |
}
|
169 |
|
170 |
if ( $user_id !== 0 && $user_id !== null ) {
|
171 |
|
172 |
-
$user_check = $wpdb->
|
173 |
|
174 |
}
|
175 |
|
@@ -179,18 +202,67 @@ final class ITSEC_Lockout {
|
|
179 |
ITSEC_Lib::create_database_tables();
|
180 |
}
|
181 |
|
182 |
-
if ( $host_check
|
183 |
|
184 |
-
$
|
|
|
|
|
|
|
185 |
|
186 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
187 |
|
188 |
-
$this->execute_lock(
|
189 |
|
190 |
}
|
191 |
|
192 |
}
|
193 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
194 |
/**
|
195 |
* This persists a lockout to storage or performs a permanent ban if appropriate.
|
196 |
*
|
@@ -335,68 +407,93 @@ final class ITSEC_Lockout {
|
|
335 |
/**
|
336 |
* Executes lockout (locks user out)
|
337 |
*
|
338 |
-
* @param
|
339 |
-
* @param bool $
|
340 |
*
|
341 |
* @return void
|
342 |
*/
|
343 |
-
public function execute_lock( $
|
344 |
|
345 |
-
if (
|
346 |
-
|
347 |
}
|
348 |
|
349 |
-
|
350 |
-
|
351 |
-
|
352 |
-
|
353 |
-
|
354 |
-
|
|
|
355 |
}
|
356 |
|
357 |
-
|
358 |
-
|
359 |
-
|
360 |
-
@header( 'Pragma: no-cache' );
|
361 |
|
362 |
if ( $network === true ) { //lockout triggered by iThemes Network
|
363 |
|
364 |
$message = ITSEC_Modules::get_setting( 'global', 'community_lockout_message' );
|
365 |
|
366 |
-
if ( !
|
367 |
-
|
368 |
-
} else {
|
369 |
-
|
370 |
-
die( __( "Your IP address has been flagged as a threat by the iThemes Security network.", 'better-wp-security' ) );
|
371 |
-
|
372 |
}
|
373 |
|
374 |
} elseif ( $user === true ) { //lockout the user
|
375 |
|
376 |
$message = ITSEC_Modules::get_setting( 'global', 'user_lockout_message' );
|
377 |
|
378 |
-
if ( !
|
379 |
-
|
380 |
-
} else {
|
381 |
-
|
382 |
-
die( __( 'You have been locked out due to too many invalid login attempts.', 'better-wp-security' ) );
|
383 |
-
|
384 |
}
|
385 |
|
386 |
} else { //just lockout the host
|
387 |
|
388 |
$message = ITSEC_Modules::get_setting( 'global', 'lockout_message' );
|
389 |
|
390 |
-
if ( !
|
391 |
-
|
392 |
-
}
|
|
|
393 |
|
394 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
395 |
|
396 |
-
|
397 |
|
|
|
|
|
398 |
}
|
399 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
400 |
}
|
401 |
|
402 |
/**
|
@@ -799,15 +896,27 @@ final class ITSEC_Lockout {
|
|
799 |
$this->send_lockout_email( $good_host, $good_user, $good_username, $host_expiration, $user_expiration, $reason );
|
800 |
}
|
801 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
802 |
if ( $good_host !== false ) {
|
803 |
|
804 |
ITSEC_Lib::release_lock( $lock );
|
805 |
-
$this->execute_lock();
|
806 |
|
807 |
} else {
|
808 |
|
|
|
|
|
809 |
ITSEC_Lib::release_lock( $lock );
|
810 |
-
$this->execute_lock(
|
811 |
|
812 |
}
|
813 |
|
79 |
add_action( 'itsec_purge_lockouts', array( $this, 'purge_lockouts' ) );
|
80 |
|
81 |
//Check for host lockouts
|
82 |
+
add_action( 'init', array( $this, 'check_current_user_for_host_lockouts' ) );
|
83 |
|
84 |
// Ensure that locked out users are prevented from checking logins.
|
85 |
add_filter( 'authenticate', array( $this, 'check_authenticate_lockout' ), 30 );
|
128 |
return $user;
|
129 |
}
|
130 |
|
131 |
+
/**
|
132 |
+
* Lockout a user on every page load if there host becomes locked.
|
133 |
+
*/
|
134 |
+
public function check_current_user_for_host_lockouts() {
|
135 |
+
|
136 |
+
if ( ! is_user_logged_in() ) {
|
137 |
+
return;
|
138 |
+
}
|
139 |
+
|
140 |
+
global $wpdb;
|
141 |
+
|
142 |
+
$host = ITSEC_Lib::get_ip();
|
143 |
+
$host_check = $wpdb->get_var( $wpdb->prepare( "SELECT `lockout_host` FROM `{$wpdb->base_prefix}itsec_lockouts` WHERE `lockout_active`=1 AND `lockout_expire_gmt` > %s AND `lockout_host` = %s;", array(
|
144 |
+
date( 'Y-m-d H:i:s', ITSEC_Core::get_current_time_gmt() ),
|
145 |
+
$host
|
146 |
+
) ) );
|
147 |
+
|
148 |
+
if ( $host_check ) {
|
149 |
+
$this->execute_lock();
|
150 |
+
}
|
151 |
+
}
|
152 |
+
|
153 |
/**
|
154 |
* Checks if the host or user is locked out and executes lockout
|
155 |
*
|
156 |
* @since 4.0
|
157 |
*
|
158 |
+
* @param mixed $user WordPress user object or false.
|
159 |
+
* @param mixed $username The username to check.
|
160 |
+
* @param string $type Lockout type asking for the check.
|
161 |
*
|
162 |
* @return void
|
163 |
*/
|
164 |
+
public function check_lockout( $user = false, $username = false, $type = '' ) {
|
165 |
global $wpdb, $itsec_globals;
|
166 |
|
167 |
$wpdb->hide_errors(); //Hide database errors in case the tables aren't there
|
183 |
$user_id = $user->ID;
|
184 |
|
185 |
if ( $username !== false && $username != '' ) {
|
186 |
+
$username_check = $wpdb->get_results( "SELECT `lockout_username`, `lockout_type` FROM `" . $wpdb->base_prefix . "itsec_lockouts` WHERE `lockout_active`=1 AND `lockout_expire_gmt` > '" . date( 'Y-m-d H:i:s', $itsec_globals['current_time_gmt'] ) . "' AND `lockout_username`='" . $username . "';" );
|
187 |
}
|
188 |
|
189 |
+
$host_check = $wpdb->get_results( "SELECT `lockout_host`, `lockout_type` FROM `" . $wpdb->base_prefix . "itsec_lockouts` WHERE `lockout_active`=1 AND `lockout_expire_gmt` > '" . date( 'Y-m-d H:i:s', $itsec_globals['current_time_gmt'] ) . "' AND `lockout_host`='" . $host . "';" );
|
190 |
|
191 |
}
|
192 |
|
193 |
if ( $user_id !== 0 && $user_id !== null ) {
|
194 |
|
195 |
+
$user_check = $wpdb->get_results( "SELECT `lockout_user`, `lockout_type` FROM `" . $wpdb->base_prefix . "itsec_lockouts` WHERE `lockout_active`=1 AND `lockout_expire_gmt` > '" . date( 'Y-m-d H:i:s', $itsec_globals['current_time_gmt'] ) . "' AND `lockout_user`=" . intval( $user_id ) . ";" );
|
196 |
|
197 |
}
|
198 |
|
202 |
ITSEC_Lib::create_database_tables();
|
203 |
}
|
204 |
|
205 |
+
if ( $host_check ) {
|
206 |
|
207 |
+
$type = $type ? $type : $host_check[0]->lockout_type;
|
208 |
+
$this->execute_lock( array( 'type' => $type ) );
|
209 |
+
|
210 |
+
} elseif ( $user_check || $username_check ) {
|
211 |
|
212 |
+
if ( ! $type ) {
|
213 |
+
$type = $user_check ? $user_check[0]->lockout_type : $username_check[0]->lockout_type;
|
214 |
+
}
|
215 |
+
|
216 |
+
$lock_context = array( 'user_lock' => true, 'type' => $type );
|
217 |
+
|
218 |
+
if ( $user ) {
|
219 |
+
$lock_context['user'] = $user;
|
220 |
+
} elseif ( $username ) {
|
221 |
+
$lock_context['username'] = $username;
|
222 |
+
}
|
223 |
|
224 |
+
$this->execute_lock( $lock_context );
|
225 |
|
226 |
}
|
227 |
|
228 |
}
|
229 |
|
230 |
+
/**
|
231 |
+
* Check if a given username is locked out.
|
232 |
+
*
|
233 |
+
* @param string $username
|
234 |
+
*
|
235 |
+
* @return bool
|
236 |
+
*/
|
237 |
+
public function is_username_locked_out( $username ) {
|
238 |
+
|
239 |
+
/** @var wpdb $wpdb */
|
240 |
+
global $wpdb;
|
241 |
+
|
242 |
+
return (bool) $wpdb->get_var( $wpdb->prepare(
|
243 |
+
"SELECT `lockout_username` FROM `{$wpdb->base_prefix}itsec_lockouts` WHERE `lockout_active`=1 AND `lockout_expire_gmt` > %s AND `lockout_username` = %s;",
|
244 |
+
date( 'Y-m-d H:i:s', ITSEC_Core::get_current_time_gmt() ), $username
|
245 |
+
) );
|
246 |
+
}
|
247 |
+
|
248 |
+
/**
|
249 |
+
* Check if a given user is locked out.
|
250 |
+
*
|
251 |
+
* @param string $user_id
|
252 |
+
*
|
253 |
+
* @return bool
|
254 |
+
*/
|
255 |
+
public function is_user_locked_out( $user_id ) {
|
256 |
+
|
257 |
+
/** @var wpdb $wpdb */
|
258 |
+
global $wpdb;
|
259 |
+
|
260 |
+
return (bool) $wpdb->get_var( $wpdb->prepare(
|
261 |
+
"SELECT `lockout_user` FROM `{$wpdb->base_prefix}itsec_lockouts` WHERE `lockout_active`=1 AND `lockout_expire_gmt` > %s AND `lockout_user` = %d;",
|
262 |
+
date( 'Y-m-d H:i:s', ITSEC_Core::get_current_time_gmt() ), $user_id
|
263 |
+
) );
|
264 |
+
}
|
265 |
+
|
266 |
/**
|
267 |
* This persists a lockout to storage or performs a permanent ban if appropriate.
|
268 |
*
|
407 |
/**
|
408 |
* Executes lockout (locks user out)
|
409 |
*
|
410 |
+
* @param array $context
|
411 |
+
* @param bool $deprecated Deprecated argument. Previously whether this is a network lock.
|
412 |
*
|
413 |
* @return void
|
414 |
*/
|
415 |
+
public function execute_lock( $context = array(), $deprecated = false ) {
|
416 |
|
417 |
+
if ( func_num_args() > 1 ) {
|
418 |
+
_deprecated_argument( __METHOD__, '6.5.0', 'A network lockout should be specified in the $context parameter.' );
|
419 |
}
|
420 |
|
421 |
+
if ( is_array( $context ) ) {
|
422 |
+
$context = wp_parse_args( $context, array( 'user_lock' => false, 'network_lock' => false, 'type' => '' ) );
|
423 |
+
$user = $context['user_lock'];
|
424 |
+
$network = $context['network_lock'];
|
425 |
+
} else {
|
426 |
+
$user = $context;
|
427 |
+
$network = $deprecated;
|
428 |
}
|
429 |
|
430 |
+
if ( ITSEC_Lib::is_ip_whitelisted( ITSEC_Lib::get_ip() ) ) {
|
431 |
+
return;
|
432 |
+
}
|
|
|
433 |
|
434 |
if ( $network === true ) { //lockout triggered by iThemes Network
|
435 |
|
436 |
$message = ITSEC_Modules::get_setting( 'global', 'community_lockout_message' );
|
437 |
|
438 |
+
if ( ! $message ) {
|
439 |
+
$message = __( 'Your IP address has been flagged as a threat by the iThemes Security network.', 'better-wp-security' );
|
|
|
|
|
|
|
|
|
440 |
}
|
441 |
|
442 |
} elseif ( $user === true ) { //lockout the user
|
443 |
|
444 |
$message = ITSEC_Modules::get_setting( 'global', 'user_lockout_message' );
|
445 |
|
446 |
+
if ( ! $message ) {
|
447 |
+
$message = __( 'You have been locked out due to too many invalid login attempts.', 'better-wp-security' );
|
|
|
|
|
|
|
|
|
448 |
}
|
449 |
|
450 |
} else { //just lockout the host
|
451 |
|
452 |
$message = ITSEC_Modules::get_setting( 'global', 'lockout_message' );
|
453 |
|
454 |
+
if ( ! $message ) {
|
455 |
+
$message = __( 'Error.', 'better-wp-security' );
|
456 |
+
}
|
457 |
+
}
|
458 |
|
459 |
+
$formatted = false;
|
460 |
+
|
461 |
+
if ( $context['type'] ) {
|
462 |
+
/**
|
463 |
+
* Filter the lockout message displayed to the user.
|
464 |
+
*
|
465 |
+
* @param string $message
|
466 |
+
* @param string $type
|
467 |
+
* @param array $context
|
468 |
+
*/
|
469 |
+
$message = apply_filters( "itsec_{$context['type']}_lockout_message", $message, $context );
|
470 |
+
|
471 |
+
/**
|
472 |
+
* Filter whether to print the lockout error message with formatting or not.
|
473 |
+
*
|
474 |
+
* @param bool $formatted
|
475 |
+
* @param string $type
|
476 |
+
* @param array $context
|
477 |
+
*/
|
478 |
+
$formatted = apply_filters( "itsec_{$context['type']}_lockout_format_message", false, $context );
|
479 |
+
}
|
480 |
|
481 |
+
$current_user = wp_get_current_user();
|
482 |
|
483 |
+
if ( is_object( $current_user ) && isset( $current_user->ID ) ) {
|
484 |
+
wp_logout();
|
485 |
}
|
486 |
|
487 |
+
if ( $formatted ) {
|
488 |
+
wp_die( $message, '', array( 'response' => 403 ) );
|
489 |
+
} else {
|
490 |
+
@header( 'HTTP/1.0 403 Forbidden' );
|
491 |
+
@header( 'Cache-Control: no-cache, must-revalidate, max-age=0' );
|
492 |
+
@header( 'Expires: Thu, 22 Jun 1978 00:28:00 GMT' );
|
493 |
+
@header( 'Pragma: no-cache' );
|
494 |
+
|
495 |
+
die( $message );
|
496 |
+
}
|
497 |
}
|
498 |
|
499 |
/**
|
896 |
$this->send_lockout_email( $good_host, $good_user, $good_username, $host_expiration, $user_expiration, $reason );
|
897 |
}
|
898 |
|
899 |
+
$lock_context = array(
|
900 |
+
'type' => $type,
|
901 |
+
);
|
902 |
+
|
903 |
+
if ( $user ) {
|
904 |
+
$lock_context['user'] = get_userdata( $user );
|
905 |
+
} elseif ( $username ) {
|
906 |
+
$lock_context['username'] = $username;
|
907 |
+
}
|
908 |
+
|
909 |
if ( $good_host !== false ) {
|
910 |
|
911 |
ITSEC_Lib::release_lock( $lock );
|
912 |
+
$this->execute_lock( $lock_context );
|
913 |
|
914 |
} else {
|
915 |
|
916 |
+
$lock_context['user_lock'] = true;
|
917 |
+
|
918 |
ITSEC_Lib::release_lock( $lock );
|
919 |
+
$this->execute_lock( $lock_context );
|
920 |
|
921 |
}
|
922 |
|
core/modules/brute-force/class-itsec-brute-force.php
CHANGED
@@ -194,10 +194,10 @@ class ITSEC_Brute_Force {
|
|
194 |
}
|
195 |
|
196 |
if ( empty( $user_id ) ) {
|
197 |
-
$itsec_lockout->check_lockout( false, $username );
|
198 |
} else {
|
199 |
-
$itsec_lockout->check_lockout( $user_id );
|
200 |
-
}
|
201 |
|
202 |
$itsec_logger->log_event( 'brute_force', 5, $details, ITSEC_Lib::get_ip(), $username, intval( $user_id ) );
|
203 |
$itsec_lockout->do_lockout( 'brute_force', $username );
|
194 |
}
|
195 |
|
196 |
if ( empty( $user_id ) ) {
|
197 |
+
$itsec_lockout->check_lockout( false, $username, 'brute_force' );
|
198 |
} else {
|
199 |
+
$itsec_lockout->check_lockout( $user_id, false, 'brute_force' );
|
200 |
+
}
|
201 |
|
202 |
$itsec_logger->log_event( 'brute_force', 5, $details, ITSEC_Lib::get_ip(), $username, intval( $user_id ) );
|
203 |
$itsec_lockout->do_lockout( 'brute_force', $username );
|
core/modules/ipcheck/class-itsec-ipcheck.php
CHANGED
@@ -234,7 +234,7 @@ class ITSEC_IPCheck {
|
|
234 |
|
235 |
if ( $this->settings['enable_ban'] && $this->is_ip_banned() ) {
|
236 |
$itsec_logger->log_event( 'ipcheck', 10, array(), ITSEC_Lib::get_ip() );
|
237 |
-
$itsec_lockout->execute_lock(
|
238 |
}
|
239 |
}
|
240 |
|
@@ -254,7 +254,7 @@ class ITSEC_IPCheck {
|
|
254 |
|
255 |
if ( $this->settings['enable_ban'] && $this->report_ip() ) {
|
256 |
$itsec_logger->log_event( 'ipcheck', 10, array(), ITSEC_Lib::get_ip() );
|
257 |
-
$itsec_lockout->execute_lock(
|
258 |
}
|
259 |
}
|
260 |
|
234 |
|
235 |
if ( $this->settings['enable_ban'] && $this->is_ip_banned() ) {
|
236 |
$itsec_logger->log_event( 'ipcheck', 10, array(), ITSEC_Lib::get_ip() );
|
237 |
+
$itsec_lockout->execute_lock( array( 'network_lock' => true ) );
|
238 |
}
|
239 |
}
|
240 |
|
254 |
|
255 |
if ( $this->settings['enable_ban'] && $this->report_ip() ) {
|
256 |
$itsec_logger->log_event( 'ipcheck', 10, array(), ITSEC_Lib::get_ip() );
|
257 |
+
$itsec_lockout->execute_lock( array( 'network_lock' => true ) );
|
258 |
}
|
259 |
}
|
260 |
|
core/modules/pro/settings-page.php
CHANGED
@@ -4,36 +4,36 @@
|
|
4 |
*/
|
5 |
|
6 |
|
7 |
-
final class
|
8 |
public function __construct() {
|
9 |
-
$this->id = '
|
10 |
-
$this->title = __( '
|
11 |
-
$this->description = __( '
|
12 |
$this->type = 'recommended';
|
13 |
$this->pro = true;
|
14 |
$this->upsell = true;
|
15 |
-
$this->upsell_url = 'http://ithemes.com/security
|
16 |
|
17 |
parent::__construct();
|
18 |
}
|
19 |
}
|
20 |
-
new
|
21 |
|
22 |
|
23 |
-
final class
|
24 |
public function __construct() {
|
25 |
-
$this->id = '
|
26 |
-
$this->title = __( '
|
27 |
-
$this->description = __( '
|
28 |
$this->type = 'recommended';
|
29 |
$this->pro = true;
|
30 |
$this->upsell = true;
|
31 |
-
$this->upsell_url = '
|
32 |
|
33 |
parent::__construct();
|
34 |
}
|
35 |
}
|
36 |
-
new
|
37 |
|
38 |
|
39 |
final class ITSEC_Password_Expiration_Settings_Page extends ITSEC_Module_Settings_Page {
|
@@ -52,6 +52,22 @@ final class ITSEC_Password_Expiration_Settings_Page extends ITSEC_Module_Setting
|
|
52 |
new ITSEC_Password_Expiration_Settings_Page();
|
53 |
|
54 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
55 |
final class ITSEC_Recaptcha_Settings_Page extends ITSEC_Module_Settings_Page {
|
56 |
public function __construct() {
|
57 |
$this->id = 'recaptcha';
|
@@ -103,36 +119,36 @@ final class ITSEC_Two_Factor_Settings_Page extends ITSEC_Module_Settings_Page {
|
|
103 |
new ITSEC_Two_Factor_Settings_Page();
|
104 |
|
105 |
|
106 |
-
final class
|
107 |
public function __construct() {
|
108 |
-
$this->id = 'user-
|
109 |
-
$this->title = __( 'User
|
110 |
-
$this->description = __( '
|
111 |
$this->type = 'recommended';
|
112 |
$this->pro = true;
|
113 |
$this->upsell = true;
|
114 |
-
$this->upsell_url = 'https://ithemes.com/security/wordpress-user-
|
115 |
|
116 |
parent::__construct();
|
117 |
}
|
118 |
}
|
119 |
-
new
|
120 |
|
121 |
|
122 |
-
final class
|
123 |
public function __construct() {
|
124 |
-
$this->id = 'user-
|
125 |
-
$this->title = __( 'User
|
126 |
-
$this->description = __( '
|
127 |
$this->type = 'recommended';
|
128 |
$this->pro = true;
|
129 |
$this->upsell = true;
|
130 |
-
$this->upsell_url = 'https://ithemes.com/security/wordpress-user-
|
131 |
|
132 |
parent::__construct();
|
133 |
}
|
134 |
}
|
135 |
-
new
|
136 |
|
137 |
|
138 |
final class ITSEC_Version_Management_Settings_Page extends ITSEC_Module_Settings_Page {
|
4 |
*/
|
5 |
|
6 |
|
7 |
+
final class ITSEC_Magic_Links_Settings_Page extends ITSEC_Module_Settings_Page {
|
8 |
public function __construct() {
|
9 |
+
$this->id = 'magic-links';
|
10 |
+
$this->title = __( 'Magic Links', 'better-wp-security' );
|
11 |
+
$this->description = __( 'Send an email with a Magic Link that bypasses a username lockout.', 'better-wp-security' );
|
12 |
$this->type = 'recommended';
|
13 |
$this->pro = true;
|
14 |
$this->upsell = true;
|
15 |
+
$this->upsell_url = 'http://ithemes.com/security/?utm_source=wordpressadmin&utm_medium=widget&utm_campaign=itsecfreecta';
|
16 |
|
17 |
parent::__construct();
|
18 |
}
|
19 |
}
|
20 |
+
new ITSEC_Magic_Links_Settings_Page();
|
21 |
|
22 |
|
23 |
+
final class ITSEC_Malware_Scheduling_Settings_Page extends ITSEC_Module_Settings_Page {
|
24 |
public function __construct() {
|
25 |
+
$this->id = 'malware-scheduling';
|
26 |
+
$this->title = __( 'Malware Scan Scheduling', 'better-wp-security' );
|
27 |
+
$this->description = __( 'Protect your site with automated malware scans. When this feature is enabled, the site will be automatically scanned each day. If a problem is found, an email is sent to select users.', 'better-wp-security' );
|
28 |
$this->type = 'recommended';
|
29 |
$this->pro = true;
|
30 |
$this->upsell = true;
|
31 |
+
$this->upsell_url = 'http://ithemes.com/security/wordpress-malware-scan/?utm_source=wordpressadmin&utm_medium=widget&utm_campaign=itsecfreecta';
|
32 |
|
33 |
parent::__construct();
|
34 |
}
|
35 |
}
|
36 |
+
new ITSEC_Malware_Scheduling_Settings_Page();
|
37 |
|
38 |
|
39 |
final class ITSEC_Password_Expiration_Settings_Page extends ITSEC_Module_Settings_Page {
|
52 |
new ITSEC_Password_Expiration_Settings_Page();
|
53 |
|
54 |
|
55 |
+
final class ITSEC_Privilege_Escalation_Settings_Page extends ITSEC_Module_Settings_Page {
|
56 |
+
public function __construct() {
|
57 |
+
$this->id = 'privilege';
|
58 |
+
$this->title = __( 'Privilege Escalation', 'better-wp-security' );
|
59 |
+
$this->description = __( 'Allow administrators to temporarily grant extra access to a user of the site for a specified period of time.', 'better-wp-security' );
|
60 |
+
$this->type = 'recommended';
|
61 |
+
$this->pro = true;
|
62 |
+
$this->upsell = true;
|
63 |
+
$this->upsell_url = 'https://ithemes.com/security/wordpress-privilege-escalation/?utm_source=wordpressadmin&utm_medium=widget&utm_campaign=itsecfreecta';
|
64 |
+
|
65 |
+
parent::__construct();
|
66 |
+
}
|
67 |
+
}
|
68 |
+
new ITSEC_Privilege_Escalation_Settings_Page();
|
69 |
+
|
70 |
+
|
71 |
final class ITSEC_Recaptcha_Settings_Page extends ITSEC_Module_Settings_Page {
|
72 |
public function __construct() {
|
73 |
$this->id = 'recaptcha';
|
119 |
new ITSEC_Two_Factor_Settings_Page();
|
120 |
|
121 |
|
122 |
+
final class ITSEC_User_Security_Check_Settings_Page extends ITSEC_Module_Settings_Page {
|
123 |
public function __construct() {
|
124 |
+
$this->id = 'user-security-check';
|
125 |
+
$this->title = __( 'User Security Check', 'better-wp-security' );
|
126 |
+
$this->description = __( 'Every user on your site affects overall security. See how your users might be affecting your security and take action when needed.', 'better-wp-security' );
|
127 |
$this->type = 'recommended';
|
128 |
$this->pro = true;
|
129 |
$this->upsell = true;
|
130 |
+
$this->upsell_url = 'https://ithemes.com/security/wordpress-user-security-check/?utm_source=wordpressadmin&utm_medium=widget&utm_campaign=itsecfreecta';
|
131 |
|
132 |
parent::__construct();
|
133 |
}
|
134 |
}
|
135 |
+
new ITSEC_User_Security_Check_Settings_Page();
|
136 |
|
137 |
|
138 |
+
final class ITSEC_User_Logging_Settings_Page extends ITSEC_Module_Settings_Page {
|
139 |
public function __construct() {
|
140 |
+
$this->id = 'user-logging';
|
141 |
+
$this->title = __( 'User Logging', 'better-wp-security' );
|
142 |
+
$this->description = __( 'Log user actions such as login, saving content and others.', 'better-wp-security' );
|
143 |
$this->type = 'recommended';
|
144 |
$this->pro = true;
|
145 |
$this->upsell = true;
|
146 |
+
$this->upsell_url = 'https://ithemes.com/security/wordpress-user-log/?utm_source=wordpressadmin&utm_medium=widget&utm_campaign=itsecfreecta';
|
147 |
|
148 |
parent::__construct();
|
149 |
}
|
150 |
}
|
151 |
+
new ITSEC_User_Logging_Settings_Page();
|
152 |
|
153 |
|
154 |
final class ITSEC_Version_Management_Settings_Page extends ITSEC_Module_Settings_Page {
|
core/modules/security-check/scanner.php
CHANGED
@@ -12,6 +12,7 @@ final class ITSEC_Security_Check_Scanner {
|
|
12 |
'ban-users' => __( 'Banned Users', 'better-wp-security' ),
|
13 |
'backup' => __( 'Database Backups', 'better-wp-security' ),
|
14 |
'brute-force' => __( 'Local Brute Force Protection', 'better-wp-security' ),
|
|
|
15 |
'malware-scheduling' => __( 'Malware Scan Scheduling', 'better-wp-security' ),
|
16 |
'network-brute-force' => __( 'Network Brute Force Protection', 'better-wp-security' ),
|
17 |
'strong-passwords' => __( 'Strong Passwords', 'better-wp-security' ),
|
@@ -48,6 +49,7 @@ final class ITSEC_Security_Check_Scanner {
|
|
48 |
|
49 |
self::enforce_activation( 'backup', __( 'Database Backups', 'better-wp-security' ) );
|
50 |
self::enforce_activation( 'brute-force', __( 'Local Brute Force Protection', 'better-wp-security' ) );
|
|
|
51 |
self::enforce_activation( 'malware-scheduling', __( 'Malware Scan Scheduling', 'better-wp-security' ) );
|
52 |
self::enforce_setting( 'malware-scheduling', 'email_notifications', true, __( 'Enabled the Email Notifications setting in Malware Scan Scheduling.', 'better-wp-security' ) );
|
53 |
|
12 |
'ban-users' => __( 'Banned Users', 'better-wp-security' ),
|
13 |
'backup' => __( 'Database Backups', 'better-wp-security' ),
|
14 |
'brute-force' => __( 'Local Brute Force Protection', 'better-wp-security' ),
|
15 |
+
'magic-links' => __( 'Magic Links', 'better-wp-security' ),
|
16 |
'malware-scheduling' => __( 'Malware Scan Scheduling', 'better-wp-security' ),
|
17 |
'network-brute-force' => __( 'Network Brute Force Protection', 'better-wp-security' ),
|
18 |
'strong-passwords' => __( 'Strong Passwords', 'better-wp-security' ),
|
49 |
|
50 |
self::enforce_activation( 'backup', __( 'Database Backups', 'better-wp-security' ) );
|
51 |
self::enforce_activation( 'brute-force', __( 'Local Brute Force Protection', 'better-wp-security' ) );
|
52 |
+
self::enforce_activation( 'magic-links', __( 'Magic Links', 'better-wp-security' ) );
|
53 |
self::enforce_activation( 'malware-scheduling', __( 'Malware Scan Scheduling', 'better-wp-security' ) );
|
54 |
self::enforce_setting( 'malware-scheduling', 'email_notifications', true, __( 'Enabled the Email Notifications setting in Malware Scan Scheduling.', 'better-wp-security' ) );
|
55 |
|
core/modules/wordpress-tweaks/class-itsec-wordpress-tweaks.php
CHANGED
@@ -70,6 +70,18 @@ final class ITSEC_WordPress_Tweaks {
|
|
70 |
|
71 |
$this->settings = ITSEC_Modules::get_settings( 'wordpress-tweaks' );
|
72 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
73 |
// Functional code for the allow_xmlrpc_multiauth setting.
|
74 |
if ( defined( 'XMLRPC_REQUEST' ) && XMLRPC_REQUEST && ! $this->settings['allow_xmlrpc_multiauth'] ) {
|
75 |
add_filter( 'authenticate', array( $this, 'block_multiauth_attempts' ), 0, 3 );
|
@@ -116,6 +128,48 @@ final class ITSEC_WordPress_Tweaks {
|
|
116 |
}
|
117 |
}
|
118 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
119 |
/**
|
120 |
* Require capabilities for reading from WordPress object routes.
|
121 |
*
|
70 |
|
71 |
$this->settings = ITSEC_Modules::get_settings( 'wordpress-tweaks' );
|
72 |
|
73 |
+
|
74 |
+
// Functional code for the valid_user_login_type setting.
|
75 |
+
if ( 'email' === $this->settings['valid_user_login_type'] ) {
|
76 |
+
add_action( 'login_init', array( $this, 'add_gettext_filter' ) );
|
77 |
+
add_filter( 'authenticate', array( $this, 'add_gettext_filter' ), 0 );
|
78 |
+
remove_filter( 'authenticate', 'wp_authenticate_username_password', 20 );
|
79 |
+
} else if ( 'username' === $this->settings['valid_user_login_type'] ) {
|
80 |
+
add_action( 'login_init', array( $this, 'add_gettext_filter' ) );
|
81 |
+
add_filter( 'authenticate', array( $this, 'add_gettext_filter' ), 0 );
|
82 |
+
remove_filter( 'authenticate', 'wp_authenticate_email_password', 20 );
|
83 |
+
}
|
84 |
+
|
85 |
// Functional code for the allow_xmlrpc_multiauth setting.
|
86 |
if ( defined( 'XMLRPC_REQUEST' ) && XMLRPC_REQUEST && ! $this->settings['allow_xmlrpc_multiauth'] ) {
|
87 |
add_filter( 'authenticate', array( $this, 'block_multiauth_attempts' ), 0, 3 );
|
128 |
}
|
129 |
}
|
130 |
|
131 |
+
/**
|
132 |
+
* Add filter for gettext to change text for the valid_user_login_type setting changes.
|
133 |
+
*
|
134 |
+
* @return null
|
135 |
+
*/
|
136 |
+
public function add_gettext_filter() {
|
137 |
+
if ( ! has_filter( 'gettext', array( $this, 'filter_gettext' ) ) ) {
|
138 |
+
add_filter( 'gettext', array( $this, 'filter_gettext' ), 20, 3 );
|
139 |
+
}
|
140 |
+
}
|
141 |
+
|
142 |
+
/**
|
143 |
+
* Filter text for the valid_user_login_type setting changes.
|
144 |
+
*
|
145 |
+
* @param string $translation Translated text.
|
146 |
+
* @param string $text Text to translate.
|
147 |
+
* @param string $domain Text domain. Unique identifier for retrieving translated strings.
|
148 |
+
*
|
149 |
+
* @return string
|
150 |
+
*/
|
151 |
+
public function filter_gettext( $translation, $text, $domain ) {
|
152 |
+
if ( 'default' !== $domain ) {
|
153 |
+
return $translation;
|
154 |
+
}
|
155 |
+
|
156 |
+
if ( 'Username or Email Address' === $text ) {
|
157 |
+
if ( 'email' === $this->settings['valid_user_login_type'] ) {
|
158 |
+
return esc_html__( 'Email Address', 'better-wp-security' );
|
159 |
+
} else if ( 'username' === $this->settings['valid_user_login_type'] ) {
|
160 |
+
return esc_html__( 'Username', 'better-wp-security' );
|
161 |
+
}
|
162 |
+
} else if ( '<strong>ERROR</strong>: Invalid username, email address or incorrect password.' === $text ) {
|
163 |
+
if ( 'email' === $this->settings['valid_user_login_type'] ) {
|
164 |
+
return __( '<strong>ERROR</strong>: Invalid email address or incorrect password.', 'better-wp-security' );
|
165 |
+
} else if ( 'username' === $this->settings['valid_user_login_type'] ) {
|
166 |
+
return __( '<strong>ERROR</strong>: Invalid username or incorrect password.', 'better-wp-security' );
|
167 |
+
}
|
168 |
+
}
|
169 |
+
|
170 |
+
return $translation;
|
171 |
+
}
|
172 |
+
|
173 |
/**
|
174 |
* Require capabilities for reading from WordPress object routes.
|
175 |
*
|
core/modules/wordpress-tweaks/settings-page.php
CHANGED
@@ -38,6 +38,12 @@ final class ITSEC_WordPress_Tweaks_Settings_Page extends ITSEC_Module_Settings_P
|
|
38 |
'default-access' => esc_html__( 'Default Access', 'better-wp-security' ),
|
39 |
);
|
40 |
|
|
|
|
|
|
|
|
|
|
|
|
|
41 |
?>
|
42 |
<p><?php esc_html_e( 'Note: These settings are listed as advanced because they block common forms of attacks but they can also block legitimate plugins and themes that rely on the same techniques. When activating the settings below, we recommend enabling them one by one to test that everything on your site is still working as expected.', 'better-wp-security' ); ?></p>
|
43 |
<p><?php esc_html_e( 'Remember, some of these settings might conflict with other plugins or themes, so test your site after enabling each setting.', 'better-wp-security' ); ?></p>
|
@@ -140,6 +146,18 @@ final class ITSEC_WordPress_Tweaks_Settings_Page extends ITSEC_Module_Settings_P
|
|
140 |
<p class="description"><?php printf( wp_kses( __( 'Enabling this feature helps protect visitors to this site (including logged in users) from phishing attacks launched by a linked site. Details on tabnapping via target="_blank" links can be found in <a href="%s">this article</a>.', 'better-wp-security' ), array( 'a' => array( 'href' => array() ) ) ), esc_url( 'https://www.jitbit.com/alexblog/256-targetblank---the-most-underestimated-vulnerability-ever/' ) ); ?></p>
|
141 |
</td>
|
142 |
</tr>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
143 |
</table>
|
144 |
<?php
|
145 |
|
38 |
'default-access' => esc_html__( 'Default Access', 'better-wp-security' ),
|
39 |
);
|
40 |
|
41 |
+
$valid_user_login_types = array(
|
42 |
+
'both' => esc_html__( 'Email Address and Username (default)', 'better-wp-security' ),
|
43 |
+
'email' => esc_html__( 'Email Address Only', 'better-wp-security' ),
|
44 |
+
'username' => esc_html__( 'Username Only', 'better-wp-security' ),
|
45 |
+
);
|
46 |
+
|
47 |
?>
|
48 |
<p><?php esc_html_e( 'Note: These settings are listed as advanced because they block common forms of attacks but they can also block legitimate plugins and themes that rely on the same techniques. When activating the settings below, we recommend enabling them one by one to test that everything on your site is still working as expected.', 'better-wp-security' ); ?></p>
|
49 |
<p><?php esc_html_e( 'Remember, some of these settings might conflict with other plugins or themes, so test your site after enabling each setting.', 'better-wp-security' ); ?></p>
|
146 |
<p class="description"><?php printf( wp_kses( __( 'Enabling this feature helps protect visitors to this site (including logged in users) from phishing attacks launched by a linked site. Details on tabnapping via target="_blank" links can be found in <a href="%s">this article</a>.', 'better-wp-security' ), array( 'a' => array( 'href' => array() ) ) ), esc_url( 'https://www.jitbit.com/alexblog/256-targetblank---the-most-underestimated-vulnerability-ever/' ) ); ?></p>
|
147 |
</td>
|
148 |
</tr>
|
149 |
+
<tr>
|
150 |
+
<th scope="row"><label for="itsec-wordpress-tweaks-valid_user_login_type"><?php esc_html_e( 'Login with Email Address or Username', 'better-wp-security' ); ?></label></th>
|
151 |
+
<td>
|
152 |
+
<p><?php esc_html_e( 'By default, WordPress allows users to log in using either an email address or username. This setting allows you to restrict logins to only accept email addresses or usernames.', 'better-wp-security' ); ?></p>
|
153 |
+
<?php $form->add_select( 'valid_user_login_type', $valid_user_login_types ); ?>
|
154 |
+
<ul>
|
155 |
+
<li><?php echo wp_kses( __( '<strong>Email Address and Username (Default)</strong> - Allow users to log in using their user\'s email address or username. This is the default WordPress behavior.', 'better-wp-security' ), array( 'strong' => array() ) ); ?></li>
|
156 |
+
<li><?php echo wp_kses( __( '<strong>Email Address Only</strong> - Users can only log in using their user\'s email address. This disables logging in using a username.', 'better-wp-security' ), array( 'strong' => array() ) ); ?></li>
|
157 |
+
<li><?php echo wp_kses( __( '<strong>Username Only</strong> - Users can only log in using their user\'s username. This disables logging in using an email address.', 'better-wp-security' ), array( 'strong' => array() ) ); ?></li>
|
158 |
+
</ul>
|
159 |
+
</td>
|
160 |
+
</tr>
|
161 |
</table>
|
162 |
<?php
|
163 |
|
core/modules/wordpress-tweaks/settings.php
CHANGED
@@ -18,6 +18,7 @@ final class ITSEC_Wordpress_Tweaks_Settings extends ITSEC_Settings {
|
|
18 |
'force_unique_nicename' => false,
|
19 |
'disable_unused_author_pages' => false,
|
20 |
'block_tabnapping' => false,
|
|
|
21 |
);
|
22 |
}
|
23 |
}
|
18 |
'force_unique_nicename' => false,
|
19 |
'disable_unused_author_pages' => false,
|
20 |
'block_tabnapping' => false,
|
21 |
+
'valid_user_login_type' => 'both',
|
22 |
);
|
23 |
}
|
24 |
}
|
core/modules/wordpress-tweaks/setup.php
CHANGED
@@ -60,27 +60,29 @@ if ( ! class_exists( 'ITSEC_WordPress_Tweaks_Setup' ) ) {
|
|
60 |
* @return void
|
61 |
*/
|
62 |
public function execute_upgrade( $itsec_old_version ) {
|
|
|
63 |
|
64 |
-
if ( $itsec_old_version < 4000 ) {
|
65 |
|
|
|
66 |
global $itsec_bwps_options;
|
67 |
|
68 |
ITSEC_Lib::create_database_tables();
|
69 |
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
if (
|
74 |
-
$
|
75 |
-
|
76 |
-
|
77 |
-
$
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
ITSEC_Response::regenerate_wp_config();
|
82 |
}
|
83 |
|
|
|
|
|
84 |
}
|
85 |
|
86 |
if ( $itsec_old_version < 4035 ) {
|
@@ -88,59 +90,31 @@ if ( ! class_exists( 'ITSEC_WordPress_Tweaks_Setup' ) ) {
|
|
88 |
}
|
89 |
|
90 |
if ( $itsec_old_version < 4041 ) {
|
91 |
-
$
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
$new_module_settings = ITSEC_Modules::get_settings( 'wordpress-tweaks' );
|
96 |
-
|
97 |
-
// Reduce to only settings in new module
|
98 |
-
$current_options = array_intersect_key( $current_options, $new_module_settings );
|
99 |
-
|
100 |
-
// Use new module settings as defaults for any missing settings
|
101 |
-
$current_options = array_merge( $new_module_settings, $current_options );
|
102 |
-
|
103 |
-
// If anything in this module is being used activate it, otherwise deactivate it
|
104 |
-
$activate = false;
|
105 |
-
foreach ( $current_options as $setting => $on ) {
|
106 |
-
// False is actually "enabled" for blocking xmlrpc multiauth
|
107 |
-
if ( ( 'allow_xmlrpc_multiauth' !== $setting && $on ) || ( 'allow_xmlrpc_multiauth' === $setting && ! $on ) ) {
|
108 |
-
$activate = true;
|
109 |
-
break;
|
110 |
-
}
|
111 |
-
}
|
112 |
-
if ( $activate ) {
|
113 |
-
ITSEC_Modules::activate( 'wordpress-tweaks' );
|
114 |
-
} else {
|
115 |
-
ITSEC_Modules::deactivate( 'wordpress-tweaks' );
|
116 |
-
}
|
117 |
-
|
118 |
-
ITSEC_Modules::set_settings( 'wordpress-tweaks', $current_options );
|
119 |
}
|
|
|
|
|
|
|
120 |
}
|
121 |
|
122 |
if ( $itsec_old_version < 4050 ) {
|
123 |
-
|
124 |
-
|
125 |
-
if (
|
126 |
-
|
127 |
-
$settings['rest_api'] = 'default-access';
|
128 |
-
} else if ( in_array( $settings['rest_api'], array( 'disable', 'require-admin' ) ) ) {
|
129 |
-
$settings['rest_api'] = 'restrict-access';
|
130 |
-
}
|
131 |
-
|
132 |
-
ITSEC_Modules::set_settings( 'wordpress-tweaks', $settings );
|
133 |
}
|
134 |
}
|
135 |
|
136 |
if ( $itsec_old_version < 4073 ) {
|
137 |
-
$settings = ITSEC_Modules::get_settings( 'wordpress-tweaks' );
|
138 |
-
|
139 |
unset( $settings['safe_jquery'] );
|
140 |
unset( $settings['jquery_version'] );
|
141 |
-
|
142 |
-
ITSEC_Modules::set_settings( 'wordpress-tweaks', $settings );
|
143 |
}
|
|
|
|
|
|
|
144 |
}
|
145 |
|
146 |
}
|
60 |
* @return void
|
61 |
*/
|
62 |
public function execute_upgrade( $itsec_old_version ) {
|
63 |
+
$settings = ITSEC_Modules::get_settings( 'wordpress-tweaks' );
|
64 |
|
|
|
65 |
|
66 |
+
if ( $itsec_old_version < 4000 ) {
|
67 |
global $itsec_bwps_options;
|
68 |
|
69 |
ITSEC_Lib::create_database_tables();
|
70 |
|
71 |
+
if ( isset( $itsec_bwps_options['st_manifest'] ) && $itsec_bwps_options['st_manifest'] ) {
|
72 |
+
$settings['wlwmanifest_header'] = true;
|
73 |
+
}
|
74 |
+
if ( isset( $itsec_bwps_options['st_edituri'] ) && $itsec_bwps_options['st_edituri'] ) {
|
75 |
+
$settings['edituri_header'] = true;
|
76 |
+
}
|
77 |
+
if ( isset( $itsec_bwps_options['st_comment'] ) && $itsec_bwps_options['st_comment'] ) {
|
78 |
+
$settings['comment_spam'] = true;
|
79 |
+
}
|
80 |
+
if ( isset( $itsec_bwps_options['st_loginerror'] ) && $itsec_bwps_options['st_loginerror'] ) {
|
81 |
+
$settings['login_errors'] = true;
|
|
|
82 |
}
|
83 |
|
84 |
+
ITSEC_Response::regenerate_server_config();
|
85 |
+
ITSEC_Response::regenerate_wp_config();
|
86 |
}
|
87 |
|
88 |
if ( $itsec_old_version < 4035 ) {
|
90 |
}
|
91 |
|
92 |
if ( $itsec_old_version < 4041 ) {
|
93 |
+
$old_settings = get_site_option( 'itsec_tweaks' );
|
94 |
+
|
95 |
+
if ( is_array( $old_settings ) ) {
|
96 |
+
$settings = array_merge( $settings, $old_settings );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
97 |
}
|
98 |
+
} else {
|
99 |
+
// Time to get rid of the cruft.
|
100 |
+
delete_site_option( 'itsec_tweaks' );
|
101 |
}
|
102 |
|
103 |
if ( $itsec_old_version < 4050 ) {
|
104 |
+
if ( 'enable' === $settings['rest_api'] ) {
|
105 |
+
$settings['rest_api'] = 'default-access';
|
106 |
+
} else if ( in_array( $settings['rest_api'], array( 'disable', 'require-admin' ) ) ) {
|
107 |
+
$settings['rest_api'] = 'restrict-access';
|
|
|
|
|
|
|
|
|
|
|
|
|
108 |
}
|
109 |
}
|
110 |
|
111 |
if ( $itsec_old_version < 4073 ) {
|
|
|
|
|
112 |
unset( $settings['safe_jquery'] );
|
113 |
unset( $settings['jquery_version'] );
|
|
|
|
|
114 |
}
|
115 |
+
|
116 |
+
|
117 |
+
ITSEC_Modules::set_settings( 'wordpress-tweaks', $settings );
|
118 |
}
|
119 |
|
120 |
}
|
core/modules/wordpress-tweaks/validator.php
CHANGED
@@ -20,6 +20,7 @@ class ITSEC_WordPress_Tweaks_Validator extends ITSEC_Validator {
|
|
20 |
$this->sanitize_setting( 'bool', 'force_unique_nicename', __( 'Force Unique Nickname', 'better-wp-security' ) );
|
21 |
$this->sanitize_setting( 'bool', 'disable_unused_author_pages', __( 'Disable Extra User Archives', 'better-wp-security' ) );
|
22 |
$this->sanitize_setting( 'bool', 'block_tabnapping', __( 'Protect Against Tabnapping', 'better-wp-security' ) );
|
|
|
23 |
}
|
24 |
|
25 |
protected function validate_settings() {
|
20 |
$this->sanitize_setting( 'bool', 'force_unique_nicename', __( 'Force Unique Nickname', 'better-wp-security' ) );
|
21 |
$this->sanitize_setting( 'bool', 'disable_unused_author_pages', __( 'Disable Extra User Archives', 'better-wp-security' ) );
|
22 |
$this->sanitize_setting( 'bool', 'block_tabnapping', __( 'Protect Against Tabnapping', 'better-wp-security' ) );
|
23 |
+
$this->sanitize_setting( array( 'both', 'email', 'username' ), 'valid_user_login_type', __( 'Login with Email Address or Username', 'better-wp-security' ) );
|
24 |
}
|
25 |
|
26 |
protected function validate_settings() {
|
core/notify.php
CHANGED
@@ -49,21 +49,28 @@ class ITSEC_Notify {
|
|
49 |
return false;
|
50 |
}
|
51 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
52 |
if ( ! ITSEC_Lib::get_lock( 'daily-digest' ) ) {
|
53 |
return false;
|
54 |
}
|
55 |
|
56 |
if ( ! $use_cron ) {
|
57 |
-
|
58 |
-
$
|
59 |
-
ITSEC_Storage::reload();
|
60 |
-
$global->load();
|
61 |
-
|
62 |
-
$last_sent = $global->get('digest_last_sent' );
|
63 |
-
$yesterday = ITSEC_Core::get_current_time_gmt() - DAY_IN_SECONDS;
|
64 |
|
65 |
// Send digest if it has been 24 hours
|
66 |
if ( $last_sent > $yesterday ) {
|
|
|
67 |
return false;
|
68 |
}
|
69 |
}
|
@@ -75,6 +82,37 @@ class ITSEC_Notify {
|
|
75 |
return $result;
|
76 |
}
|
77 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
78 |
/**
|
79 |
* Send the daily digest email.
|
80 |
*
|
@@ -155,7 +193,7 @@ class ITSEC_Notify {
|
|
155 |
|
156 |
ITSEC_Modules::set_setting( 'global', 'digest_last_sent', ITSEC_Core::get_current_time_gmt() );
|
157 |
ITSEC_Modules::set_setting( 'global', 'digest_messages', array() );
|
158 |
-
|
159 |
|
160 |
$subject = esc_html__( 'Daily Security Digest', 'better-wp-security' );
|
161 |
$mail->set_subject( $subject );
|
49 |
return false;
|
50 |
}
|
51 |
|
52 |
+
// Check the cached digest_last_sent value. This will be fast but may be inaccurate.
|
53 |
+
if ( ! $use_cron ) {
|
54 |
+
$last_sent = ITSEC_Modules::get_setting( 'global', 'digest_last_sent' );
|
55 |
+
$yesterday = ITSEC_Core::get_current_time_gmt() - DAY_IN_SECONDS;
|
56 |
+
|
57 |
+
if ( $last_sent > $yesterday ) {
|
58 |
+
return false;
|
59 |
+
}
|
60 |
+
}
|
61 |
+
|
62 |
+
// Attempt to acquire a lock so only one process can send the daily digest at a time.
|
63 |
if ( ! ITSEC_Lib::get_lock( 'daily-digest' ) ) {
|
64 |
return false;
|
65 |
}
|
66 |
|
67 |
if ( ! $use_cron ) {
|
68 |
+
// This prevents errors where the last sent value is loaded in memory early in the request, before another process has finished sending the value.
|
69 |
+
$last_sent = $this->get_last_sent_uncached();
|
|
|
|
|
|
|
|
|
|
|
70 |
|
71 |
// Send digest if it has been 24 hours
|
72 |
if ( $last_sent > $yesterday ) {
|
73 |
+
|
74 |
return false;
|
75 |
}
|
76 |
}
|
82 |
return $result;
|
83 |
}
|
84 |
|
85 |
+
/**
|
86 |
+
* Get the time the daily digest was last sent directly from the database.
|
87 |
+
*
|
88 |
+
* @return int
|
89 |
+
*/
|
90 |
+
private function get_last_sent_uncached() {
|
91 |
+
|
92 |
+
/** @var $wpdb \wpdb */
|
93 |
+
global $wpdb;
|
94 |
+
|
95 |
+
$option = 'itsec-storage';
|
96 |
+
$storage = array();
|
97 |
+
|
98 |
+
if ( is_multisite() ) {
|
99 |
+
$network_id = get_current_site()->id;
|
100 |
+
$row = $wpdb->get_row( $wpdb->prepare( "SELECT meta_value FROM $wpdb->sitemeta WHERE meta_key = %s AND site_id = %d", $option, $network_id ) );
|
101 |
+
|
102 |
+
if ( is_object( $row ) ) {
|
103 |
+
$storage = maybe_unserialize( $row->meta_value );
|
104 |
+
}
|
105 |
+
} else {
|
106 |
+
$row = $wpdb->get_row( $wpdb->prepare( "SELECT option_value FROM $wpdb->options WHERE option_name = %s LIMIT 1", $option ) );
|
107 |
+
|
108 |
+
if ( is_object( $row ) ) {
|
109 |
+
$storage = maybe_unserialize( $row->option_value );
|
110 |
+
}
|
111 |
+
}
|
112 |
+
|
113 |
+
return isset( $storage['global'], $storage['global']['digest_last_sent'] ) ? $storage['global']['digest_last_sent'] : 0;
|
114 |
+
}
|
115 |
+
|
116 |
/**
|
117 |
* Send the daily digest email.
|
118 |
*
|
193 |
|
194 |
ITSEC_Modules::set_setting( 'global', 'digest_last_sent', ITSEC_Core::get_current_time_gmt() );
|
195 |
ITSEC_Modules::set_setting( 'global', 'digest_messages', array() );
|
196 |
+
ITSEC_Storage::save();
|
197 |
|
198 |
$subject = esc_html__( 'Daily Security Digest', 'better-wp-security' );
|
199 |
$mail->set_subject( $subject );
|
history.txt
CHANGED
@@ -680,3 +680,11 @@
|
|
680 |
6.5.1 - 2017-08-23 - Chris Jean & Timothy Jacobs
|
681 |
Bug Fix: Fixed logical error that prevented backups from executing.
|
682 |
Bug Fix: Fixed issue that could cause database locks to flood the database.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
680 |
6.5.1 - 2017-08-23 - Chris Jean & Timothy Jacobs
|
681 |
Bug Fix: Fixed logical error that prevented backups from executing.
|
682 |
Bug Fix: Fixed issue that could cause database locks to flood the database.
|
683 |
+
6.6.0 - 2017-09-06 - Chris Jean & Timothy Jacobs
|
684 |
+
New Feature: Added a new setting in WordPress Tweaks: "Login with Email Address or Username".
|
685 |
+
Enhancement: Host email images from the plugin instead of relying on iThemes servers to help email clients marking messages as spam or blocking images.
|
686 |
+
Bug Fix: Error when searching for modules preventing modules from appearing.
|
687 |
+
Bug Fix: Use the wp_options table when acquiring locks in Multisite.
|
688 |
+
Bug Fix: Prevent duplicate daily digest emails on sites with high load.
|
689 |
+
Misc: Added Magic Links, a new Pro-only feature, to be activated by Security Check.
|
690 |
+
Misc: Rearranged modules to be listed alphabetically.
|
readme.txt
CHANGED
@@ -3,7 +3,7 @@ Contributors: ithemes, chrisjean, gerroald, mattdanner, timothyblynjacobs
|
|
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.6
|
5 |
Tested up to: 4.8.1
|
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,15 @@ Free support may be available with the help of the community in the <a href="htt
|
|
188 |
|
189 |
== Changelog ==
|
190 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
191 |
= 6.5.1 =
|
192 |
* Bug Fix: Fixed logical error that prevented backups from executing.
|
193 |
* Bug Fix: Fixed issue that could cause database locks to flood the database.
|
@@ -358,5 +367,5 @@ Free support may be available with the help of the community in the <a href="htt
|
|
358 |
|
359 |
== Upgrade Notice ==
|
360 |
|
361 |
-
= 6.
|
362 |
-
Version 6.
|
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.6
|
5 |
Tested up to: 4.8.1
|
6 |
+
Stable tag: 6.6.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.6.0 =
|
192 |
+
* New Feature: Added a new setting in WordPress Tweaks: "Login with Email Address or Username".
|
193 |
+
* Enhancement: Host email images from the plugin instead of relying on iThemes servers to help email clients marking messages as spam or blocking images.
|
194 |
+
* Bug Fix: Error when searching for modules preventing modules from appearing.
|
195 |
+
* Bug Fix: Use the wp_options table when acquiring locks in Multisite.
|
196 |
+
* Bug Fix: Prevent duplicate daily digest emails on sites with high load.
|
197 |
+
* Misc: Added Magic Links, a new Pro-only feature, to be activated by Security Check.
|
198 |
+
* Misc: Rearranged modules to be listed alphabetically.
|
199 |
+
|
200 |
= 6.5.1 =
|
201 |
* Bug Fix: Fixed logical error that prevented backups from executing.
|
202 |
* Bug Fix: Fixed issue that could cause database locks to flood the database.
|
367 |
|
368 |
== Upgrade Notice ==
|
369 |
|
370 |
+
= 6.6.0 =
|
371 |
+
Version 6.6.0 contains important bug fixes. It is recommended for all users.
|