Version Description
- New Feature: iThemes Security now includes Security Check Pro to automatically and correctly determine your visitors IP addresses. Enable this scan by running Security Check and opting in to Security Check Pro or activate the Security Check Pro module in Advanced Modules. H/t Jeremy Voisin
- Enhancement: Run Security Check Pro IP Detection automatically once a day.
- Enhancement: Manually re-run Security Check Pro IP Detection from the Global Settings page.
Download this release
Release Info
Developer | TimothyBlynJacobs |
Plugin | iThemes Security (formerly Better WP Security) |
Version | 7.6.0 |
Comparing to | |
See all releases |
Code changes from version 7.5.0 to 7.6.0
- better-wp-security.php +1 -1
- core/admin-pages/js/settings.js +13 -0
- core/admin-pages/module-settings.php +12 -0
- core/admin-pages/page-settings.php +4 -0
- core/core.php +3 -1
- core/history.txt +6 -0
- core/lib.php +22 -64
- core/lib/class-itsec-ip-detector.php +119 -0
- core/lib/class-itsec-lib-ip-detector.php +98 -0
- core/modules.php +2 -1
- core/modules/global/css/index.php +1 -0
- core/modules/global/css/settings-page.css +15 -0
- core/modules/global/js/settings-page.js +106 -43
- core/modules/global/settings-page.php +260 -235
- core/modules/global/setup.php +12 -7
- core/modules/global/validator.php +33 -9
- core/modules/security-check-pro/activate.php +3 -0
- core/modules/security-check-pro/active.php +5 -0
- core/modules/security-check-pro/class-itsec-security-check-pro.php +82 -0
- core/modules/security-check-pro/deactivate.php +5 -0
- core/modules/security-check-pro/debug.php +60 -0
- core/modules/security-check-pro/index.php +1 -0
- core/modules/security-check-pro/js/debug.js +18 -0
- core/modules/security-check-pro/js/index.php +1 -0
- core/modules/security-check-pro/js/settings-page.js +106 -0
- core/modules/security-check-pro/privacy.php +15 -0
- core/modules/security-check-pro/settings-page.php +34 -0
- core/modules/security-check-pro/settings.php +20 -0
- core/modules/security-check-pro/utility.php +328 -0
- core/modules/security-check-pro/validator.php +43 -0
- core/modules/security-check/js/settings-page.js +2 -1
- core/modules/security-check/settings-page.php +40 -23
- core/package.json +3 -2
- core/response.php +9 -0
- history.txt +4 -0
- package.json +3 -2
- readme.txt +8 -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: 7.
|
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: 7.6.0
|
10 |
* Text Domain: better-wp-security
|
11 |
* Network: True
|
12 |
* License: GPLv2
|
core/admin-pages/js/settings.js
CHANGED
@@ -216,6 +216,19 @@ var itsecSettingsPage = {
|
|
216 |
itsecUtil.sendAJAXRequest( module, 'save', data, itsecSettingsPage.saveSettingsCallback );
|
217 |
},
|
218 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
219 |
saveSettingsCallback: function( results ) {
|
220 |
if ( '' === results.module ) {
|
221 |
jQuery( '#itsec-save' ).prop( 'disabled', false );
|
216 |
itsecUtil.sendAJAXRequest( module, 'save', data, itsecSettingsPage.saveSettingsCallback );
|
217 |
},
|
218 |
|
219 |
+
scrollTop: function() {
|
220 |
+
var $container = jQuery( '.itsec-module-cards-container' );
|
221 |
+
var view = $container.hasClass( 'grid' ) ? 'grid' : 'list';
|
222 |
+
|
223 |
+
if ( 'grid' === view ) {
|
224 |
+
$container.find( '.itsec-module-settings-content-container:visible' ).animate( { 'scrollTop': 0 }, 'fast' );
|
225 |
+
}
|
226 |
+
|
227 |
+
if ( 'list' === view ) {
|
228 |
+
jQuery( document ).scrollTop( 0 );
|
229 |
+
}
|
230 |
+
},
|
231 |
+
|
232 |
saveSettingsCallback: function( results ) {
|
233 |
if ( '' === results.module ) {
|
234 |
jQuery( '#itsec-save' ).prop( 'disabled', false );
|
core/admin-pages/module-settings.php
CHANGED
@@ -2,6 +2,18 @@
|
|
2 |
|
3 |
/**
|
4 |
* The iThemes Security Module Settings Page API parent class.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5 |
*/
|
6 |
class ITSEC_Module_Settings_Page {
|
7 |
/**
|
2 |
|
3 |
/**
|
4 |
* The iThemes Security Module Settings Page API parent class.
|
5 |
+
*
|
6 |
+
* @property-read string $id
|
7 |
+
* @property-read string $title
|
8 |
+
* @property-read string $description
|
9 |
+
* @property-read string $type
|
10 |
+
* @property-read string $pro
|
11 |
+
* @property-read bool $can_save
|
12 |
+
* @property-read bool $redraw_on_save
|
13 |
+
* @property-read bool $upsell
|
14 |
+
* @property-read string $upsell_url
|
15 |
+
* @property-read bool $information_only
|
16 |
+
* @property-read string $status
|
17 |
*/
|
18 |
class ITSEC_Module_Settings_Page {
|
19 |
/**
|
core/admin-pages/page-settings.php
CHANGED
@@ -5,7 +5,11 @@ final class ITSEC_Settings_Page {
|
|
5 |
private static $instance;
|
6 |
|
7 |
private $self_url = '';
|
|
|
|
|
8 |
private $modules = array();
|
|
|
|
|
9 |
private $widgets = array();
|
10 |
private $translations = array();
|
11 |
|
5 |
private static $instance;
|
6 |
|
7 |
private $self_url = '';
|
8 |
+
|
9 |
+
/** @var ITSEC_Module_Settings_Page[] */
|
10 |
private $modules = array();
|
11 |
+
|
12 |
+
/** @var ITSEC_Settings_Page_Sidebar_Widget[] */
|
13 |
private $widgets = array();
|
14 |
private $translations = array();
|
15 |
|
core/core.php
CHANGED
@@ -24,7 +24,7 @@ if ( ! class_exists( 'ITSEC_Core' ) ) {
|
|
24 |
*
|
25 |
* @access private
|
26 |
*/
|
27 |
-
private $plugin_build =
|
28 |
|
29 |
/**
|
30 |
* Used to distinguish between a user modifying settings and the API modifying settings (such as from Sync
|
@@ -297,6 +297,7 @@ if ( ! class_exists( 'ITSEC_Core' ) ) {
|
|
297 |
*/
|
298 |
public function register_events( $scheduler ) {
|
299 |
$scheduler->schedule( ITSEC_Scheduler::S_DAILY, 'clear-locks' );
|
|
|
300 |
}
|
301 |
|
302 |
/**
|
@@ -342,6 +343,7 @@ if ( ! class_exists( 'ITSEC_Core' ) ) {
|
|
342 |
ITSEC_Modules::register_module( 'file-writing', "$path/modules/file-writing", 'always-active' );
|
343 |
ITSEC_Modules::register_module( 'malware', "$path/modules/malware", 'always-active' );
|
344 |
ITSEC_Modules::register_module( 'feature-flags', "$path/modules/feature-flags", 'always-active' );
|
|
|
345 |
|
346 |
if ( ! ITSEC_Core::is_pro() ) {
|
347 |
ITSEC_Modules::register_module( 'pro-module-upsells', "$path/modules/pro", 'always-active' );
|
24 |
*
|
25 |
* @access private
|
26 |
*/
|
27 |
+
private $plugin_build = 4116;
|
28 |
|
29 |
/**
|
30 |
* Used to distinguish between a user modifying settings and the API modifying settings (such as from Sync
|
297 |
*/
|
298 |
public function register_events( $scheduler ) {
|
299 |
$scheduler->schedule( ITSEC_Scheduler::S_DAILY, 'clear-locks' );
|
300 |
+
$scheduler->schedule( ITSEC_Scheduler::S_DAILY, 'health-check' );
|
301 |
}
|
302 |
|
303 |
/**
|
343 |
ITSEC_Modules::register_module( 'file-writing', "$path/modules/file-writing", 'always-active' );
|
344 |
ITSEC_Modules::register_module( 'malware', "$path/modules/malware", 'always-active' );
|
345 |
ITSEC_Modules::register_module( 'feature-flags', "$path/modules/feature-flags", 'always-active' );
|
346 |
+
ITSEC_Modules::register_module( 'security-check-pro', "$path/modules/security-check-pro", self::is_pro() ? 'always-active' : 'default-inactive' );
|
347 |
|
348 |
if ( ! ITSEC_Core::is_pro() ) {
|
349 |
ITSEC_Modules::register_module( 'pro-module-upsells', "$path/modules/pro", 'always-active' );
|
core/history.txt
CHANGED
@@ -833,3 +833,9 @@
|
|
833 |
5.4.2 - 2019-11-14 - Timothy Jacobs
|
834 |
Tweak: Add stub Passwordless Login settings page.
|
835 |
Bug Fix: PHP warning if lockout_active field is missing.
|
|
|
|
|
|
|
|
|
|
|
|
833 |
5.4.2 - 2019-11-14 - Timothy Jacobs
|
834 |
Tweak: Add stub Passwordless Login settings page.
|
835 |
Bug Fix: PHP warning if lockout_active field is missing.
|
836 |
+
5.4.3 - 2019-11-18 - Timothy Jacobs
|
837 |
+
Tweak: Introduce ITSEC_Lib method to retrieve WP branch version.
|
838 |
+
5.5.0 - 2019-12-09 - Timothy Jacobs
|
839 |
+
New Feature: iThemes Security now includes Security Check Pro to automatically and correctly determine your visitors IP addresses. Enable this scan by running Security Check and opting in to Security Check Pro or activate the Security Check Pro module in Advanced Modules. H/t Jeremy Voisin
|
840 |
+
Enhancement: Run Security Check Pro IP Detection automatically once a day.
|
841 |
+
Enhancement: Manually re-run Security Check Pro IP Detection from the Global Settings page.
|
core/lib.php
CHANGED
@@ -160,6 +160,8 @@ final class ITSEC_Lib {
|
|
160 |
*
|
161 |
* @since 4.0.0
|
162 |
*
|
|
|
|
|
163 |
* @return String The IP address of the user
|
164 |
*/
|
165 |
public static function get_ip( $use_cache = true ) {
|
@@ -172,82 +174,23 @@ final class ITSEC_Lib {
|
|
172 |
if ( false !== $ip ) {
|
173 |
$ip = filter_var( $ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_RES_RANGE | FILTER_FLAG_NO_PRIV_RANGE );
|
174 |
|
175 |
-
if (
|
176 |
$GLOBALS['__itsec_remote_ip'] = $ip;
|
177 |
|
178 |
return $ip;
|
179 |
}
|
180 |
}
|
181 |
|
182 |
-
|
183 |
-
|
184 |
-
$headers = array(
|
185 |
-
'HTTP_CF_CONNECTING_IP', // CloudFlare
|
186 |
-
'HTTP_X_FORWARDED_FOR', // Squid and most other forward and reverse proxies
|
187 |
-
'REMOTE_ADDR', // Default source of remote IP
|
188 |
-
);
|
189 |
-
|
190 |
-
$headers = (array) apply_filters( 'itsec_filter_remote_addr_headers', $headers );
|
191 |
-
$proxy = ITSEC_Modules::get_setting( 'global', 'proxy' );
|
192 |
-
|
193 |
-
switch ( $proxy ) {
|
194 |
-
case 'disabled':
|
195 |
-
return $GLOBALS['__itsec_remote_ip'] = $_SERVER['REMOTE_ADDR'];
|
196 |
-
case 'manual':
|
197 |
-
$header = ITSEC_Modules::get_setting( 'global', 'proxy_header' );
|
198 |
-
|
199 |
-
if ( in_array( $header, $headers, true ) ) {
|
200 |
-
$headers = array( $header );
|
201 |
-
}
|
202 |
-
break;
|
203 |
-
}
|
204 |
-
|
205 |
-
if ( ! in_array( 'REMOTE_ADDR', $headers, true ) ) {
|
206 |
-
$headers[] = 'REMOTE_ADDR';
|
207 |
-
}
|
208 |
-
|
209 |
-
// Loop through twice. The first run won't accept a reserved or private range IP. If an acceptable IP is not
|
210 |
-
// found, try again while accepting reserved or private range IPs.
|
211 |
-
for ( $x = 0; $x < 2; $x ++ ) {
|
212 |
-
foreach ( $headers as $header ) {
|
213 |
-
if ( ! isset( $_SERVER[ $header ] ) ) {
|
214 |
-
continue;
|
215 |
-
}
|
216 |
-
|
217 |
-
$ip = trim( $_SERVER[ $header ] );
|
218 |
-
|
219 |
-
if ( empty( $ip ) ) {
|
220 |
-
continue;
|
221 |
-
}
|
222 |
-
|
223 |
-
if ( false !== ( $comma_index = strpos( $_SERVER[ $header ], ',' ) ) ) {
|
224 |
-
$ip = substr( $ip, 0, $comma_index );
|
225 |
-
}
|
226 |
-
|
227 |
-
if ( 0 === $x ) {
|
228 |
-
// First run through. Only accept an IP not in the reserved or private range.
|
229 |
-
$ip = filter_var( $ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_RES_RANGE | FILTER_FLAG_NO_PRIV_RANGE );
|
230 |
-
} else {
|
231 |
-
$ip = filter_var( $ip, FILTER_VALIDATE_IP );
|
232 |
-
}
|
233 |
-
|
234 |
-
if ( ! empty( $ip ) ) {
|
235 |
-
break;
|
236 |
-
}
|
237 |
-
}
|
238 |
-
|
239 |
-
if ( ! empty( $ip ) ) {
|
240 |
-
break;
|
241 |
-
}
|
242 |
-
}
|
243 |
|
244 |
-
if (
|
245 |
// If an IP is not found, force it to a localhost IP that would not be blacklisted as this typically
|
246 |
// indicates a local request that does not provide the localhost IP.
|
247 |
$ip = '127.0.0.1';
|
248 |
}
|
249 |
|
250 |
-
$GLOBALS['__itsec_remote_ip'] =
|
251 |
|
252 |
return $GLOBALS['__itsec_remote_ip'];
|
253 |
}
|
@@ -1882,4 +1825,19 @@ final class ITSEC_Lib {
|
|
1882 |
define( 'DONOTCACHEPAGE', true );
|
1883 |
}
|
1884 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1885 |
}
|
160 |
*
|
161 |
* @since 4.0.0
|
162 |
*
|
163 |
+
* @param bool $use_cache Whether to check the cache, or force the retrieval of a new value.
|
164 |
+
*
|
165 |
* @return String The IP address of the user
|
166 |
*/
|
167 |
public static function get_ip( $use_cache = true ) {
|
174 |
if ( false !== $ip ) {
|
175 |
$ip = filter_var( $ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_RES_RANGE | FILTER_FLAG_NO_PRIV_RANGE );
|
176 |
|
177 |
+
if ( $ip ) {
|
178 |
$GLOBALS['__itsec_remote_ip'] = $ip;
|
179 |
|
180 |
return $ip;
|
181 |
}
|
182 |
}
|
183 |
|
184 |
+
self::load( 'ip-detector' );
|
185 |
+
$ip = ITSEC_Lib_IP_Detector::build()->get();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
186 |
|
187 |
+
if ( ! $ip ) {
|
188 |
// If an IP is not found, force it to a localhost IP that would not be blacklisted as this typically
|
189 |
// indicates a local request that does not provide the localhost IP.
|
190 |
$ip = '127.0.0.1';
|
191 |
}
|
192 |
|
193 |
+
$GLOBALS['__itsec_remote_ip'] = $ip;
|
194 |
|
195 |
return $GLOBALS['__itsec_remote_ip'];
|
196 |
}
|
1825 |
define( 'DONOTCACHEPAGE', true );
|
1826 |
}
|
1827 |
}
|
1828 |
+
|
1829 |
+
/**
|
1830 |
+
* Get the WordPress branch version.
|
1831 |
+
*
|
1832 |
+
* @example 5.2.4 => 5.2
|
1833 |
+
*
|
1834 |
+
* @return string
|
1835 |
+
*/
|
1836 |
+
public static function get_wp_branch() {
|
1837 |
+
$version = get_bloginfo( 'version' );
|
1838 |
+
|
1839 |
+
list( $major, $minor ) = explode( '.', $version );
|
1840 |
+
|
1841 |
+
return $major . '.' . $minor;
|
1842 |
+
}
|
1843 |
}
|
core/lib/class-itsec-ip-detector.php
ADDED
@@ -0,0 +1,119 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Class ITSEC_IP_Detector
|
5 |
+
*
|
6 |
+
* @internal Use {@see ITSEC_Lib::get_ip()} instead of this class directly.
|
7 |
+
*/
|
8 |
+
class ITSEC_IP_Detector {
|
9 |
+
|
10 |
+
/** @var array */
|
11 |
+
private $server;
|
12 |
+
|
13 |
+
/** @var array */
|
14 |
+
private $headers = [];
|
15 |
+
|
16 |
+
/** @var bool */
|
17 |
+
private $allow_private = false;
|
18 |
+
|
19 |
+
/**
|
20 |
+
* ITSEC_IP_Detector constructor.
|
21 |
+
*
|
22 |
+
* A new detector instance should be created whenever you look for a new IP.
|
23 |
+
*
|
24 |
+
* @param array $server A copy of $_SERVER.
|
25 |
+
*/
|
26 |
+
public function __construct( array $server ) { $this->server = $server; }
|
27 |
+
|
28 |
+
/**
|
29 |
+
* Add a header to check for an IP.
|
30 |
+
*
|
31 |
+
* @param string $header The header name.
|
32 |
+
* @param int $position If multiple IPs are included in this header,
|
33 |
+
* the 0-based position of the IP to return.
|
34 |
+
*
|
35 |
+
* @return $this
|
36 |
+
*/
|
37 |
+
public function add_header( $header, $position = - 1 ) {
|
38 |
+
$this->headers[] = [ $header, $position ];
|
39 |
+
|
40 |
+
return $this;
|
41 |
+
}
|
42 |
+
|
43 |
+
/**
|
44 |
+
* Get the IP address for this request.
|
45 |
+
*
|
46 |
+
* @return string
|
47 |
+
*/
|
48 |
+
public function get() {
|
49 |
+
if ( $ip = $this->get_ip() ) {
|
50 |
+
return $ip;
|
51 |
+
}
|
52 |
+
|
53 |
+
$this->allow_private = true;
|
54 |
+
|
55 |
+
return $this->get_ip();
|
56 |
+
}
|
57 |
+
|
58 |
+
/**
|
59 |
+
* Get the IP given the current configuration.
|
60 |
+
*
|
61 |
+
* @return string
|
62 |
+
*/
|
63 |
+
private function get_ip() {
|
64 |
+
foreach ( $this->headers as list( $header, $position ) ) {
|
65 |
+
$ip = $this->get_for_header( $header, $position );
|
66 |
+
|
67 |
+
if ( ! $ip ) {
|
68 |
+
continue;
|
69 |
+
}
|
70 |
+
|
71 |
+
if ( $this->allow_private ) {
|
72 |
+
$ip = filter_var( $ip, FILTER_VALIDATE_IP );
|
73 |
+
} else {
|
74 |
+
$ip = filter_var( $ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_RES_RANGE | FILTER_FLAG_NO_PRIV_RANGE );
|
75 |
+
}
|
76 |
+
|
77 |
+
if ( $ip ) {
|
78 |
+
return (string) $ip;
|
79 |
+
}
|
80 |
+
}
|
81 |
+
|
82 |
+
return '';
|
83 |
+
}
|
84 |
+
|
85 |
+
/**
|
86 |
+
* Get the IP address for a header.
|
87 |
+
*
|
88 |
+
* @param string $header
|
89 |
+
* @param int $position
|
90 |
+
*
|
91 |
+
* @return string
|
92 |
+
*/
|
93 |
+
private function get_for_header( $header, $position ) {
|
94 |
+
if ( empty( $this->server[ $header ] ) ) {
|
95 |
+
return '';
|
96 |
+
}
|
97 |
+
|
98 |
+
$value = trim( $this->server[ $header ] );
|
99 |
+
|
100 |
+
if ( - 1 === $position ) {
|
101 |
+
return explode( ',', $value )[0];
|
102 |
+
}
|
103 |
+
|
104 |
+
// Handle Forwarded: header syntax https://tools.ietf.org/html/rfc7239#section-4
|
105 |
+
if ( preg_match_all( '{(?:for)=(?:"?\[?)([a-z0-9\.:_\-/]*)}i', $value, $matches, PREG_SET_ORDER ) ) {
|
106 |
+
if ( ! empty( $matches[ $position ][1] ) ) {
|
107 |
+
return $matches[ $position ][1];
|
108 |
+
}
|
109 |
+
}
|
110 |
+
|
111 |
+
$parts = preg_split( '/[, ]/', $value );
|
112 |
+
|
113 |
+
if ( ! empty( $parts[ $position ] ) ) {
|
114 |
+
return $parts[ $position ];
|
115 |
+
}
|
116 |
+
|
117 |
+
return '';
|
118 |
+
}
|
119 |
+
}
|
core/lib/class-itsec-lib-ip-detector.php
ADDED
@@ -0,0 +1,98 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
require_once( __DIR__ . '/class-itsec-ip-detector.php' );
|
4 |
+
|
5 |
+
/**
|
6 |
+
* Class ITSEC_Lib_IP_Detector
|
7 |
+
*
|
8 |
+
* @internal Use {@see ITSEC_Lib::get_ip()} instead of this class directly.
|
9 |
+
*/
|
10 |
+
class ITSEC_Lib_IP_Detector {
|
11 |
+
|
12 |
+
public static function get_proxy_types() {
|
13 |
+
$types = array(
|
14 |
+
'automatic' => esc_html__( 'Automatic', 'better-wp-security' ),
|
15 |
+
'manual' => esc_html__( 'Manual', 'better-wp-security' ),
|
16 |
+
'disabled' => esc_html__( 'Disabled', 'better-wp-security' ),
|
17 |
+
);
|
18 |
+
|
19 |
+
/**
|
20 |
+
* Filters the list of available proxy types.
|
21 |
+
*
|
22 |
+
* @param string[] $types List of available proxy types.
|
23 |
+
*/
|
24 |
+
return apply_filters( 'itsec_proxy_types', $types );
|
25 |
+
}
|
26 |
+
|
27 |
+
/**
|
28 |
+
* Get a list of the available proxy headers.
|
29 |
+
*
|
30 |
+
* @return string[]
|
31 |
+
*/
|
32 |
+
public static function get_proxy_headers() {
|
33 |
+
return apply_filters( 'itsec_filter_remote_addr_headers', array(
|
34 |
+
'HTTP_CF_CONNECTING_IP', // CloudFlare
|
35 |
+
'HTTP_X_FORWARDED_FOR', // Squid and most other forward and reverse proxies
|
36 |
+
) );
|
37 |
+
}
|
38 |
+
|
39 |
+
/**
|
40 |
+
* Build an IP detector instance from the configured settings.
|
41 |
+
*
|
42 |
+
* @return ITSEC_IP_Detector
|
43 |
+
*/
|
44 |
+
public static function build() {
|
45 |
+
$proxy = ITSEC_Modules::get_setting( 'global', 'proxy' );
|
46 |
+
|
47 |
+
return self::build_for_type( $proxy );
|
48 |
+
}
|
49 |
+
|
50 |
+
/**
|
51 |
+
* Build a detector for a given proxy type and args.
|
52 |
+
*
|
53 |
+
* @param string $proxy
|
54 |
+
* @param array $args
|
55 |
+
*
|
56 |
+
* @return ITSEC_IP_Detector
|
57 |
+
*/
|
58 |
+
public static function build_for_type( $proxy, array $args = [] ) {
|
59 |
+
$detector = new ITSEC_IP_Detector( $_SERVER );
|
60 |
+
|
61 |
+
$headers = self::get_proxy_headers();
|
62 |
+
|
63 |
+
/**
|
64 |
+
* Fires when a new IP detector is used.
|
65 |
+
*
|
66 |
+
* The dynamic portion of the hook name, `$proxy`, refers to the proxy type.
|
67 |
+
*
|
68 |
+
* @param bool $configured Was the detector configured.
|
69 |
+
* @param ITSEC_IP_Detector $detector The IP detector.
|
70 |
+
* @param array $args Additional args to customize the behavior.
|
71 |
+
*/
|
72 |
+
$configured = apply_filters( "itsec_build_ip_detector_for_{$proxy}", false, $detector, $args );
|
73 |
+
|
74 |
+
if ( ! $configured ) {
|
75 |
+
switch ( $proxy ) {
|
76 |
+
case 'disabled':
|
77 |
+
break;
|
78 |
+
case 'manual':
|
79 |
+
$header = empty( $args['header'] ) ? ITSEC_Modules::get_setting( 'global', 'proxy_header' ) : $args['header'];
|
80 |
+
|
81 |
+
if ( in_array( $header, $headers, true ) ) {
|
82 |
+
$detector->add_header( $header );
|
83 |
+
}
|
84 |
+
break;
|
85 |
+
case 'automatic':
|
86 |
+
default:
|
87 |
+
foreach ( $headers as $header ) {
|
88 |
+
$detector->add_header( $header );
|
89 |
+
}
|
90 |
+
break;
|
91 |
+
}
|
92 |
+
}
|
93 |
+
|
94 |
+
$detector->add_header( 'REMOTE_ADDR' );
|
95 |
+
|
96 |
+
return $detector;
|
97 |
+
}
|
98 |
+
}
|
core/modules.php
CHANGED
@@ -251,7 +251,8 @@ final class ITSEC_Modules {
|
|
251 |
/**
|
252 |
* Update a single setting in a module.
|
253 |
*
|
254 |
-
* The new value will be validated
|
|
|
255 |
*
|
256 |
* @param string $slug The module slug.
|
257 |
* @param string $name The setting name to updated.
|
251 |
/**
|
252 |
* Update a single setting in a module.
|
253 |
*
|
254 |
+
* The new value will be validated and updated in memory. The change isn't persisted until
|
255 |
+
* the end of the request or a manual call to {@see ITSEC_Storage::save()}.
|
256 |
*
|
257 |
* @param string $slug The module slug.
|
258 |
* @param string $name The setting name to updated.
|
core/modules/global/css/index.php
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
<?php // Silence is golden.
|
core/modules/global/css/settings-page.css
ADDED
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
.itsec-global-proxy-wrapper {
|
2 |
+
margin: 1em 0;
|
3 |
+
}
|
4 |
+
|
5 |
+
.itsec-global-proxy-wrapper #itsec-global-proxy {
|
6 |
+
margin: 0 !important;
|
7 |
+
}
|
8 |
+
|
9 |
+
.itsec-global-detected-ip {
|
10 |
+
background: #edeff0;
|
11 |
+
color: #23282d;
|
12 |
+
padding: 10px 20px;
|
13 |
+
border-radius: 14px;
|
14 |
+
max-width: max-content;
|
15 |
+
}
|
core/modules/global/js/settings-page.js
CHANGED
@@ -1,5 +1,5 @@
|
|
1 |
function itsec_change_show_error_codes( args ) {
|
2 |
-
var show = args[0];
|
3 |
|
4 |
if ( show ) {
|
5 |
jQuery( 'body' ).addClass( 'itsec-show-error-codes' );
|
@@ -9,7 +9,7 @@ function itsec_change_show_error_codes( args ) {
|
|
9 |
}
|
10 |
|
11 |
function itsec_change_write_files( args ) {
|
12 |
-
var enabled = args[0];
|
13 |
|
14 |
if ( enabled ) {
|
15 |
jQuery( 'body' ).removeClass( 'itsec-write-files-disabled' ).addClass( 'itsec-write-files-enabled' );
|
@@ -18,55 +18,118 @@ function itsec_change_write_files( args ) {
|
|
18 |
}
|
19 |
}
|
20 |
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
|
|
|
|
36 |
}
|
37 |
-
};
|
38 |
|
39 |
-
|
40 |
-
|
41 |
|
42 |
-
|
43 |
-
|
|
|
|
|
|
|
44 |
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
|
51 |
-
|
52 |
-
|
53 |
|
54 |
-
|
55 |
-
|
|
|
|
|
56 |
|
57 |
-
|
|
|
|
|
|
|
|
|
58 |
|
59 |
-
|
|
|
|
|
|
|
|
|
60 |
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
|
|
|
|
|
|
|
|
67 |
}
|
68 |
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
function itsec_change_show_error_codes( args ) {
|
2 |
+
var show = args[ 0 ];
|
3 |
|
4 |
if ( show ) {
|
5 |
jQuery( 'body' ).addClass( 'itsec-show-error-codes' );
|
9 |
}
|
10 |
|
11 |
function itsec_change_write_files( args ) {
|
12 |
+
var enabled = args[ 0 ];
|
13 |
|
14 |
if ( enabled ) {
|
15 |
jQuery( 'body' ).removeClass( 'itsec-write-files-disabled' ).addClass( 'itsec-write-files-enabled' );
|
18 |
}
|
19 |
}
|
20 |
|
21 |
+
( function( $ ) {
|
22 |
+
function logTypeChanged() {
|
23 |
+
var type = jQuery( '#itsec-global-log_type' ).val();
|
24 |
+
|
25 |
+
if ( 'both' === type ) {
|
26 |
+
jQuery( '#itsec-global-log_rotation' ).parents( 'tr' ).show();
|
27 |
+
jQuery( '#itsec-global-file_log_rotation' ).parents( 'tr' ).show();
|
28 |
+
jQuery( '#itsec-global-log_location' ).parents( 'tr' ).show();
|
29 |
+
} else if ( 'file' === type ) {
|
30 |
+
jQuery( '#itsec-global-log_rotation' ).parents( 'tr' ).hide();
|
31 |
+
jQuery( '#itsec-global-file_log_rotation' ).parents( 'tr' ).show();
|
32 |
+
jQuery( '#itsec-global-log_location' ).parents( 'tr' ).show();
|
33 |
+
} else {
|
34 |
+
jQuery( '#itsec-global-log_rotation' ).parents( 'tr' ).show();
|
35 |
+
jQuery( '#itsec-global-file_log_rotation' ).parents( 'tr' ).hide();
|
36 |
+
jQuery( '#itsec-global-log_location' ).parents( 'tr' ).hide();
|
37 |
+
}
|
38 |
}
|
|
|
39 |
|
40 |
+
function proxyHeaderChanged() {
|
41 |
+
var proxy = $( '#itsec-global-proxy' ).val();
|
42 |
|
43 |
+
if ( 'security-check' === proxy ) {
|
44 |
+
$( '#itsec-global-ip-scan' ).show();
|
45 |
+
} else {
|
46 |
+
$( '#itsec-global-ip-scan' ).hide();
|
47 |
+
}
|
48 |
|
49 |
+
if ( 'manual' === proxy ) {
|
50 |
+
$( '.itsec-global-proxy_header-container' ).show();
|
51 |
+
} else {
|
52 |
+
$( '.itsec-global-proxy_header-container' ).hide();
|
53 |
+
}
|
54 |
|
55 |
+
updateIp();
|
56 |
+
}
|
57 |
|
58 |
+
function updateIp() {
|
59 |
+
$( '.itsec-global-detected-ip' ).text( itsec_global_settings_page.l10n.loading );
|
60 |
+
var proxyType = $( '#itsec-global-proxy' ).val();
|
61 |
+
var args = {};
|
62 |
|
63 |
+
switch ( proxyType ) {
|
64 |
+
case 'manual':
|
65 |
+
args.header = $( '#itsec-global-proxy_header' ).val();
|
66 |
+
break;
|
67 |
+
}
|
68 |
|
69 |
+
var data = {
|
70 |
+
method: 'get-ip',
|
71 |
+
proxy : proxyType,
|
72 |
+
args : args,
|
73 |
+
};
|
74 |
|
75 |
+
itsecUtil.sendModuleAJAXRequest( 'global', data, function( r ) {
|
76 |
+
if ( r.errors.length > 0 ) {
|
77 |
+
itsecSettingsPage.showErrors( r.errors, 'global', 'open', 'error' );
|
78 |
+
itsecSettingsPage.scrollTop();
|
79 |
+
}
|
80 |
+
|
81 |
+
if ( r.response ) {
|
82 |
+
$( '.itsec-global-detected-ip' ).text( r.response.ip_l10n );
|
83 |
+
}
|
84 |
+
} );
|
85 |
}
|
86 |
|
87 |
+
$( function() {
|
88 |
+
$( document ).on( 'click', '#itsec-global-add-to-whitelist', function( e ) {
|
89 |
+
e.preventDefault();
|
90 |
+
|
91 |
+
var $whitelist = $( '#itsec-global-lockout_white_list' ),
|
92 |
+
whitelist = $whitelist.val().trim();
|
93 |
+
whitelist += '\n' + itsec_global_settings_page.ip;
|
94 |
+
$whitelist.val( whitelist );
|
95 |
+
} );
|
96 |
+
|
97 |
+
$( document ).on( 'click', '#itsec-global-reset-log-location', function( e ) {
|
98 |
+
e.preventDefault();
|
99 |
+
|
100 |
+
$( '#itsec-global-log_location' ).val( itsec_global_settings_page.log_location );
|
101 |
+
} );
|
102 |
+
|
103 |
+
$( document ).on( 'click', '#itsec-global-ip-scan', function( e ) {
|
104 |
+
e.preventDefault();
|
105 |
+
|
106 |
+
var $btn = $( this ).attr( 'disabled', true );
|
107 |
+
|
108 |
+
itsecUtil.sendModuleAJAXRequest( 'global', { method: 'scan-ip' }, function( r ) {
|
109 |
+
if ( r.errors.length > 0 ) {
|
110 |
+
itsecSettingsPage.showErrors( r.errors, 'global', 'open', 'error' );
|
111 |
+
itsecSettingsPage.scrollTop();
|
112 |
+
}
|
113 |
+
|
114 |
+
if ( r.response ) {
|
115 |
+
$( '.itsec-global-detected-ip' ).text( r.response.ip_l10n );
|
116 |
+
}
|
117 |
+
|
118 |
+
$btn.attr( 'disabled', false );
|
119 |
+
} );
|
120 |
+
} );
|
121 |
+
|
122 |
+
$( document ).on( 'change', '#itsec-global-log_type', logTypeChanged );
|
123 |
+
$( document ).on( 'change', '#itsec-global-proxy', proxyHeaderChanged );
|
124 |
+
$( document ).on( 'change', '#itsec-global-proxy_header', updateIp );
|
125 |
+
itsecSettingsPage.events.on( 'modulesReloaded', proxyHeaderChanged );
|
126 |
+
itsecSettingsPage.events.on( 'moduleReloaded', function( e, module ) {
|
127 |
+
if ( 'global' === module ) {
|
128 |
+
proxyHeaderChanged();
|
129 |
+
}
|
130 |
+
} );
|
131 |
+
|
132 |
+
logTypeChanged();
|
133 |
+
proxyHeaderChanged();
|
134 |
+
} );
|
135 |
+
} )( jQuery );
|
core/modules/global/settings-page.php
CHANGED
@@ -1,14 +1,13 @@
|
|
1 |
<?php
|
2 |
|
3 |
final class ITSEC_Global_Settings_Page extends ITSEC_Module_Settings_Page {
|
4 |
-
private $version =
|
5 |
-
|
6 |
|
7 |
public function __construct() {
|
8 |
-
$this->id
|
9 |
-
$this->title
|
10 |
$this->description = __( 'Configure basic settings that control how iThemes Security functions.', 'better-wp-security' );
|
11 |
-
$this->type
|
12 |
|
13 |
parent::__construct();
|
14 |
|
@@ -35,10 +34,14 @@ final class ITSEC_Global_Settings_Page extends ITSEC_Module_Settings_Page {
|
|
35 |
$vars = array(
|
36 |
'ip' => ITSEC_Lib::get_ip(),
|
37 |
'log_location' => ITSEC_Modules::get_default( $this->id, 'log_location' ),
|
|
|
|
|
|
|
38 |
);
|
39 |
|
40 |
-
wp_enqueue_script( 'itsec-global-settings-page-script', plugins_url( 'js/settings-page.js', __FILE__ ), array( 'jquery', 'itsec-settings-page-script' ), $this->version, true );
|
41 |
wp_localize_script( 'itsec-global-settings-page-script', 'itsec_global_settings_page', $vars );
|
|
|
42 |
}
|
43 |
|
44 |
public function handle_form_post( $data ) {
|
@@ -55,15 +58,64 @@ final class ITSEC_Global_Settings_Page extends ITSEC_Module_Settings_Page {
|
|
55 |
}
|
56 |
}
|
57 |
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
63 |
|
|
|
|
|
|
|
|
|
64 |
}
|
65 |
|
66 |
protected function render_settings( $form ) {
|
|
|
67 |
$validator = ITSEC_Modules::get_validator( $this->id );
|
68 |
|
69 |
$log_types = $validator->get_valid_log_types();
|
@@ -80,247 +132,220 @@ final class ITSEC_Global_Settings_Page extends ITSEC_Module_Settings_Page {
|
|
80 |
|
81 |
$proxy = array( 'value' => $validator->get_proxy_types() );
|
82 |
|
83 |
-
|
84 |
-
$proxy['disabled'] = true;
|
85 |
-
}
|
86 |
-
|
87 |
-
$possible_headers = apply_filters( 'itsec_filter_remote_addr_headers', array(
|
88 |
-
'HTTP_CF_CONNECTING_IP', // CloudFlare
|
89 |
-
'HTTP_X_FORWARDED_FOR', // Squid and most other forward and reverse proxies
|
90 |
-
'REMOTE_ADDR', // Default source of remote IP
|
91 |
-
) );
|
92 |
-
|
93 |
-
$ucwords = version_compare( phpversion(), '5.5.16', '>=' ) || ( version_compare( phpversion(), '5.4.32', '>=' ) && version_compare( phpversion(), '5.5.0', '<' ) );
|
94 |
-
$proxy_header_opt = array();
|
95 |
-
|
96 |
-
foreach ( $possible_headers as $header ) {
|
97 |
-
$label = $header;
|
98 |
|
99 |
-
|
100 |
-
|
101 |
-
}
|
102 |
-
|
103 |
-
$label = str_replace( '_', '-', $label );
|
104 |
-
$label = strtolower( $label );
|
105 |
-
$label = $ucwords ? ucwords( $label, '-' ) : implode( '-', array_map( 'ucfirst', explode( '-', $label ) ) );
|
106 |
-
|
107 |
-
if ( isset( $_SERVER[ $header ] ) ) {
|
108 |
-
$label .= ' (' . esc_attr( $_SERVER[ $header ] ) . ')';
|
109 |
-
}
|
110 |
-
|
111 |
-
$label = str_replace('Ip', 'IP', $label );
|
112 |
-
|
113 |
-
$proxy_header_opt[ $header ] = $label;
|
114 |
-
}
|
115 |
-
|
116 |
-
?>
|
117 |
-
<table class="form-table itsec-settings-section">
|
118 |
-
<tr>
|
119 |
-
<th scope="row"><label for="itsec-global-write_files"><?php _e( 'Write to Files', 'better-wp-security' ); ?></label></th>
|
120 |
-
<td>
|
121 |
-
<?php $form->add_checkbox( 'write_files' ); ?>
|
122 |
-
<label for="itsec-global-write_files"><?php _e( 'Allow iThemes Security to write to wp-config.php and .htaccess.', 'better-wp-security' ); ?></label>
|
123 |
-
<p class="description"><?php _e( 'Whether or not iThemes Security should be allowed to write to wp-config.php and .htaccess automatically. If disabled you will need to manually place configuration options in those files.', 'better-wp-security' ); ?></p>
|
124 |
-
</td>
|
125 |
-
</tr>
|
126 |
-
<tr>
|
127 |
-
<th scope="row"><label for="itsec-global-lockout_message"><?php _e( 'Host Lockout Message', 'better-wp-security' ); ?></label></th>
|
128 |
-
<td>
|
129 |
-
<?php $form->add_textarea( 'lockout_message', array( 'class' => 'widefat' ) ); ?>
|
130 |
-
<p class="description"><?php _e( 'The message to display when a computer (host) has been locked out.', 'better-wp-security' ); ?></p>
|
131 |
-
<p class="description"><?php _e( 'You can use HTML in your message. Allowed tags include: a, br, em, strong, h1, h2, h3, h4, h5, h6, div.', 'better-wp-security' ); ?></p>
|
132 |
-
</td>
|
133 |
-
</tr>
|
134 |
-
<tr>
|
135 |
-
<th scope="row"><label for="itsec-global-user_lockout_message"><?php _e( 'User Lockout Message', 'better-wp-security' ); ?></label></th>
|
136 |
-
<td>
|
137 |
-
<?php $form->add_textarea( 'user_lockout_message', array( 'class' => 'widefat' ) ); ?>
|
138 |
-
<p class="description"><?php _e( 'The message to display to a user when their account has been locked out.', 'better-wp-security' ); ?></p>
|
139 |
-
<p class="description"><?php _e( 'You can use HTML in your message. Allowed tags include: a, br, em, strong, h1, h2, h3, h4, h5, h6, div.', 'better-wp-security' ); ?></p>
|
140 |
-
</td>
|
141 |
-
</tr>
|
142 |
-
<tr>
|
143 |
-
<th scope="row"><label for="itsec-global-community_lockout_message"><?php _e( 'Community Lockout Message', 'better-wp-security' ); ?></label></th>
|
144 |
-
<td>
|
145 |
-
<?php $form->add_textarea( 'community_lockout_message', array( 'class' => 'widefat' ) ); ?>
|
146 |
-
<p class="description"><?php _e( 'The message to display to a user when their IP has been flagged as bad by the iThemes network.', 'better-wp-security' ); ?></p>
|
147 |
-
<p class="description"><?php _e( 'You can use HTML in your message. Allowed tags include: a, br, em, strong, h1, h2, h3, h4, h5, h6, div.', 'better-wp-security' ); ?></p>
|
148 |
-
</td>
|
149 |
-
</tr>
|
150 |
-
<tr>
|
151 |
-
<th scope="row"><label for="itsec-global-blacklist"><?php _e( 'Blacklist Repeat Offender', 'better-wp-security' ); ?></label></th>
|
152 |
-
<td>
|
153 |
-
<?php $form->add_checkbox( 'blacklist' ); ?>
|
154 |
-
<label for="itsec-global-blacklist"><?php _e( 'Enable Blacklist Repeat Offender', 'better-wp-security' ); ?></label>
|
155 |
-
<p class="description"><?php _e( 'If this box is checked the IP address of the offending computer will be added to the "Ban Users" blacklist after reaching the number of lockouts listed below.', 'better-wp-security' ); ?></p>
|
156 |
-
</td>
|
157 |
-
</tr>
|
158 |
-
<tr>
|
159 |
-
<th scope="row"><label for="itsec-global-blacklist_count"><?php _e( 'Blacklist Threshold', 'better-wp-security' ); ?></label></th>
|
160 |
-
<td>
|
161 |
-
<?php $form->add_text( 'blacklist_count', array( 'class' => 'small-text' ) ); ?>
|
162 |
-
<label for="itsec-global-blacklist_count"><?php _e( 'Lockouts', 'better-wp-security' ); ?></label>
|
163 |
-
<p class="description"><?php _e( 'The number of lockouts per IP before the host is banned permanently from this site.', 'better-wp-security' ); ?></p>
|
164 |
-
</td>
|
165 |
-
</tr>
|
166 |
-
<tr>
|
167 |
-
<th scope="row"><label for="itsec-global-blacklist_period"><?php _e( 'Blacklist Lookback Period', 'better-wp-security' ); ?></label></th>
|
168 |
-
<td>
|
169 |
-
<?php $form->add_text( 'blacklist_period', array( 'class' => 'small-text' ) ); ?>
|
170 |
-
<label for="itsec-global-blacklist_period"><?php _e( 'Days', 'better-wp-security' ); ?></label>
|
171 |
-
<p class="description"><?php _e( 'How many days should a lockout be remembered to meet the blacklist count above.', 'better-wp-security' ); ?></p>
|
172 |
-
</td>
|
173 |
-
</tr>
|
174 |
-
<tr>
|
175 |
-
<th scope="row"><label for="itsec-global-lockout_period"><?php _e( 'Lockout Period', 'better-wp-security' ); ?></label></th>
|
176 |
-
<td>
|
177 |
-
<?php $form->add_text( 'lockout_period', array( 'class' => 'small-text' ) ); ?>
|
178 |
-
<label for="itsec-global-lockout_period"><?php _e( 'Minutes', 'better-wp-security' ); ?></label>
|
179 |
-
<p class="description"><?php _e( 'The length of time a host or user will be banned from this site after hitting the limit of bad logins. The default setting of 15 minutes is recommended as increasing it could prevent attacking IP addresses from being added to the blacklist.', 'better-wp-security' ); ?></p>
|
180 |
-
</td>
|
181 |
-
</tr>
|
182 |
-
<tr>
|
183 |
-
<th scope="row"><label for="itsec-global-lockout_white_list"><?php _e( 'Lockout White List', 'better-wp-security' ); ?></label></th>
|
184 |
-
<td>
|
185 |
-
<?php $form->add_textarea( 'lockout_white_list' ); ?>
|
186 |
-
<p><?php $form->add_button( 'add-to-whitelist', array( 'value' => __( 'Add my current IP to the White List', 'better-wp-security' ), 'class' => 'button-primary' ) ); ?></p>
|
187 |
-
<p class="description"><?php _e( 'Use the guidelines below to enter hosts that will not be locked out from your site. This will keep you from locking yourself out of any features if you should trigger a lockout. Please note this does not override away mode and will only prevent a temporary ban. Should a permanent ban be triggered you will still be added to the "Ban Users" list unless the IP address is also white listed in that section.', 'better-wp-security' ); ?></p>
|
188 |
-
<ul>
|
189 |
-
<li>
|
190 |
-
<?php _e( 'You may white list users by individual IP address or IP address range using wildcards or CIDR notation.', 'better-wp-security' ); ?>
|
191 |
-
<ul>
|
192 |
-
<li><?php _e( 'Individual IP addresses must be in IPv4 or IPv6 standard format (###.###.###.### or ####:####:####:####:####:####:####:####).', 'better-wp-security' ); ?></li>
|
193 |
-
<li><?php _e( 'CIDR notation is allowed to specify a range of IP addresses (###.###.###.###/## or ####:####:####:####:####:####:####:####/###).', 'better-wp-security' ); ?></li>
|
194 |
-
<li><?php _e( 'Wildcards are also supported with some limitations. If using wildcards (*), you must start with the right-most chunk in the IP address. For example ###.###.###.* and ###.###.*.* are permitted but ###.###.*.### is not. Wildcards are only for convenient entering of IP addresses, and will be automatically converted to their appropriate CIDR notation format on save.', 'better-wp-security' ); ?></li>
|
195 |
-
</ul>
|
196 |
-
</li>
|
197 |
-
<li><?php _e( 'Enter only 1 IP address or 1 IP address range per line.', 'better-wp-security' ); ?></li>
|
198 |
-
</ul>
|
199 |
-
<p><a href="<?php echo esc_url( ITSEC_Lib::get_trace_ip_link() ); ?>" target="_blank" rel="noopener noreferrer"><?php _e( 'Lookup IP Address.', 'better-wp-security' ); ?></a></p>
|
200 |
-
<p class="description"><strong><?php _e( 'This white list will prevent any IP listed from triggering an automatic lockout. You can still block the IP address manually in the banned users settings.', 'better-wp-security' ); ?></strong></p>
|
201 |
-
</td>
|
202 |
-
</tr>
|
203 |
-
<tr>
|
204 |
-
<th scope="row"><label for="itsec-global-log_type"><?php _e( 'Log Type', 'better-wp-security' ); ?></label></th>
|
205 |
-
<td>
|
206 |
-
<?php $form->add_select( 'log_type', $log_types ); ?>
|
207 |
-
<label for="itsec-global-log_type"><?php _e( 'How should event logs be kept', 'better-wp-security' ); ?></label>
|
208 |
-
<p class="description"><?php _e( 'iThemes Security can log events in multiple ways, each with advantages and disadvantages. Database Only puts all events in the database with your posts and other WordPress data. This makes it easy to retrieve and process but can be slower if the database table gets very large. File Only is very fast but the plugin does not process the logs itself as that would take far more resources. For most users or smaller sites Database Only should be fine. If you have a very large site or a log processing software then File Only might be a better option.', 'better-wp-security' ); ?></p>
|
209 |
-
</td>
|
210 |
-
</tr>
|
211 |
-
<tr>
|
212 |
-
<th scope="row"><label for="itsec-global-log_rotation"><?php _e( 'Days to Keep Database Logs', 'better-wp-security' ); ?></label></th>
|
213 |
-
<td>
|
214 |
-
<?php $form->add_text( 'log_rotation', array( 'class' => 'small-text' ) ); ?>
|
215 |
-
<label for="itsec-global-log_rotation"><?php _e( 'Days', 'better-wp-security' ); ?></label>
|
216 |
-
<p class="description"><?php _e( 'The number of days database logs should be kept.', 'better-wp-security' ); ?></p>
|
217 |
-
</td>
|
218 |
-
</tr>
|
219 |
-
<tr>
|
220 |
-
<th scope="row"><label for="itsec-global-file_log_rotation"><?php _e( 'Days to Keep File Logs', 'better-wp-security' ); ?></label></th>
|
221 |
-
<td>
|
222 |
-
<?php $form->add_text( 'file_log_rotation', array( 'class' => 'small-text' ) ); ?>
|
223 |
-
<label for="itsec-global-log_rotation"><?php _e( 'Days', 'better-wp-security' ); ?></label>
|
224 |
-
<p class="description"><?php _e( 'The number of days file logs should be kept. File logs will additionally be rotated once the file hits 10MB. Set to 0 to only use log rotation.', 'better-wp-security' ); ?></p>
|
225 |
-
</td>
|
226 |
-
</tr>
|
227 |
-
<tr>
|
228 |
-
<th scope="row"><label for="itsec-global-log_location"><?php _e( 'Path to Log Files', 'better-wp-security' ); ?></label></th>
|
229 |
-
<td>
|
230 |
-
<?php $form->add_text( 'log_location', array( 'class' => 'large-text code' ) ); ?>
|
231 |
-
<p><label for="itsec-global-log_location"><?php _e( 'The path on your server where log files should be stored.', 'better-wp-security' ); ?></label></p>
|
232 |
-
<p class="description"><?php _e( 'This path must be writable by your website. For added security, it is recommended you do not include it in your website root folder.', 'better-wp-security' ); ?></p>
|
233 |
-
<p><?php $form->add_button( 'reset-log-location', array( 'value' => __( 'Restore Default Log File Path', 'better-wp-security' ), 'class' => 'button-secondary' ) ); ?></p>
|
234 |
-
</td>
|
235 |
-
</tr>
|
236 |
-
<?php if ( is_dir( WP_PLUGIN_DIR . '/iwp-client' ) ) : ?>
|
237 |
<tr>
|
238 |
-
<th scope="row"><label for="itsec-global-
|
239 |
<td>
|
240 |
-
<?php $form->add_checkbox( '
|
241 |
-
<label for="itsec-global-
|
242 |
-
<p class="description"><?php
|
243 |
</td>
|
244 |
</tr>
|
245 |
-
<?php endif; ?>
|
246 |
-
<tr>
|
247 |
-
<th scope="row"><label for="itsec-global-allow_tracking"><?php _e( 'Allow Data Tracking', 'better-wp-security' ); ?></label></th>
|
248 |
-
<td>
|
249 |
-
<?php $form->add_checkbox( 'allow_tracking' ); ?>
|
250 |
-
<label for="itsec-global-allow_tracking"><?php _e( 'Allow iThemes to track plugin usage via anonymous data.', 'better-wp-security' ); ?></label>
|
251 |
-
</td>
|
252 |
-
</tr>
|
253 |
-
<?php if ( 'nginx' === ITSEC_Lib::get_server() ) : ?>
|
254 |
<tr>
|
255 |
-
<th scope="row"><label for="itsec-global-
|
256 |
<td>
|
257 |
-
<?php $form->
|
258 |
-
<p
|
259 |
-
<p class="description"><?php _e( '
|
260 |
</td>
|
261 |
</tr>
|
262 |
-
|
263 |
-
|
264 |
-
|
265 |
-
|
266 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
267 |
<p class="description">
|
268 |
-
|
269 |
</p>
|
270 |
-
|
271 |
-
|
272 |
-
|
273 |
-
|
274 |
-
|
275 |
-
|
276 |
-
|
277 |
-
|
278 |
-
|
279 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
280 |
<p class="description">
|
281 |
-
<?php
|
|
|
|
|
|
|
282 |
</p>
|
283 |
-
|
284 |
-
</
|
285 |
-
</tr>
|
286 |
-
<tr class="itsec-global-proxy_header-container">
|
287 |
-
<th scope="row"><label for="itsec-global-proxy_header"><?php esc_html_e( 'Proxy Header', 'better-wp-security' ); ?></label></th>
|
288 |
-
<td>
|
289 |
-
<?php $form->add_select( 'proxy_header', $proxy_header_opt ); ?>
|
290 |
-
<p class="description">
|
291 |
-
<?php printf(
|
292 |
-
esc_html__( 'Select the header your Proxy Server uses to forward the client IP address. If you don\'t know the header, you can contact your hosting provider or select the header that has your %1$sIP Address%2$s.', 'better-wp-security' ),
|
293 |
-
'<a href="https://whatismyipaddress.com">', '</a>'
|
294 |
-
); ?>
|
295 |
-
</p>
|
296 |
-
</td>
|
297 |
-
</tr>
|
298 |
-
<tr>
|
299 |
-
<th scope="row"><label for="itsec-global-hide_admin_bar"><?php _e( 'Hide Security Menu in Admin Bar', 'better-wp-security' ); ?></label></th>
|
300 |
-
<td>
|
301 |
-
<?php $form->add_checkbox( 'hide_admin_bar' ); ?>
|
302 |
-
<label for="itsec-global-hide_admin_bar"><?php _e( 'Hide security menu in admin bar.', 'better-wp-security' ); ?></label>
|
303 |
-
<p class="description"><?php esc_html_e( 'Remove the Security Messages Menu from the admin bar and receive the messages as traditional WordPress Admin Notices.', 'better-wp-security' ); ?></p>
|
304 |
-
</td>
|
305 |
-
</tr>
|
306 |
-
<tr>
|
307 |
-
<th scope="row"><label for="itsec-global-show_error_codes"><?php _e( 'Show Error Codes', 'better-wp-security' ); ?></label></th>
|
308 |
-
<td>
|
309 |
-
<?php $form->add_select( 'show_error_codes', $show_error_codes_options ); ?>
|
310 |
-
<p class="description"><?php _e( 'Each error message in iThemes Security has an associated error code that can help diagnose an issue. Changing this setting to "Yes" causes these codes to display. This setting should be left set to "No" unless iThemes Security support requests that you change it.', 'better-wp-security' ); ?></p>
|
311 |
-
</td>
|
312 |
-
</tr>
|
313 |
-
<?php if ( ITSEC_Core::is_pro() ) : ?>
|
314 |
<tr>
|
315 |
-
<th scope="row"><label for="itsec-global-
|
316 |
<td>
|
317 |
-
<?php $form->
|
318 |
-
<
|
|
|
319 |
</td>
|
320 |
</tr>
|
321 |
-
|
322 |
-
|
323 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
324 |
|
325 |
}
|
326 |
}
|
1 |
<?php
|
2 |
|
3 |
final class ITSEC_Global_Settings_Page extends ITSEC_Module_Settings_Page {
|
4 |
+
private $version = 4;
|
|
|
5 |
|
6 |
public function __construct() {
|
7 |
+
$this->id = 'global';
|
8 |
+
$this->title = __( 'Global Settings', 'better-wp-security' );
|
9 |
$this->description = __( 'Configure basic settings that control how iThemes Security functions.', 'better-wp-security' );
|
10 |
+
$this->type = 'recommended';
|
11 |
|
12 |
parent::__construct();
|
13 |
|
34 |
$vars = array(
|
35 |
'ip' => ITSEC_Lib::get_ip(),
|
36 |
'log_location' => ITSEC_Modules::get_default( $this->id, 'log_location' ),
|
37 |
+
'l10n' => array(
|
38 |
+
'loading' => esc_html__( 'Loading...', 'better-wp-security' ),
|
39 |
+
)
|
40 |
);
|
41 |
|
42 |
+
wp_enqueue_script( 'itsec-global-settings-page-script', plugins_url( 'js/settings-page.js', __FILE__ ), array( 'jquery', 'itsec-settings-page-script', 'itsec-util' ), $this->version, true );
|
43 |
wp_localize_script( 'itsec-global-settings-page-script', 'itsec_global_settings_page', $vars );
|
44 |
+
wp_enqueue_style( 'itsec-global-settings', plugins_url( 'css/settings-page.css', __FILE__ ), array(), $this->version );
|
45 |
}
|
46 |
|
47 |
public function handle_form_post( $data ) {
|
58 |
}
|
59 |
}
|
60 |
|
61 |
+
public function handle_ajax_request( $data ) {
|
62 |
+
$method = empty( $data['method'] ) ? '' : $data['method'];
|
63 |
+
|
64 |
+
switch ( $method ) {
|
65 |
+
case 'get-ip':
|
66 |
+
ITSEC_Lib::load( 'ip-detector' );
|
67 |
+
$detector = ITSEC_Lib_IP_Detector::build_for_type( $data['proxy'], isset( $data['args'] ) ? $data['args'] : array() );
|
68 |
+
$ip = $detector->get();
|
69 |
+
|
70 |
+
return array(
|
71 |
+
'ip' => $ip,
|
72 |
+
'ip_l10n' => sprintf( __( 'Detected IP: %s', 'better-wp-security' ), $ip ),
|
73 |
+
);
|
74 |
+
case 'scan-ip':
|
75 |
+
if ( ! ITSEC_Modules::is_active( 'security-check-pro' ) ) {
|
76 |
+
ITSEC_Modules::activate( 'security-check-pro' );
|
77 |
+
ITSEC_Modules::load_module_file( 'active.php', 'security-check-pro' );
|
78 |
+
}
|
79 |
+
|
80 |
+
ITSEC_Modules::load_module_file( 'feedback.php', 'security-check' );
|
81 |
+
ITSEC_Modules::load_module_file( 'utility.php', 'security-check-pro' );
|
82 |
+
$scan = ITSEC_Security_Check_Pro_Utility::get_server_response();
|
83 |
+
|
84 |
+
if ( is_wp_error( $scan ) ) {
|
85 |
+
ITSEC_Response::add_error( $scan );
|
86 |
+
} elseif ( empty( $scan['remote_ip'] ) ) {
|
87 |
+
ITSEC_Response::add_error( __( 'Could not detect IP header.', 'better-wp-security' ) );
|
88 |
+
} else {
|
89 |
+
ITSEC_Lib::load( 'ip-detector' );
|
90 |
+
$detector = ITSEC_Lib_IP_Detector::build_for_type( 'security-check' );
|
91 |
+
$ip = $detector->get();
|
92 |
+
|
93 |
+
if ( ! $ip ) {
|
94 |
+
ITSEC_Response::add_error( __( 'Identified IP was invalid.', 'better-wp-security' ) );
|
95 |
+
|
96 |
+
return null;
|
97 |
+
}
|
98 |
+
|
99 |
+
return array(
|
100 |
+
'ip' => $ip,
|
101 |
+
'ip_l10n' => sprintf( __( 'Detected IP: %s', 'better-wp-security' ), $ip ),
|
102 |
+
);
|
103 |
+
}
|
104 |
+
|
105 |
+
return null;
|
106 |
+
default:
|
107 |
+
return null;
|
108 |
+
}
|
109 |
+
}
|
110 |
|
111 |
+
protected function render_description( $form ) {
|
112 |
+
?>
|
113 |
+
<p><?php _e( 'The following settings modify the behavior of many of the features offered by iThemes Security.', 'better-wp-security' ); ?></p>
|
114 |
+
<?php
|
115 |
}
|
116 |
|
117 |
protected function render_settings( $form ) {
|
118 |
+
/** @var ITSEC_Global_Validator $validator */
|
119 |
$validator = ITSEC_Modules::get_validator( $this->id );
|
120 |
|
121 |
$log_types = $validator->get_valid_log_types();
|
132 |
|
133 |
$proxy = array( 'value' => $validator->get_proxy_types() );
|
134 |
|
135 |
+
$proxy_header_opt = $validator->get_proxy_header_options();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
136 |
|
137 |
+
?>
|
138 |
+
<table class="form-table itsec-settings-section">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
139 |
<tr>
|
140 |
+
<th scope="row"><label for="itsec-global-write_files"><?php _e( 'Write to Files', 'better-wp-security' ); ?></label></th>
|
141 |
<td>
|
142 |
+
<?php $form->add_checkbox( 'write_files' ); ?>
|
143 |
+
<label for="itsec-global-write_files"><?php _e( 'Allow iThemes Security to write to wp-config.php and .htaccess.', 'better-wp-security' ); ?></label>
|
144 |
+
<p class="description"><?php _e( 'Whether or not iThemes Security should be allowed to write to wp-config.php and .htaccess automatically. If disabled you will need to manually place configuration options in those files.', 'better-wp-security' ); ?></p>
|
145 |
</td>
|
146 |
</tr>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
147 |
<tr>
|
148 |
+
<th scope="row"><label for="itsec-global-lockout_message"><?php _e( 'Host Lockout Message', 'better-wp-security' ); ?></label></th>
|
149 |
<td>
|
150 |
+
<?php $form->add_textarea( 'lockout_message', array( 'class' => 'widefat' ) ); ?>
|
151 |
+
<p class="description"><?php _e( 'The message to display when a computer (host) has been locked out.', 'better-wp-security' ); ?></p>
|
152 |
+
<p class="description"><?php _e( 'You can use HTML in your message. Allowed tags include: a, br, em, strong, h1, h2, h3, h4, h5, h6, div.', 'better-wp-security' ); ?></p>
|
153 |
</td>
|
154 |
</tr>
|
155 |
+
<tr>
|
156 |
+
<th scope="row"><label for="itsec-global-user_lockout_message"><?php _e( 'User Lockout Message', 'better-wp-security' ); ?></label></th>
|
157 |
+
<td>
|
158 |
+
<?php $form->add_textarea( 'user_lockout_message', array( 'class' => 'widefat' ) ); ?>
|
159 |
+
<p class="description"><?php _e( 'The message to display to a user when their account has been locked out.', 'better-wp-security' ); ?></p>
|
160 |
+
<p class="description"><?php _e( 'You can use HTML in your message. Allowed tags include: a, br, em, strong, h1, h2, h3, h4, h5, h6, div.', 'better-wp-security' ); ?></p>
|
161 |
+
</td>
|
162 |
+
</tr>
|
163 |
+
<tr>
|
164 |
+
<th scope="row"><label for="itsec-global-community_lockout_message"><?php _e( 'Community Lockout Message', 'better-wp-security' ); ?></label></th>
|
165 |
+
<td>
|
166 |
+
<?php $form->add_textarea( 'community_lockout_message', array( 'class' => 'widefat' ) ); ?>
|
167 |
+
<p class="description"><?php _e( 'The message to display to a user when their IP has been flagged as bad by the iThemes network.', 'better-wp-security' ); ?></p>
|
168 |
+
<p class="description"><?php _e( 'You can use HTML in your message. Allowed tags include: a, br, em, strong, h1, h2, h3, h4, h5, h6, div.', 'better-wp-security' ); ?></p>
|
169 |
+
</td>
|
170 |
+
</tr>
|
171 |
+
<tr>
|
172 |
+
<th scope="row"><label for="itsec-global-blacklist"><?php _e( 'Blacklist Repeat Offender', 'better-wp-security' ); ?></label></th>
|
173 |
+
<td>
|
174 |
+
<?php $form->add_checkbox( 'blacklist' ); ?>
|
175 |
+
<label for="itsec-global-blacklist"><?php _e( 'Enable Blacklist Repeat Offender', 'better-wp-security' ); ?></label>
|
176 |
+
<p class="description"><?php _e( 'If this box is checked the IP address of the offending computer will be added to the "Ban Users" blacklist after reaching the number of lockouts listed below.', 'better-wp-security' ); ?></p>
|
177 |
+
</td>
|
178 |
+
</tr>
|
179 |
+
<tr>
|
180 |
+
<th scope="row"><label for="itsec-global-blacklist_count"><?php _e( 'Blacklist Threshold', 'better-wp-security' ); ?></label></th>
|
181 |
+
<td>
|
182 |
+
<?php $form->add_text( 'blacklist_count', array( 'class' => 'small-text' ) ); ?>
|
183 |
+
<label for="itsec-global-blacklist_count"><?php _e( 'Lockouts', 'better-wp-security' ); ?></label>
|
184 |
+
<p class="description"><?php _e( 'The number of lockouts per IP before the host is banned permanently from this site.', 'better-wp-security' ); ?></p>
|
185 |
+
</td>
|
186 |
+
</tr>
|
187 |
+
<tr>
|
188 |
+
<th scope="row"><label for="itsec-global-blacklist_period"><?php _e( 'Blacklist Lookback Period', 'better-wp-security' ); ?></label></th>
|
189 |
+
<td>
|
190 |
+
<?php $form->add_text( 'blacklist_period', array( 'class' => 'small-text' ) ); ?>
|
191 |
+
<label for="itsec-global-blacklist_period"><?php _e( 'Days', 'better-wp-security' ); ?></label>
|
192 |
+
<p class="description"><?php _e( 'How many days should a lockout be remembered to meet the blacklist count above.', 'better-wp-security' ); ?></p>
|
193 |
+
</td>
|
194 |
+
</tr>
|
195 |
+
<tr>
|
196 |
+
<th scope="row"><label for="itsec-global-lockout_period"><?php _e( 'Lockout Period', 'better-wp-security' ); ?></label></th>
|
197 |
+
<td>
|
198 |
+
<?php $form->add_text( 'lockout_period', array( 'class' => 'small-text' ) ); ?>
|
199 |
+
<label for="itsec-global-lockout_period"><?php _e( 'Minutes', 'better-wp-security' ); ?></label>
|
200 |
+
<p class="description"><?php _e( 'The length of time a host or user will be banned from this site after hitting the limit of bad logins. The default setting of 15 minutes is recommended as increasing it could prevent attacking IP addresses from being added to the blacklist.', 'better-wp-security' ); ?></p>
|
201 |
+
</td>
|
202 |
+
</tr>
|
203 |
+
<tr>
|
204 |
+
<th scope="row"><label for="itsec-global-lockout_white_list"><?php _e( 'Lockout White List', 'better-wp-security' ); ?></label></th>
|
205 |
+
<td>
|
206 |
+
<?php $form->add_textarea( 'lockout_white_list' ); ?>
|
207 |
+
<p><?php $form->add_button( 'add-to-whitelist', array( 'value' => __( 'Add my current IP to the White List', 'better-wp-security' ), 'class' => 'button-primary' ) ); ?></p>
|
208 |
+
<p class="description"><?php _e( 'Use the guidelines below to enter hosts that will not be locked out from your site. This will keep you from locking yourself out of any features if you should trigger a lockout. Please note this does not override away mode and will only prevent a temporary ban. Should a permanent ban be triggered you will still be added to the "Ban Users" list unless the IP address is also white listed in that section.', 'better-wp-security' ); ?></p>
|
209 |
+
<ul>
|
210 |
+
<li>
|
211 |
+
<?php _e( 'You may white list users by individual IP address or IP address range using wildcards or CIDR notation.', 'better-wp-security' ); ?>
|
212 |
+
<ul>
|
213 |
+
<li><?php _e( 'Individual IP addresses must be in IPv4 or IPv6 standard format (###.###.###.### or ####:####:####:####:####:####:####:####).', 'better-wp-security' ); ?></li>
|
214 |
+
<li><?php _e( 'CIDR notation is allowed to specify a range of IP addresses (###.###.###.###/## or ####:####:####:####:####:####:####:####/###).', 'better-wp-security' ); ?></li>
|
215 |
+
<li><?php _e( 'Wildcards are also supported with some limitations. If using wildcards (*), you must start with the right-most chunk in the IP address. For example ###.###.###.* and ###.###.*.* are permitted but ###.###.*.### is not. Wildcards are only for convenient entering of IP addresses, and will be automatically converted to their appropriate CIDR notation format on save.', 'better-wp-security' ); ?></li>
|
216 |
+
</ul>
|
217 |
+
</li>
|
218 |
+
<li><?php _e( 'Enter only 1 IP address or 1 IP address range per line.', 'better-wp-security' ); ?></li>
|
219 |
+
</ul>
|
220 |
+
<p><a href="<?php echo esc_url( ITSEC_Lib::get_trace_ip_link() ); ?>" target="_blank" rel="noopener noreferrer"><?php _e( 'Lookup IP Address.', 'better-wp-security' ); ?></a></p>
|
221 |
<p class="description">
|
222 |
+
<strong><?php _e( 'This white list will prevent any IP listed from triggering an automatic lockout. You can still block the IP address manually in the banned users settings.', 'better-wp-security' ); ?></strong>
|
223 |
</p>
|
224 |
+
</td>
|
225 |
+
</tr>
|
226 |
+
<tr>
|
227 |
+
<th scope="row"><label for="itsec-global-log_type"><?php _e( 'Log Type', 'better-wp-security' ); ?></label></th>
|
228 |
+
<td>
|
229 |
+
<?php $form->add_select( 'log_type', $log_types ); ?>
|
230 |
+
<label for="itsec-global-log_type"><?php _e( 'How should event logs be kept', 'better-wp-security' ); ?></label>
|
231 |
+
<p class="description"><?php _e( 'iThemes Security can log events in multiple ways, each with advantages and disadvantages. Database Only puts all events in the database with your posts and other WordPress data. This makes it easy to retrieve and process but can be slower if the database table gets very large. File Only is very fast but the plugin does not process the logs itself as that would take far more resources. For most users or smaller sites Database Only should be fine. If you have a very large site or a log processing software then File Only might be a better option.', 'better-wp-security' ); ?></p>
|
232 |
+
</td>
|
233 |
+
</tr>
|
234 |
+
<tr>
|
235 |
+
<th scope="row"><label for="itsec-global-log_rotation"><?php _e( 'Days to Keep Database Logs', 'better-wp-security' ); ?></label></th>
|
236 |
+
<td>
|
237 |
+
<?php $form->add_text( 'log_rotation', array( 'class' => 'small-text' ) ); ?>
|
238 |
+
<label for="itsec-global-log_rotation"><?php _e( 'Days', 'better-wp-security' ); ?></label>
|
239 |
+
<p class="description"><?php _e( 'The number of days database logs should be kept.', 'better-wp-security' ); ?></p>
|
240 |
+
</td>
|
241 |
+
</tr>
|
242 |
+
<tr>
|
243 |
+
<th scope="row"><label for="itsec-global-file_log_rotation"><?php _e( 'Days to Keep File Logs', 'better-wp-security' ); ?></label></th>
|
244 |
+
<td>
|
245 |
+
<?php $form->add_text( 'file_log_rotation', array( 'class' => 'small-text' ) ); ?>
|
246 |
+
<label for="itsec-global-log_rotation"><?php _e( 'Days', 'better-wp-security' ); ?></label>
|
247 |
+
<p class="description"><?php _e( 'The number of days file logs should be kept. File logs will additionally be rotated once the file hits 10MB. Set to 0 to only use log rotation.', 'better-wp-security' ); ?></p>
|
248 |
+
</td>
|
249 |
+
</tr>
|
250 |
+
<tr>
|
251 |
+
<th scope="row"><label for="itsec-global-log_location"><?php _e( 'Path to Log Files', 'better-wp-security' ); ?></label></th>
|
252 |
+
<td>
|
253 |
+
<?php $form->add_text( 'log_location', array( 'class' => 'large-text code' ) ); ?>
|
254 |
+
<p><label for="itsec-global-log_location"><?php _e( 'The path on your server where log files should be stored.', 'better-wp-security' ); ?></label></p>
|
255 |
+
<p class="description"><?php _e( 'This path must be writable by your website. For added security, it is recommended you do not include it in your website root folder.', 'better-wp-security' ); ?></p>
|
256 |
+
<p><?php $form->add_button( 'reset-log-location', array( 'value' => __( 'Restore Default Log File Path', 'better-wp-security' ), 'class' => 'button-secondary' ) ); ?></p>
|
257 |
+
</td>
|
258 |
+
</tr>
|
259 |
+
<?php if ( is_dir( WP_PLUGIN_DIR . '/iwp-client' ) ) : ?>
|
260 |
+
<tr>
|
261 |
+
<th scope="row"><label for="itsec-global-infinitewp_compatibility"><?php _e( 'Add InfiniteWP Compatibility', 'better-wp-security' ); ?></label></th>
|
262 |
+
<td>
|
263 |
+
<?php $form->add_checkbox( 'infinitewp_compatibility' ); ?>
|
264 |
+
<label for="itsec-global-infinitewp_compatibility"><?php _e( 'Enable InfiniteWP Compatibility', 'better-wp-security' ); ?></label>
|
265 |
+
<p class="description"><?php printf( __( 'Turning this feature on will enable compatibility with <a href="%s" target="_blank" rel="noopener noreferrer">InfiniteWP</a>. Do not turn it on unless you use the InfiniteWP service.', 'better-wp-security' ), 'http://infinitewp.com' ); ?></p>
|
266 |
+
</td>
|
267 |
+
</tr>
|
268 |
+
<?php endif; ?>
|
269 |
+
<tr>
|
270 |
+
<th scope="row"><label for="itsec-global-allow_tracking"><?php _e( 'Allow Data Tracking', 'better-wp-security' ); ?></label></th>
|
271 |
+
<td>
|
272 |
+
<?php $form->add_checkbox( 'allow_tracking' ); ?>
|
273 |
+
<label for="itsec-global-allow_tracking"><?php _e( 'Allow iThemes to track plugin usage via anonymous data.', 'better-wp-security' ); ?></label>
|
274 |
+
</td>
|
275 |
+
</tr>
|
276 |
+
<?php if ( 'nginx' === ITSEC_Lib::get_server() ) : ?>
|
277 |
+
<tr>
|
278 |
+
<th scope="row"><label for="itsec-global-nginx_file"><?php _e( 'NGINX Conf File', 'better-wp-security' ); ?></label></th>
|
279 |
+
<td>
|
280 |
+
<?php $form->add_text( 'nginx_file', array( 'class' => 'large-text code' ) ); ?>
|
281 |
+
<p><label for="itsec-global-nginx_file"><?php _e( 'The path on your server where the nginx config file is located.', 'better-wp-security' ); ?></label></p>
|
282 |
+
<p class="description"><?php _e( 'This path must be writable by your website. For added security, it is recommended you do not include it in your website root folder.', 'better-wp-security' ); ?></p>
|
283 |
+
</td>
|
284 |
+
</tr>
|
285 |
+
<?php endif; ?>
|
286 |
+
<tr>
|
287 |
+
<th scope="row"><label for="itsec-global-proxy"><?php esc_html_e( 'Proxy Detection', 'better-wp-security' ); ?></label></th>
|
288 |
+
<td>
|
289 |
+
<div class="itsec-global-proxy-wrapper">
|
290 |
+
<?php $form->add_select( 'proxy', $proxy ); ?>
|
291 |
+
<?php $form->add_button( 'ip-scan', array( 'value' => esc_html__( 'Run Security Check Scan Now', 'better-wp-security' ), 'class' => 'button' ) ); ?>
|
292 |
+
</div>
|
293 |
+
<p class="itsec-global-detected-ip"><?php printf( __( 'Detected IP: %s', 'better-wp-security' ), ITSEC_Lib::get_ip() ) ?></p>
|
294 |
+
<p class="description"><?php esc_html_e( 'Choose how iThemes Security determines your visitor\'s IP addresses. Incorrectly configuring this setting may lead to attackers bypassing lockouts or bans.', 'better-wp-security' ); ?></p>
|
295 |
+
<ul>
|
296 |
+
<?php if ( isset( $proxy['value']['security-check'] ) ): ?>
|
297 |
+
<li>
|
298 |
+
<?php printf(
|
299 |
+
esc_html__( 'Security Check Scan – (Recommended) Security Check will connect to the iThemes.com servers to accurately identify your server configuration. %1$sRead our Privacy Policy%2$s. Security Check will correctly identify remote IP addresses and ensure your site is using the recommended features.', 'better-wp-security' ),
|
300 |
+
'<a href="https://ithemes.com/privacy-policy/" target="_blank">',
|
301 |
+
'</a>'
|
302 |
+
); ?>
|
303 |
+
</li>
|
304 |
+
<?php endif; ?>
|
305 |
+
<li><?php esc_html_e( 'Automatic – (Not Recommended) iThemes Security will try to find the correct proxy header to use automatically.', 'better-wp-security' ); ?></li>
|
306 |
+
<li><?php esc_html_e( 'Manual – Manually select the header your proxy uses.', 'better-wp-security' ); ?></li>
|
307 |
+
<li><?php esc_html_e( 'Disabled – Do not use Proxy Detection if your website isn\'t behind a proxy.', 'better-wp-security' ); ?></li>
|
308 |
+
</ul>
|
309 |
+
</td>
|
310 |
+
</tr>
|
311 |
+
<tr class="itsec-global-proxy_header-container">
|
312 |
+
<th scope="row"><label for="itsec-global-proxy_header"><?php esc_html_e( 'Proxy Header', 'better-wp-security' ); ?></label></th>
|
313 |
+
<td>
|
314 |
+
<?php $form->add_select( 'proxy_header', $proxy_header_opt ); ?>
|
315 |
<p class="description">
|
316 |
+
<?php printf(
|
317 |
+
esc_html__( 'Select the header your Proxy Server uses to forward the client IP address. If you don\'t know the header, you can contact your hosting provider or select the header that has your %1$sIP Address%2$s.', 'better-wp-security' ),
|
318 |
+
'<a href="https://whatismyipaddress.com">', '</a>'
|
319 |
+
); ?>
|
320 |
</p>
|
321 |
+
</td>
|
322 |
+
</tr>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
323 |
<tr>
|
324 |
+
<th scope="row"><label for="itsec-global-hide_admin_bar"><?php _e( 'Hide Security Menu in Admin Bar', 'better-wp-security' ); ?></label></th>
|
325 |
<td>
|
326 |
+
<?php $form->add_checkbox( 'hide_admin_bar' ); ?>
|
327 |
+
<label for="itsec-global-hide_admin_bar"><?php _e( 'Hide security menu in admin bar.', 'better-wp-security' ); ?></label>
|
328 |
+
<p class="description"><?php esc_html_e( 'Remove the Security Messages Menu from the admin bar and receive the messages as traditional WordPress Admin Notices.', 'better-wp-security' ); ?></p>
|
329 |
</td>
|
330 |
</tr>
|
331 |
+
<tr>
|
332 |
+
<th scope="row"><label for="itsec-global-show_error_codes"><?php _e( 'Show Error Codes', 'better-wp-security' ); ?></label></th>
|
333 |
+
<td>
|
334 |
+
<?php $form->add_select( 'show_error_codes', $show_error_codes_options ); ?>
|
335 |
+
<p class="description"><?php _e( 'Each error message in iThemes Security has an associated error code that can help diagnose an issue. Changing this setting to "Yes" causes these codes to display. This setting should be left set to "No" unless iThemes Security support requests that you change it.', 'better-wp-security' ); ?></p>
|
336 |
+
</td>
|
337 |
+
</tr>
|
338 |
+
<?php if ( ITSEC_Core::is_pro() ) : ?>
|
339 |
+
<tr>
|
340 |
+
<th scope="row"><label for="itsec-global-enable_grade_report"><?php _e( 'Enable Grade Report', 'better-wp-security' ); ?></label></th>
|
341 |
+
<td>
|
342 |
+
<?php $form->add_select( 'enable_grade_report', $enable_grade_report_options ); ?>
|
343 |
+
<p class="description"><?php _e( 'The Grade Report feature can help you identify vulnerabilities on the site. Visit the Notification Center to select which users receive emails from this feature.', 'better-wp-security' ); ?></p>
|
344 |
+
</td>
|
345 |
+
</tr>
|
346 |
+
<?php endif; ?>
|
347 |
+
</table>
|
348 |
+
<?php
|
349 |
|
350 |
}
|
351 |
}
|
core/modules/global/setup.php
CHANGED
@@ -6,10 +6,10 @@ if ( ! class_exists( 'ITSEC_Global_Setup' ) ) {
|
|
6 |
|
7 |
public function __construct() {
|
8 |
|
9 |
-
add_action( 'itsec_modules_do_plugin_activation',
|
10 |
-
add_action( 'itsec_modules_do_plugin_deactivation', array( $this, 'execute_deactivate' )
|
11 |
-
add_action( 'itsec_modules_do_plugin_uninstall',
|
12 |
-
add_action( 'itsec_modules_do_plugin_upgrade',
|
13 |
|
14 |
}
|
15 |
|
@@ -50,8 +50,8 @@ if ( ! class_exists( 'ITSEC_Global_Setup' ) ) {
|
|
50 |
|
51 |
if ( $options['log_info'] ) {
|
52 |
$new_log_info = substr( sanitize_title( get_bloginfo( 'name' ) ), 0, 20 ) . '-' . wp_generate_password( 30, false );
|
53 |
-
$old_file
|
54 |
-
$new_file
|
55 |
|
56 |
// If the file exists already, don't update the location unless we successfully move it.
|
57 |
if ( file_exists( $old_file ) && rename( $old_file, $new_file ) ) {
|
@@ -128,8 +128,13 @@ if ( ! class_exists( 'ITSEC_Global_Setup' ) ) {
|
|
128 |
ITSEC_Modules::set_setting( 'global', 'proxy', 'disabled' );
|
129 |
}
|
130 |
}
|
131 |
-
}
|
132 |
|
|
|
|
|
|
|
|
|
|
|
|
|
133 |
}
|
134 |
|
135 |
}
|
6 |
|
7 |
public function __construct() {
|
8 |
|
9 |
+
add_action( 'itsec_modules_do_plugin_activation', array( $this, 'execute_activate' ) );
|
10 |
+
add_action( 'itsec_modules_do_plugin_deactivation', array( $this, 'execute_deactivate' ) );
|
11 |
+
add_action( 'itsec_modules_do_plugin_uninstall', array( $this, 'execute_uninstall' ) );
|
12 |
+
add_action( 'itsec_modules_do_plugin_upgrade', array( $this, 'execute_upgrade' ), null, 2 );
|
13 |
|
14 |
}
|
15 |
|
50 |
|
51 |
if ( $options['log_info'] ) {
|
52 |
$new_log_info = substr( sanitize_title( get_bloginfo( 'name' ) ), 0, 20 ) . '-' . wp_generate_password( 30, false );
|
53 |
+
$old_file = path_join( $options['log_location'], 'event-log-' . $options['log_info'] . '.log' );
|
54 |
+
$new_file = path_join( $options['log_location'], 'event-log-' . $new_log_info . '.log' );
|
55 |
|
56 |
// If the file exists already, don't update the location unless we successfully move it.
|
57 |
if ( file_exists( $old_file ) && rename( $old_file, $new_file ) ) {
|
128 |
ITSEC_Modules::set_setting( 'global', 'proxy', 'disabled' );
|
129 |
}
|
130 |
}
|
|
|
131 |
|
132 |
+
if ( $itsec_old_version < 4116 ) {
|
133 |
+
if ( ITSEC_Core::is_pro() && ITSEC_Modules::get_setting( 'security-check-pro', 'remote_ip_index' ) ) {
|
134 |
+
ITSEC_Modules::set_setting( 'global', 'proxy', 'security-check' );
|
135 |
+
}
|
136 |
+
}
|
137 |
+
}
|
138 |
}
|
139 |
|
140 |
}
|
core/modules/global/validator.php
CHANGED
@@ -22,8 +22,7 @@ class ITSEC_Global_Validator extends ITSEC_Validator {
|
|
22 |
$this->vars_to_skip_validate_matching_fields = array( 'digest_last_sent', 'digest_messages', 'digest_email', 'email_notifications', 'notification_email', 'backup_email', 'show_new_dashboard_notice', 'proxy_override', 'proxy', 'proxy_header', 'server_ips', 'initial_build', 'feature_flags' );
|
23 |
$this->set_previous_if_empty( array( 'did_upgrade', 'log_info', 'show_security_check', 'build', 'activation_timestamp', 'lock_file', 'cron_status', 'use_cron', 'cron_test_time', 'proxy', 'proxy_header', 'server_ips', 'initial_build', 'feature_flags' ) );
|
24 |
$this->set_default_if_empty( array( 'log_location', 'nginx_file', 'enable_grade_report' ) );
|
25 |
-
$this->preserve_setting_if_exists( array(
|
26 |
-
|
27 |
|
28 |
$this->sanitize_setting( 'bool', 'write_files', __( 'Write to Files', 'better-wp-security' ) );
|
29 |
$this->sanitize_setting( 'bool', 'blacklist', __( 'Blacklist Repeat Offender', 'better-wp-security' ) );
|
@@ -55,8 +54,8 @@ class ITSEC_Global_Validator extends ITSEC_Validator {
|
|
55 |
|
56 |
$allowed_tags = $this->get_allowed_tags();
|
57 |
|
58 |
-
$this->settings['lockout_message']
|
59 |
-
$this->settings['user_lockout_message']
|
60 |
$this->settings['community_lockout_message'] = trim( wp_kses( $this->settings['community_lockout_message'], $allowed_tags ) );
|
61 |
|
62 |
$this->sanitize_setting( 'newline-separated-ips', 'server_ips', __( 'Server IPs', 'better-wp-security' ) );
|
@@ -64,11 +63,36 @@ class ITSEC_Global_Validator extends ITSEC_Validator {
|
|
64 |
}
|
65 |
|
66 |
public function get_proxy_types() {
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
72 |
}
|
73 |
|
74 |
public function get_valid_log_types() {
|
22 |
$this->vars_to_skip_validate_matching_fields = array( 'digest_last_sent', 'digest_messages', 'digest_email', 'email_notifications', 'notification_email', 'backup_email', 'show_new_dashboard_notice', 'proxy_override', 'proxy', 'proxy_header', 'server_ips', 'initial_build', 'feature_flags' );
|
23 |
$this->set_previous_if_empty( array( 'did_upgrade', 'log_info', 'show_security_check', 'build', 'activation_timestamp', 'lock_file', 'cron_status', 'use_cron', 'cron_test_time', 'proxy', 'proxy_header', 'server_ips', 'initial_build', 'feature_flags' ) );
|
24 |
$this->set_default_if_empty( array( 'log_location', 'nginx_file', 'enable_grade_report' ) );
|
25 |
+
$this->preserve_setting_if_exists( array( 'digest_email', 'email_notifications', 'notification_email', 'backup_email', 'proxy_override' ) );
|
|
|
26 |
|
27 |
$this->sanitize_setting( 'bool', 'write_files', __( 'Write to Files', 'better-wp-security' ) );
|
28 |
$this->sanitize_setting( 'bool', 'blacklist', __( 'Blacklist Repeat Offender', 'better-wp-security' ) );
|
54 |
|
55 |
$allowed_tags = $this->get_allowed_tags();
|
56 |
|
57 |
+
$this->settings['lockout_message'] = trim( wp_kses( $this->settings['lockout_message'], $allowed_tags ) );
|
58 |
+
$this->settings['user_lockout_message'] = trim( wp_kses( $this->settings['user_lockout_message'], $allowed_tags ) );
|
59 |
$this->settings['community_lockout_message'] = trim( wp_kses( $this->settings['community_lockout_message'], $allowed_tags ) );
|
60 |
|
61 |
$this->sanitize_setting( 'newline-separated-ips', 'server_ips', __( 'Server IPs', 'better-wp-security' ) );
|
63 |
}
|
64 |
|
65 |
public function get_proxy_types() {
|
66 |
+
ITSEC_Lib::load( 'ip-detector' );
|
67 |
+
|
68 |
+
return ITSEC_Lib_IP_Detector::get_proxy_types();
|
69 |
+
}
|
70 |
+
|
71 |
+
public function get_proxy_header_options() {
|
72 |
+
ITSEC_Lib::load( 'ip-detector' );
|
73 |
+
|
74 |
+
$possible_headers = ITSEC_Lib_IP_Detector::get_proxy_headers();
|
75 |
+
$possible_headers[] = 'REMOTE_ADDR';
|
76 |
+
|
77 |
+
$ucwords = version_compare( phpversion(), '5.5.16', '>=' ) || ( version_compare( phpversion(), '5.4.32', '>=' ) && version_compare( phpversion(), '5.5.0', '<' ) );
|
78 |
+
$options = array();
|
79 |
+
|
80 |
+
foreach ( $possible_headers as $header ) {
|
81 |
+
$label = $header;
|
82 |
+
|
83 |
+
if ( 0 === strpos( $header, 'HTTP_' ) ) {
|
84 |
+
$label = substr( $label, 5 );
|
85 |
+
}
|
86 |
+
|
87 |
+
$label = str_replace( '_', '-', $label );
|
88 |
+
$label = strtolower( $label );
|
89 |
+
$label = $ucwords ? ucwords( $label, '-' ) : implode( '-', array_map( 'ucfirst', explode( '-', $label ) ) );
|
90 |
+
$label = str_replace('Ip', 'IP', $label );
|
91 |
+
|
92 |
+
$options[ $header ] = $label;
|
93 |
+
}
|
94 |
+
|
95 |
+
return $options;
|
96 |
}
|
97 |
|
98 |
public function get_valid_log_types() {
|
core/modules/security-check-pro/activate.php
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
ITSEC_Response::reload_module( 'security-check' );
|
3 |
+
ITSEC_Response::reload_module( 'global' );
|
core/modules/security-check-pro/active.php
ADDED
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
require_once( __DIR__ . '/class-itsec-security-check-pro.php' );
|
4 |
+
$itsec_security_check_pro = new ITSEC_Security_Check_Pro();
|
5 |
+
$itsec_security_check_pro->run();
|
core/modules/security-check-pro/class-itsec-security-check-pro.php
ADDED
@@ -0,0 +1,82 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
final class ITSEC_Security_Check_Pro {
|
4 |
+
public function __construct() { }
|
5 |
+
|
6 |
+
public function run() {
|
7 |
+
if ( defined( 'ITSEC_DISABLE_SECURITY_CHECK_PRO' ) && ITSEC_DISABLE_SECURITY_CHECK_PRO ) {
|
8 |
+
return;
|
9 |
+
}
|
10 |
+
|
11 |
+
if ( isset( $_POST['itsec-security-check'] ) ) {
|
12 |
+
require_once( dirname( __FILE__ ) . '/utility.php' );
|
13 |
+
|
14 |
+
ITSEC_Security_Check_Pro_Utility::handle_scan_request();
|
15 |
+
}
|
16 |
+
|
17 |
+
add_action( 'itsec-security-check-before-default-checks', array( $this, 'run_scan' ) );
|
18 |
+
add_action( 'itsec-security-check-enable-ssl', array( $this, 'handle_enable_ssl' ) );
|
19 |
+
|
20 |
+
add_filter( 'itsec-ssl-support-probability', array( $this, 'filter_ssl_support_probability' ) );
|
21 |
+
|
22 |
+
if ( ! defined( 'ITSEC_DISABLE_AUTOMATIC_REMOTE_IP_DETECTION' ) || ! ITSEC_DISABLE_AUTOMATIC_REMOTE_IP_DETECTION ) {
|
23 |
+
add_filter( 'itsec_proxy_types', array( $this, 'add_security_check_proxy_type' ) );
|
24 |
+
add_filter( 'itsec_build_ip_detector_for_security-check', array( $this, 'build_detector' ), 10, 2 );
|
25 |
+
add_action( 'itsec_scheduled_health-check', array( $this, 'health_check' ) );
|
26 |
+
}
|
27 |
+
}
|
28 |
+
|
29 |
+
public function run_scan( $feedback ) {
|
30 |
+
require_once( dirname( __FILE__ ) . '/utility.php' );
|
31 |
+
|
32 |
+
ITSEC_Security_Check_Pro_Utility::run_scan( $feedback );
|
33 |
+
}
|
34 |
+
|
35 |
+
public function handle_enable_ssl( $data ) {
|
36 |
+
require_once( dirname( __FILE__ ) . '/utility.php' );
|
37 |
+
|
38 |
+
ITSEC_Security_Check_Pro_Utility::handle_enable_ssl( $data );
|
39 |
+
}
|
40 |
+
|
41 |
+
public function filter_ssl_support_probability( $probability ) {
|
42 |
+
if ( ITSEC_Modules::get_setting( 'security-check-pro', 'ssl_supported' ) ) {
|
43 |
+
$probability = 100;
|
44 |
+
}
|
45 |
+
|
46 |
+
return $probability;
|
47 |
+
}
|
48 |
+
|
49 |
+
public function add_security_check_proxy_type( $proxy_types ) {
|
50 |
+
return ITSEC_Lib::array_insert_before( 'automatic', $proxy_types, 'security-check', esc_html__( 'Security Check Scan', 'better-wp-security' ) );
|
51 |
+
}
|
52 |
+
|
53 |
+
/**
|
54 |
+
* Add the remote IP index to the detector.
|
55 |
+
*
|
56 |
+
* @param bool $configured
|
57 |
+
* @param ITSEC_IP_Detector $detector
|
58 |
+
*
|
59 |
+
* @return bool
|
60 |
+
*/
|
61 |
+
public function build_detector( $configured, ITSEC_IP_Detector $detector ) {
|
62 |
+
$index = ITSEC_Modules::get_setting( 'security-check-pro', 'remote_ip_index' );
|
63 |
+
|
64 |
+
if ( ! $index ) {
|
65 |
+
return $configured;
|
66 |
+
}
|
67 |
+
|
68 |
+
if ( is_string( $index ) ) {
|
69 |
+
$detector->add_header( $index );
|
70 |
+
} elseif ( is_array( $index ) && 2 === count( $index ) ) {
|
71 |
+
$detector->add_header( $index[0], (int) $index[1] );
|
72 |
+
}
|
73 |
+
|
74 |
+
return true;
|
75 |
+
}
|
76 |
+
|
77 |
+
public function health_check() {
|
78 |
+
ITSEC_Modules::load_module_file( 'feedback.php', 'security-check' );
|
79 |
+
require_once( __DIR__ . '/utility.php' );
|
80 |
+
ITSEC_Security_Check_Pro_Utility::get_server_response();
|
81 |
+
}
|
82 |
+
}
|
core/modules/security-check-pro/deactivate.php
ADDED
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
ITSEC_Modules::set_setting( 'global', 'proxy', 'automatic' );
|
4 |
+
ITSEC_Response::reload_module( 'security-check' );
|
5 |
+
ITSEC_Response::reload_module( 'global' );
|
core/modules/security-check-pro/debug.php
ADDED
@@ -0,0 +1,60 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Class ITSEC_Security_Check_Pro_Debug
|
5 |
+
*/
|
6 |
+
class ITSEC_Security_Check_Pro_Debug {
|
7 |
+
|
8 |
+
public function __construct() {
|
9 |
+
add_action( 'itsec_debug_page', array( $this, 'render' ) );
|
10 |
+
add_action( 'itsec_debug_page_enqueue', array( $this, 'enqueue_scripts_and_styles' ) );
|
11 |
+
add_action( 'itsec_debug_module_request_security-check-pro', array( $this, 'handle_ajax_request' ) );
|
12 |
+
}
|
13 |
+
|
14 |
+
public function enqueue_scripts_and_styles() {
|
15 |
+
wp_enqueue_script( 'itsec-security-check-pro-debug', plugins_url( 'js/debug.js', __FILE__ ), array( 'itsec-util' ), ITSEC_Core::get_plugin_build() );
|
16 |
+
}
|
17 |
+
|
18 |
+
public function handle_ajax_request( $data ) {
|
19 |
+
|
20 |
+
ITSEC_Modules::load_module_file( 'feedback.php', 'security-check' );
|
21 |
+
ITSEC_Modules::load_module_file( 'scanner.php', 'security-check' );
|
22 |
+
|
23 |
+
require_once( dirname( __FILE__ ) . '/utility.php' );
|
24 |
+
|
25 |
+
$feedback = new ITSEC_Security_Check_Feedback();
|
26 |
+
$response = ITSEC_Security_Check_Pro_Utility::run_scan( $feedback );
|
27 |
+
|
28 |
+
$raw_data = $feedback->get_raw_data();
|
29 |
+
|
30 |
+
if ( is_wp_error( $response ) ) {
|
31 |
+
ITSEC_Response::add_error( $response );
|
32 |
+
} else {
|
33 |
+
ITSEC_Response::add_message( esc_html__( 'Scan Complete', 'better-wp-security' ) );
|
34 |
+
}
|
35 |
+
|
36 |
+
foreach ( $raw_data['sections'] as $id => $section ) {
|
37 |
+
foreach ( $section['entries'] as $entry ) {
|
38 |
+
if ( 'text' === $entry['type'] ) {
|
39 |
+
ITSEC_Response::add_info( $entry['value'] );
|
40 |
+
}
|
41 |
+
}
|
42 |
+
}
|
43 |
+
}
|
44 |
+
|
45 |
+
/**
|
46 |
+
* Render our data to the Debug Page.
|
47 |
+
*/
|
48 |
+
public function render() {
|
49 |
+
?>
|
50 |
+
|
51 |
+
<div>
|
52 |
+
<h2><?php esc_html_e( 'Security Check Pro', 'better-wp-security' ); ?></h2>
|
53 |
+
<button class="button" id="itsec-debug-run-security-check-pro"><?php esc_html_e( 'Run', 'better-wp-security' ); ?></button>
|
54 |
+
</div>
|
55 |
+
|
56 |
+
<?php
|
57 |
+
}
|
58 |
+
}
|
59 |
+
|
60 |
+
new ITSEC_Security_Check_Pro_Debug();
|
core/modules/security-check-pro/index.php
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
<?php // Silence is golden.
|
core/modules/security-check-pro/js/debug.js
ADDED
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
(function ( $, itsecUtil ) {
|
2 |
+
"use strict";
|
3 |
+
|
4 |
+
$( function () {
|
5 |
+
$( '#itsec-debug-run-security-check-pro' ).on( 'click', function () {
|
6 |
+
|
7 |
+
var $btn = $( this );
|
8 |
+
$btn.prop( 'disabled', true );
|
9 |
+
|
10 |
+
itsecUtil.sendModuleAJAXRequest( 'security-check-pro', { run: true }, function ( response ) {
|
11 |
+
|
12 |
+
$btn.prop( 'disabled', false );
|
13 |
+
|
14 |
+
itsecUtil.displayNotices( response, $( '#itsec-messages' ) );
|
15 |
+
} );
|
16 |
+
} );
|
17 |
+
} );
|
18 |
+
})( jQuery, window.itsecUtil );
|
core/modules/security-check-pro/js/index.php
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
<?php //You don't belong here. ?>
|
core/modules/security-check-pro/js/settings-page.js
ADDED
@@ -0,0 +1,106 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
jQuery( document ).ready( function ( $ ) {
|
2 |
+
|
3 |
+
$( document ).on( 'click', '#itsec-security-check-secure_site', function( e ) {
|
4 |
+
e.preventDefault();
|
5 |
+
|
6 |
+
$( '#itsec-security-check-secure_site' )
|
7 |
+
.removeClass( 'button-primary' )
|
8 |
+
.addClass( 'button-secondary' )
|
9 |
+
.attr( 'value', itsec_security_check_settings.securing_site )
|
10 |
+
.prop( 'disabled', true );
|
11 |
+
|
12 |
+
$( '#itsec-security-check-details-container' ).html( '' );
|
13 |
+
|
14 |
+
var data = {
|
15 |
+
'method': 'secure-site'
|
16 |
+
};
|
17 |
+
|
18 |
+
itsecUtil.sendModuleAJAXRequest( 'security-check', data, function( results ) {
|
19 |
+
$( '#itsec-security-check-secure_site' )
|
20 |
+
.addClass( 'button-primary' )
|
21 |
+
.removeClass( 'button-secondary' )
|
22 |
+
.attr( 'value', itsec_security_check_settings.rerun_secure_site )
|
23 |
+
.prop( 'disabled', false );
|
24 |
+
|
25 |
+
$( '#itsec-security-check-details-container' ).html( results.response );
|
26 |
+
} );
|
27 |
+
} );
|
28 |
+
|
29 |
+
$( document ).on( 'click', '#itsec-module-card-security-check .itsec-security-check-container-is-interactive :submit', function( e ) {
|
30 |
+
e.preventDefault();
|
31 |
+
|
32 |
+
var $button = $( this );
|
33 |
+
var $container = $( this ).parents( '.itsec-security-check-container-is-interactive' );
|
34 |
+
var inputs = $container.find( ':input' ).serializeArray();
|
35 |
+
var data = {};
|
36 |
+
|
37 |
+
for ( var i = 0; i < inputs.length; i++ ) {
|
38 |
+
var input = inputs[i];
|
39 |
+
|
40 |
+
if ( '[]' === input.name.substr( -2 ) ) {
|
41 |
+
var name = input.name.substr( 0, input.name.length - 2 );
|
42 |
+
|
43 |
+
if ( data[name] ) {
|
44 |
+
data[name].push( input.value );
|
45 |
+
} else {
|
46 |
+
data[name] = [input.value];
|
47 |
+
}
|
48 |
+
} else {
|
49 |
+
data[input.name] = input.value;
|
50 |
+
}
|
51 |
+
};
|
52 |
+
|
53 |
+
|
54 |
+
$button
|
55 |
+
.removeClass( 'button-primary' )
|
56 |
+
.addClass( 'button-secondary' )
|
57 |
+
.prop( 'disabled', true );
|
58 |
+
|
59 |
+
if ( $button.data( 'clicked-value' ) ) {
|
60 |
+
$button
|
61 |
+
.data( 'original-value', $( this ).val() )
|
62 |
+
.attr( 'value', $( this ).data( 'clicked-value' ) )
|
63 |
+
}
|
64 |
+
|
65 |
+
var ajaxFunction = itsecUtil.sendModuleAJAXRequest;
|
66 |
+
|
67 |
+
if ( 'undefined' !== typeof itsecSecurityCheckAJAXRequest ) {
|
68 |
+
ajaxFunction = itsecSecurityCheckAJAXRequest;
|
69 |
+
}
|
70 |
+
|
71 |
+
ajaxFunction( 'security-check', data, function( results ) {
|
72 |
+
$button
|
73 |
+
.removeClass( 'button-secondary' )
|
74 |
+
.addClass( 'button-primary' )
|
75 |
+
.prop( 'disabled', false );
|
76 |
+
|
77 |
+
if ( $button.data( 'original-value' ) ) {
|
78 |
+
$button
|
79 |
+
.attr( 'value', $( this ).data( 'original-value' ) )
|
80 |
+
}
|
81 |
+
|
82 |
+
|
83 |
+
var $feedback = $container.find( '.itsec-security-check-feedback' );
|
84 |
+
$feedback.html( '' );
|
85 |
+
|
86 |
+
if ( results.errors && results.errors.length > 0 ) {
|
87 |
+
$container
|
88 |
+
.removeClass( 'itsec-security-check-container-call-to-action' )
|
89 |
+
.removeClass( 'itsec-security-check-container-confirmation' )
|
90 |
+
.addClass( 'itsec-security-check-container-error' );
|
91 |
+
|
92 |
+
$.each( results.errors, function( index, error ) {
|
93 |
+
$feedback.append( '<div class="error inline"><p><strong>' + error + '</strong></p></div>' );
|
94 |
+
} );
|
95 |
+
} else {
|
96 |
+
$container
|
97 |
+
.removeClass( 'itsec-security-check-container-call-to-action' )
|
98 |
+
.removeClass( 'itsec-security-check-container-error' )
|
99 |
+
.addClass( 'itsec-security-check-container-confirmation' );
|
100 |
+
|
101 |
+
$container.html( results.response );
|
102 |
+
$( '#itsec-notice-network-brute-force' ).hide();
|
103 |
+
}
|
104 |
+
} );
|
105 |
+
} );
|
106 |
+
} );
|
core/modules/security-check-pro/privacy.php
ADDED
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
final class ITSEC_Security_Check_Pro_Privacy {
|
4 |
+
public function __construct() {
|
5 |
+
add_filter( 'itsec_get_privacy_policy_for_sharing', array( $this, 'get_privacy_policy_for_sharing' ) );
|
6 |
+
}
|
7 |
+
|
8 |
+
public function get_privacy_policy_for_sharing( $policy ) {
|
9 |
+
/* Translators: 1: Link to iThemes' privacy policy */
|
10 |
+
$policy .= "<p class=\"privacy-policy-tutorial\">" . sprintf( wp_kses( __( 'When running Security Check, ithemes.com will be contacted as part of a process to determine if the site supports TLS/SSL requests. No personal data is sent to ithemes.com as part of this process. Requests to ithemes.com include the site\'s URL. For ithemes.com privacy policy details, please see the <a href="%1$s">iThemes Privacy Policy</a>.', 'better-wp-security' ), array( 'a' => array( 'href' => array() ) ) ), 'https://ithemes.com/privacy-policy/' ) . "</p>\n";
|
11 |
+
|
12 |
+
return $policy;
|
13 |
+
}
|
14 |
+
}
|
15 |
+
new ITSEC_Security_Check_Pro_Privacy();
|
core/modules/security-check-pro/settings-page.php
ADDED
@@ -0,0 +1,34 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class ITSEC_Security_Check_Pro_Settings_Page extends ITSEC_Module_Settings_Page {
|
4 |
+
|
5 |
+
public function __construct() {
|
6 |
+
$this->id = 'security-check-pro';
|
7 |
+
$this->title = __( 'Security Check Pro', 'better-wp-security' );
|
8 |
+
$this->description = __( 'Adds secure automatic IP detection and SSL server setup checks.', 'better-wp-security' );
|
9 |
+
$this->type = 'advanced';
|
10 |
+
$this->can_save = false;
|
11 |
+
|
12 |
+
parent::__construct();
|
13 |
+
}
|
14 |
+
|
15 |
+
protected function render_description( $form ) {
|
16 |
+
echo '<p>';
|
17 |
+
echo __( 'Adds secure automatic IP detection and SSL server setup checks.', 'better-wp-security' );
|
18 |
+
printf(
|
19 |
+
__( 'This feature requires contacting an iThemes.com server. See our %1$sPrivacy Policy%2$s.', 'better-wp-security' ),
|
20 |
+
'<a href="https://ithemes.com/privacy-policy/">',
|
21 |
+
'</a>'
|
22 |
+
);
|
23 |
+
echo '</p>';
|
24 |
+
}
|
25 |
+
|
26 |
+
protected function render_settings( $form ) {
|
27 |
+
|
28 |
+
}
|
29 |
+
}
|
30 |
+
|
31 |
+
|
32 |
+
if ( ! ITSEC_Modules::is_always_active( 'security-check-pro' ) ) {
|
33 |
+
new ITSEC_Security_Check_Pro_Settings_Page();
|
34 |
+
}
|
core/modules/security-check-pro/settings.php
ADDED
@@ -0,0 +1,20 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
final class ITSEC_Security_Check_Pro_Settings extends ITSEC_Settings {
|
4 |
+
public function get_id() {
|
5 |
+
return 'security-check-pro';
|
6 |
+
}
|
7 |
+
|
8 |
+
public function get_defaults() {
|
9 |
+
return array(
|
10 |
+
'last_scan_timestamp' => null,
|
11 |
+
'remote_ip_index' => null,
|
12 |
+
'ssl_supported' => null,
|
13 |
+
'remote_ips_timestamp' => null,
|
14 |
+
'remote_ips' => array(),
|
15 |
+
'key_salt' => '',
|
16 |
+
);
|
17 |
+
}
|
18 |
+
}
|
19 |
+
|
20 |
+
ITSEC_Modules::register_settings( new ITSEC_Security_Check_Pro_Settings() );
|
core/modules/security-check-pro/utility.php
ADDED
@@ -0,0 +1,328 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
final class ITSEC_Security_Check_Pro_Utility {
|
4 |
+
private static $api_url = 'https://itsec-ssl-proxy-detect.ithemes.com/';
|
5 |
+
private static $config_url = 'https://itsec-ssl-proxy-detect.ithemes.com/config.json';
|
6 |
+
|
7 |
+
/**
|
8 |
+
* Run the security check pro scan.
|
9 |
+
*
|
10 |
+
* @param ITSEC_Security_Check_Feedback $feedback
|
11 |
+
*
|
12 |
+
* @return array|WP_Error
|
13 |
+
*/
|
14 |
+
public static function run_scan( $feedback ) {
|
15 |
+
$response = self::get_server_response();
|
16 |
+
|
17 |
+
if ( ! is_array( $response ) ) {
|
18 |
+
$settings = ITSEC_Modules::get_settings( 'security-check-pro' );
|
19 |
+
|
20 |
+
if ( ! is_int( $settings['last_scan_timestamp'] ) || time() > $settings['last_scan_timestamp'] + HOUR_IN_SECONDS ) {
|
21 |
+
return $response;
|
22 |
+
}
|
23 |
+
|
24 |
+
$response = array(
|
25 |
+
'remote_ip' => ! empty( $settings['remote_ip_index'] ),
|
26 |
+
'ssl_supported' => $settings['ssl_supported'],
|
27 |
+
);
|
28 |
+
}
|
29 |
+
|
30 |
+
if ( ! defined( 'ITSEC_DISABLE_AUTOMATIC_REMOTE_IP_DETECTION' ) || ! ITSEC_DISABLE_AUTOMATIC_REMOTE_IP_DETECTION ) {
|
31 |
+
if ( isset( $response['remote_ip'] ) && $response['remote_ip'] ) {
|
32 |
+
ITSEC_Modules::set_setting( 'global', 'proxy', 'security-check' );
|
33 |
+
$feedback->add_section( 'security-check-pro-remote-ip', array( 'status' => 'action-taken' ) );
|
34 |
+
$feedback->add_text( __( 'Identified remote IP entry to protect against IP spoofing.', 'better-wp-security' ) );
|
35 |
+
}
|
36 |
+
}
|
37 |
+
|
38 |
+
if ( isset( $response['ssl_supported'] ) && $response['ssl_supported'] ) {
|
39 |
+
ITSEC_Response::reload_module( 'ssl' );
|
40 |
+
|
41 |
+
$ssl_settings = ITSEC_Modules::get_settings( 'ssl' );
|
42 |
+
|
43 |
+
if ( 'enabled' === $ssl_settings['require_ssl'] || ( 'advanced' === $ssl_settings['require_ssl'] && $ssl_settings['admin'] ) ) {
|
44 |
+
$feedback->add_section( 'security-check-pro-ssl' );
|
45 |
+
$feedback->add_text( __( 'Requests for http pages are redirected to https as recommended.', 'better-wp-security' ) );
|
46 |
+
} else {
|
47 |
+
$feedback->add_section( 'security-check-pro-ssl', array( 'interactive' => true, 'status' => 'call-to-action' ) );
|
48 |
+
$feedback->add_text( __( 'Your site supports SSL. Redirecting all http page requests to https is highly recommended as it protects login details from being stolen when using public WiFi or insecure networks.', 'better-wp-security' ) );
|
49 |
+
|
50 |
+
if ( ! is_ssl() ) {
|
51 |
+
$feedback->add_text( __( 'Please note that you will have to log back in after enabling this.', 'better-wp-security' ) );
|
52 |
+
}
|
53 |
+
|
54 |
+
$feedback->add_input( 'submit', 'enable_ssl', array(
|
55 |
+
'value' => __( 'Redirect HTTP Requests to HTTPS', 'better-wp-security' ),
|
56 |
+
'style_class' => 'button-primary',
|
57 |
+
'data' => array(
|
58 |
+
'clicked-value' => __( 'Updating Site Configuration...', 'better-wp-security' ),
|
59 |
+
),
|
60 |
+
) );
|
61 |
+
$feedback->add_input( 'hidden', 'method', array(
|
62 |
+
'value' => 'enable-ssl',
|
63 |
+
) );
|
64 |
+
}
|
65 |
+
}
|
66 |
+
|
67 |
+
return $response;
|
68 |
+
}
|
69 |
+
|
70 |
+
public static function handle_enable_ssl( $data ) {
|
71 |
+
$settings = ITSEC_Modules::get_settings( 'ssl' );
|
72 |
+
|
73 |
+
$settings['require_ssl'] = 'enabled';
|
74 |
+
|
75 |
+
$results = ITSEC_Modules::set_settings( 'ssl', $settings );
|
76 |
+
|
77 |
+
if ( is_wp_error( $results ) ) {
|
78 |
+
ITSEC_Response::add_error( $results );
|
79 |
+
} elseif ( $results['saved'] ) {
|
80 |
+
ITSEC_Modules::activate( 'ssl' );
|
81 |
+
ITSEC_Response::add_js_function_call( 'setModuleToActive', 'ssl' );
|
82 |
+
ITSEC_Response::set_response( '<p>' . __( 'Your site now redirects http page requests to https.', 'better-wp-security' ) . '</p>' );
|
83 |
+
ITSEC_Response::reload_module( 'ssl' );
|
84 |
+
}
|
85 |
+
}
|
86 |
+
|
87 |
+
public static function handle_scan_request() {
|
88 |
+
if ( ! isset( $_POST['itsec-security-check'] ) || 'scan' !== $_POST['itsec-security-check'] ) {
|
89 |
+
return;
|
90 |
+
}
|
91 |
+
|
92 |
+
if ( ! isset( $_POST['site'], $_POST['key'], $_POST['expect'], $_POST['scheme'] ) ) {
|
93 |
+
return;
|
94 |
+
}
|
95 |
+
|
96 |
+
if ( ! self::validate_key( $_POST['key'] ) ) {
|
97 |
+
return;
|
98 |
+
}
|
99 |
+
|
100 |
+
if ( defined( 'ITSEC_DISABLE_AUTOMATIC_REMOTE_IP_DETECTION' ) && ITSEC_DISABLE_AUTOMATIC_REMOTE_IP_DETECTION ) {
|
101 |
+
$remote_ip_index = '';
|
102 |
+
} else {
|
103 |
+
$remote_ip_index = self::get_remote_ip_index();
|
104 |
+
|
105 |
+
if ( false === $remote_ip_index ) {
|
106 |
+
$remote_ip_index = '';
|
107 |
+
}
|
108 |
+
}
|
109 |
+
|
110 |
+
if ( 'https' === $_POST['scheme'] && is_ssl() ) {
|
111 |
+
$ssl_supported = true;
|
112 |
+
} else {
|
113 |
+
$ssl_supported = false;
|
114 |
+
}
|
115 |
+
|
116 |
+
$settings = array(
|
117 |
+
'last_scan_timestamp' => time(),
|
118 |
+
'remote_ip_index' => $remote_ip_index,
|
119 |
+
'ssl_supported' => $ssl_supported,
|
120 |
+
);
|
121 |
+
|
122 |
+
ITSEC_Modules::set_settings( 'security-check-pro', $settings );
|
123 |
+
|
124 |
+
header( 'Content-Type: text/plain' );
|
125 |
+
echo "<response>{$_POST['expect']}:" . ( empty( $remote_ip_index ) ? 'false' : 'true' ) . ':' . ( $ssl_supported ? 'true' : 'false' ) . '</response>';
|
126 |
+
exit();
|
127 |
+
}
|
128 |
+
|
129 |
+
public static function get_remote_ip_index() {
|
130 |
+
$remote_ips = self::get_remote_ips();
|
131 |
+
|
132 |
+
|
133 |
+
$standard_indexes = array(
|
134 |
+
'REMOTE_ADDR',
|
135 |
+
'HTTP_X_REAL_IP',
|
136 |
+
'HTTP_X_FORWARDED_FOR',
|
137 |
+
'HTTP_CF_CONNECTING_IP',
|
138 |
+
'HTTP_CLIENT_IP',
|
139 |
+
);
|
140 |
+
|
141 |
+
foreach ( $remote_ips as $ip ) {
|
142 |
+
foreach ( $standard_indexes as $standard_index ) {
|
143 |
+
$index = self::get_index( $ip, $standard_index );
|
144 |
+
|
145 |
+
if ( false !== $index ) {
|
146 |
+
return $index;
|
147 |
+
}
|
148 |
+
}
|
149 |
+
}
|
150 |
+
|
151 |
+
|
152 |
+
foreach ( $remote_ips as $ip ) {
|
153 |
+
foreach ( array_keys( $_SERVER ) as $var ) {
|
154 |
+
$index = self::get_index( $ip, $var );
|
155 |
+
|
156 |
+
if ( false !== $index ) {
|
157 |
+
return $index;
|
158 |
+
}
|
159 |
+
}
|
160 |
+
}
|
161 |
+
|
162 |
+
|
163 |
+
return false;
|
164 |
+
}
|
165 |
+
|
166 |
+
public static function get_index( $ip, $var ) {
|
167 |
+
if ( ! isset( $_SERVER[ $var ] ) ) {
|
168 |
+
return false;
|
169 |
+
}
|
170 |
+
|
171 |
+
if ( $_SERVER[ $var ] === $ip ) {
|
172 |
+
return $var;
|
173 |
+
}
|
174 |
+
|
175 |
+
$value = trim( $_SERVER[ $var ] );
|
176 |
+
$ip_regex_pattern = '/' . preg_quote( $ip, '/' ) . '/';
|
177 |
+
|
178 |
+
if ( preg_match( $ip_regex_pattern, $value ) ) {
|
179 |
+
$potential_ips = preg_split( '/[, ]+/', $value );
|
180 |
+
|
181 |
+
foreach ( $potential_ips as $index => $potential_ip ) {
|
182 |
+
if ( $ip === $potential_ip ) {
|
183 |
+
return array( $var, $index );
|
184 |
+
}
|
185 |
+
}
|
186 |
+
|
187 |
+
if ( preg_match_all( '{(?:for)=(?:"?\[?)([a-z0-9\.:_\-/]*)}i', $value, $matches, PREG_SET_ORDER ) ) {
|
188 |
+
foreach ( $matches as $index => $match ) {
|
189 |
+
if ( $ip === $match[1] ) {
|
190 |
+
return array( $var, $index );
|
191 |
+
}
|
192 |
+
}
|
193 |
+
}
|
194 |
+
}
|
195 |
+
|
196 |
+
return false;
|
197 |
+
}
|
198 |
+
|
199 |
+
public static function get_server_response() {
|
200 |
+
$data = array(
|
201 |
+
'site' => get_home_url(),
|
202 |
+
'key' => self::get_key(),
|
203 |
+
);
|
204 |
+
|
205 |
+
$remote_post_args = array(
|
206 |
+
'timeout' => 60,
|
207 |
+
'body' => $data,
|
208 |
+
);
|
209 |
+
|
210 |
+
$response = wp_remote_post( self::$api_url, $remote_post_args );
|
211 |
+
|
212 |
+
if ( is_wp_error( $response ) && ( 'connect() timed out!' !== $response->get_error_message() ) ) {
|
213 |
+
$url = preg_replace( '|^https://|', 'http://', self::$api_url );
|
214 |
+
$response = wp_remote_post( $url, $remote_post_args );
|
215 |
+
}
|
216 |
+
|
217 |
+
if ( is_wp_error( $response ) ) {
|
218 |
+
if ( 'connect() timed out!' === $response->get_error_message() ) {
|
219 |
+
return new WP_Error( 'http_request_failed', __( 'The server was unable to be contacted.', 'better-wp-security' ) );
|
220 |
+
}
|
221 |
+
|
222 |
+
return $response;
|
223 |
+
}
|
224 |
+
|
225 |
+
if ( '' === trim( $response['body'] ) ) {
|
226 |
+
return new WP_Error( 'itsec-security-check-pro-empty-response', __( 'An error occurred when communicating with the iThemes Security Check server: The server returned a blank response.', 'better-wp-security' ) );
|
227 |
+
}
|
228 |
+
|
229 |
+
$body = json_decode( $response['body'], true );
|
230 |
+
|
231 |
+
if ( is_null( $body ) ) {
|
232 |
+
return new WP_Error( 'itsec-security-check-pro-non-json-response', __( 'An error occurred when communicating with the iThemes Security Check server: The server did not return JSON data when JSON data was expected.', 'better-wp-security' ) );
|
233 |
+
}
|
234 |
+
|
235 |
+
if ( isset( $body['error'], $body['error']['code'], $body['error']['message'] ) ) {
|
236 |
+
return new WP_Error( 'itsec-security-check-pro-' . $body['error']['code'], sprintf( __( 'An error occurred when communicating with the iThemes Security Check server: %s (%s)', 'better-wp-security' ), $body['error']['message'], $body['error']['code'] ) );
|
237 |
+
}
|
238 |
+
|
239 |
+
if ( empty( $body['complete'] ) ) {
|
240 |
+
return new WP_Error( 'itsec-security-check-pro-scan-incomplete', __( 'The iThemes Security Check server could not contact your site. Please wait a few minutes and try again.', 'better-wp-security' ) );
|
241 |
+
}
|
242 |
+
|
243 |
+
return $body;
|
244 |
+
}
|
245 |
+
|
246 |
+
public static function validate_key( $key, $expires = false ) {
|
247 |
+
$salt = ITSEC_Modules::get_setting( 'security-check-pro', 'key_salt' );
|
248 |
+
$key = trim( $key );
|
249 |
+
|
250 |
+
if ( empty( $salt ) ) {
|
251 |
+
return false; // Only validate if a salt has been stored.
|
252 |
+
}
|
253 |
+
|
254 |
+
if ( ! preg_match( '/^(\d+):([a-f0-9]+)$/', $key, $matches ) ) {
|
255 |
+
return false;
|
256 |
+
}
|
257 |
+
|
258 |
+
if ( false === $expires ) {
|
259 |
+
$expires = 2 * MINUTE_IN_SECONDS; // keys expire every 2 minutes by default.
|
260 |
+
}
|
261 |
+
|
262 |
+
$time = $matches[1];
|
263 |
+
$hash = $matches[2];
|
264 |
+
|
265 |
+
if ( time() > $time + $expires ) {
|
266 |
+
return false;
|
267 |
+
}
|
268 |
+
|
269 |
+
$calculated_hash = hash_hmac( 'md5', $time, $salt );
|
270 |
+
|
271 |
+
return hash_equals( $calculated_hash, $hash );
|
272 |
+
}
|
273 |
+
|
274 |
+
public static function get_key() {
|
275 |
+
$salt = ITSEC_Modules::get_setting( 'security-check-pro', 'key_salt' );
|
276 |
+
|
277 |
+
if ( empty( $salt ) ) {
|
278 |
+
$salt = wp_generate_password( 60, true, true );
|
279 |
+
ITSEC_Modules::set_setting( 'security-check-pro', 'key_salt', $salt );
|
280 |
+
ITSEC_Storage::save();
|
281 |
+
}
|
282 |
+
|
283 |
+
$time = time();
|
284 |
+
$hash = hash_hmac( 'md5', $time, $salt );
|
285 |
+
|
286 |
+
$key = "$time:$hash";
|
287 |
+
|
288 |
+
return $key;
|
289 |
+
}
|
290 |
+
|
291 |
+
public static function get_remote_ips() {
|
292 |
+
$remote_ips = apply_filters( 'itsec-security-check-pro-remote-ips', array() );
|
293 |
+
|
294 |
+
if ( is_array( $remote_ips ) && ! empty( $remote_ips ) ) {
|
295 |
+
return $remote_ips;
|
296 |
+
}
|
297 |
+
|
298 |
+
|
299 |
+
$settings = ITSEC_Modules::get_settings( 'security-check-pro' );
|
300 |
+
|
301 |
+
if ( $settings['remote_ips_timestamp'] + ( 5 * MINUTE_IN_SECONDS ) > time() && ! empty( $settings['remote_ips'] ) ) {
|
302 |
+
return $settings['remote_ips'];
|
303 |
+
}
|
304 |
+
|
305 |
+
|
306 |
+
$response = wp_remote_get( self::$config_url );
|
307 |
+
|
308 |
+
if ( is_wp_error( $response ) ) {
|
309 |
+
return array();
|
310 |
+
}
|
311 |
+
|
312 |
+
|
313 |
+
$body = $response['body'];
|
314 |
+
$data = json_decode( $body, true );
|
315 |
+
|
316 |
+
if ( ! is_array( $data ) || ! isset( $data['ips'] ) || ! is_array( $data['ips'] ) ) {
|
317 |
+
return array();
|
318 |
+
}
|
319 |
+
|
320 |
+
|
321 |
+
$settings['remote_ips_timestamp'] = time();
|
322 |
+
$settings['remote_ips'] = $data['ips'];
|
323 |
+
|
324 |
+
ITSEC_Modules::set_settings( 'security-check-pro', $settings );
|
325 |
+
|
326 |
+
return $data['ips'];
|
327 |
+
}
|
328 |
+
}
|
core/modules/security-check-pro/validator.php
ADDED
@@ -0,0 +1,43 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
final class ITSEC_Security_Check_Pro_Validator extends ITSEC_Validator {
|
4 |
+
public function get_id() {
|
5 |
+
return 'security-check-pro';
|
6 |
+
}
|
7 |
+
|
8 |
+
protected function sanitize_settings() {
|
9 |
+
$this->set_previous_if_empty( array_keys( $this->defaults ) );
|
10 |
+
$this->vars_to_skip_validate_matching_fields = array_keys( $this->defaults );
|
11 |
+
$this->vars_to_skip_validate_matching_types = array_keys( $this->defaults );
|
12 |
+
|
13 |
+
if ( ! is_null( $this->settings['last_scan_timestamp'] ) && ! is_int( $this->settings['last_scan_timestamp'] ) || $this->settings['last_scan_timestamp'] < 0 ) {
|
14 |
+
$this->settings['last_scan_timestamp'] = $this->defaults['last_scan_timestamp'];
|
15 |
+
}
|
16 |
+
|
17 |
+
if ( is_array( $this->settings['remote_ip_index'] ) ) {
|
18 |
+
if ( 2 !== count( $this->settings['remote_ip_index'] ) || ! is_string( $this->settings['remote_ip_index'][0] ) || ! is_int( $this->settings['remote_ip_index'][1] ) ) {
|
19 |
+
$this->settings['remote_ip_index'] = $this->defaults['remote_ip_index'];
|
20 |
+
}
|
21 |
+
} else if ( ! is_null( $this->settings['remote_ip_index'] ) && ! is_string( $this->settings['remote_ip_index'] ) ) {
|
22 |
+
$this->settings['remote_ip_index'] = $this->defaults['remote_ip_index'];
|
23 |
+
}
|
24 |
+
|
25 |
+
if ( ! is_null( $this->settings['ssl_supported'] ) && ! is_bool( $this->settings['ssl_supported'] ) ) {
|
26 |
+
$this->settings['ssl_supported'] = $this->defaults['ssl_supported'];
|
27 |
+
}
|
28 |
+
|
29 |
+
if ( ! is_int( $this->settings['remote_ips_timestamp'] ) ) {
|
30 |
+
$this->settings['remote_ips_timestamp'] = $this->defaults['remote_ips_timestamp'];
|
31 |
+
}
|
32 |
+
|
33 |
+
if ( ! is_array( $this->settings['remote_ips'] ) ) {
|
34 |
+
$this->settings['remote_ips'] = $this->defaults['remote_ips'];
|
35 |
+
}
|
36 |
+
|
37 |
+
if ( ! is_string( $this->settings['key_salt'] ) ) {
|
38 |
+
$this->settings['key_salt'] = $this->defaults['key_salt'];
|
39 |
+
}
|
40 |
+
}
|
41 |
+
}
|
42 |
+
|
43 |
+
ITSEC_Modules::register_validator( new ITSEC_Security_Check_Pro_Validator() );
|
core/modules/security-check/js/settings-page.js
CHANGED
@@ -12,7 +12,8 @@ jQuery( document ).ready( function ( $ ) {
|
|
12 |
$( '#itsec-security-check-details-container' ).html( '' );
|
13 |
|
14 |
var data = {
|
15 |
-
'method': 'secure-site'
|
|
|
16 |
};
|
17 |
|
18 |
itsecUtil.sendModuleAJAXRequest( 'security-check', data, function( results ) {
|
12 |
$( '#itsec-security-check-details-container' ).html( '' );
|
13 |
|
14 |
var data = {
|
15 |
+
'method': 'secure-site',
|
16 |
+
pro: $( '#itsec-security-check-security_check_pro' ).is( ':checked' ),
|
17 |
};
|
18 |
|
19 |
itsecUtil.sendModuleAJAXRequest( 'security-check', data, function( results ) {
|
core/modules/security-check/settings-page.php
CHANGED
@@ -1,16 +1,15 @@
|
|
1 |
<?php
|
2 |
|
3 |
final class ITSEC_Security_Check_Settings_Page extends ITSEC_Module_Settings_Page {
|
4 |
-
private $script_version =
|
5 |
-
|
6 |
|
7 |
public function __construct() {
|
8 |
-
$this->id
|
9 |
-
$this->title
|
10 |
-
$this->description
|
11 |
-
$this->type
|
12 |
$this->information_only = true;
|
13 |
-
$this->can_save
|
14 |
|
15 |
parent::__construct();
|
16 |
}
|
@@ -27,6 +26,12 @@ final class ITSEC_Security_Check_Settings_Page extends ITSEC_Module_Settings_Pag
|
|
27 |
|
28 |
public function handle_ajax_request( $data ) {
|
29 |
if ( 'secure-site' === $data['method'] ) {
|
|
|
|
|
|
|
|
|
|
|
|
|
30 |
require_once( dirname( __FILE__ ) . '/scanner.php' );
|
31 |
require_once( dirname( __FILE__ ) . '/feedback-renderer.php' );
|
32 |
|
@@ -35,7 +40,7 @@ final class ITSEC_Security_Check_Settings_Page extends ITSEC_Module_Settings_Pag
|
|
35 |
ob_start();
|
36 |
ITSEC_Security_Check_Feedback_Renderer::render( $results );
|
37 |
ITSEC_Response::set_response( ob_get_clean() );
|
38 |
-
}
|
39 |
require_once( dirname( __FILE__ ) . '/scanner.php' );
|
40 |
|
41 |
ITSEC_Security_Check_Scanner::activate_network_brute_force( $_POST['data'] );
|
@@ -44,27 +49,39 @@ final class ITSEC_Security_Check_Settings_Page extends ITSEC_Module_Settings_Pag
|
|
44 |
}
|
45 |
}
|
46 |
|
47 |
-
protected function render_description( $form ) {}
|
48 |
|
49 |
protected function render_settings( $form ) {
|
50 |
require_once( dirname( __FILE__ ) . '/scanner.php' );
|
51 |
|
52 |
$modules_to_activate = ITSEC_Security_Check_Scanner::get_supported_modules();
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
<?php
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
67 |
|
68 |
}
|
69 |
}
|
|
|
70 |
new ITSEC_Security_Check_Settings_Page();
|
1 |
<?php
|
2 |
|
3 |
final class ITSEC_Security_Check_Settings_Page extends ITSEC_Module_Settings_Page {
|
4 |
+
private $script_version = 4;
|
|
|
5 |
|
6 |
public function __construct() {
|
7 |
+
$this->id = 'security-check';
|
8 |
+
$this->title = __( 'Security Check', 'better-wp-security' );
|
9 |
+
$this->description = __( 'Ensure that your site is using the recommended features and settings.', 'better-wp-security' );
|
10 |
+
$this->type = 'recommended';
|
11 |
$this->information_only = true;
|
12 |
+
$this->can_save = false;
|
13 |
|
14 |
parent::__construct();
|
15 |
}
|
26 |
|
27 |
public function handle_ajax_request( $data ) {
|
28 |
if ( 'secure-site' === $data['method'] ) {
|
29 |
+
if ( ! empty( $data['pro'] ) ) {
|
30 |
+
ITSEC_Modules::activate( 'security-check-pro' );
|
31 |
+
ITSEC_Modules::load_module_file( 'active.php', 'security-check-pro' );
|
32 |
+
ITSEC_Response::remove_js_function_call( 'reloadModule', 'security-check' );
|
33 |
+
}
|
34 |
+
|
35 |
require_once( dirname( __FILE__ ) . '/scanner.php' );
|
36 |
require_once( dirname( __FILE__ ) . '/feedback-renderer.php' );
|
37 |
|
40 |
ob_start();
|
41 |
ITSEC_Security_Check_Feedback_Renderer::render( $results );
|
42 |
ITSEC_Response::set_response( ob_get_clean() );
|
43 |
+
} elseif ( 'activate-network-brute-force' === $data['method'] ) {
|
44 |
require_once( dirname( __FILE__ ) . '/scanner.php' );
|
45 |
|
46 |
ITSEC_Security_Check_Scanner::activate_network_brute_force( $_POST['data'] );
|
49 |
}
|
50 |
}
|
51 |
|
52 |
+
protected function render_description( $form ) { }
|
53 |
|
54 |
protected function render_settings( $form ) {
|
55 |
require_once( dirname( __FILE__ ) . '/scanner.php' );
|
56 |
|
57 |
$modules_to_activate = ITSEC_Security_Check_Scanner::get_supported_modules();
|
58 |
+
?>
|
59 |
+
<div id="itsec-security-check-details-container">
|
60 |
+
<p><?php _e( 'Some features and settings are recommended for every site to run. This tool will ensure that your site is using these recommendations.', 'better-wp-security' ); ?></p>
|
61 |
+
<p><?php _e( 'When the button below is clicked the following modules will be enabled and configured:', 'better-wp-security' ); ?></p>
|
62 |
+
<ul class="itsec-security-check-list">
|
63 |
+
<?php foreach ( $modules_to_activate as $name ) : ?>
|
64 |
+
<li><p><?php echo $name; ?></p></li>
|
65 |
+
<?php endforeach; ?>
|
66 |
+
</ul>
|
67 |
+
|
68 |
+
<?php if ( ! ITSEC_Modules::is_active( 'security-check-pro' ) ) : ?>
|
69 |
+
<p>
|
70 |
+
<label>
|
71 |
+
<?php $form->add_checkbox( 'security_check_pro' ); ?>
|
72 |
+
<?php printf(
|
73 |
+
esc_html__( 'Enable Security Check Pro to identify IP addresses and ensure attackers are locked out correctly. This requires contacting an iThemes.com server. Read our %1$sPrivacy Policy%2$s.', 'better-wp-security' ),
|
74 |
+
'<a href="https://ithemes.com/privacy-policy/" target="_blank">',
|
75 |
+
'</a>'
|
76 |
+
); ?>
|
77 |
+
</label>
|
78 |
+
</p>
|
79 |
+
<?php endif; ?>
|
80 |
+
</div>
|
81 |
+
<p><?php $form->add_button( 'secure_site', array( 'value' => 'Secure Site', 'class' => 'button-primary' ) ); ?></p>
|
82 |
+
<?php
|
83 |
|
84 |
}
|
85 |
}
|
86 |
+
|
87 |
new ITSEC_Security_Check_Settings_Page();
|
core/package.json
CHANGED
@@ -110,7 +110,8 @@
|
|
110 |
"test-unit:update": "npm run test-unit -- --updateSnapshot",
|
111 |
"test-unit:watch": "npm run test-unit -- --watch",
|
112 |
"watch": "./node_modules/.bin/webpack --watch",
|
113 |
-
"test-
|
114 |
-
"test-acceptance
|
|
|
115 |
}
|
116 |
}
|
110 |
"test-unit:update": "npm run test-unit -- --updateSnapshot",
|
111 |
"test-unit:watch": "npm run test-unit -- --watch",
|
112 |
"watch": "./node_modules/.bin/webpack --watch",
|
113 |
+
"test-wpunit": "docker-compose exec -T -w /var/www/html/wp-content/plugins/ithemes-security-pro wordpress ./vendor/bin/codecept run wpunit",
|
114 |
+
"test-acceptance": "docker-compose exec -T -w /var/www/html/wp-content/plugins/ithemes-security-pro wordpress ./vendor/bin/codecept run acceptance",
|
115 |
+
"test-acceptance:build": "docker-compose exec -T -w /var/www/html/wp-content/plugins/ithemes-security-pro wordpress ./vendor/bin/codecept build"
|
116 |
}
|
117 |
}
|
core/response.php
CHANGED
@@ -153,6 +153,15 @@ final class ITSEC_Response {
|
|
153 |
return $self->js_function_calls;
|
154 |
}
|
155 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
156 |
public static function set_show_default_success_message( $show_default_success_message ) {
|
157 |
$self = self::get_instance();
|
158 |
|
153 |
return $self->js_function_calls;
|
154 |
}
|
155 |
|
156 |
+
public static function remove_js_function_call( $js_function, $args = null ) {
|
157 |
+
$self = self::get_instance();
|
158 |
+
$call = is_null( $args ) ? array( $js_function ) : array( $js_function, $args );
|
159 |
+
|
160 |
+
$self->js_function_calls = array_values( array_filter( $self->js_function_calls, static function ( $maybe_call ) use ( $call ) {
|
161 |
+
return $maybe_call !== $call;
|
162 |
+
} ) );
|
163 |
+
}
|
164 |
+
|
165 |
public static function set_show_default_success_message( $show_default_success_message ) {
|
166 |
$self = self::get_instance();
|
167 |
|
history.txt
CHANGED
@@ -859,3 +859,7 @@
|
|
859 |
Bug Fix: Admin Notices list did not refresh after dismissing a notice.
|
860 |
Bug Fix: Strong Passwords zxcvbn Library was not evaluating penalty strings correctly.
|
861 |
Bug Fix: Fix PHP warning if there are multiple detected proxy headers.
|
|
|
|
|
|
|
|
859 |
Bug Fix: Admin Notices list did not refresh after dismissing a notice.
|
860 |
Bug Fix: Strong Passwords zxcvbn Library was not evaluating penalty strings correctly.
|
861 |
Bug Fix: Fix PHP warning if there are multiple detected proxy headers.
|
862 |
+
7.6.0 - 2019-12-09 - Timothy Jacobs
|
863 |
+
New Feature: iThemes Security now includes Security Check Pro to automatically and correctly determine your visitors IP addresses. Enable this scan by running Security Check and opting in to Security Check Pro or activate the Security Check Pro module in Advanced Modules. H/t Jeremy Voisin
|
864 |
+
Enhancement: Run Security Check Pro IP Detection automatically once a day.
|
865 |
+
Enhancement: Manually re-run Security Check Pro IP Detection from the Global Settings page.
|
package.json
CHANGED
@@ -110,7 +110,8 @@
|
|
110 |
"test-unit:update": "npm run test-unit -- --updateSnapshot",
|
111 |
"test-unit:watch": "npm run test-unit -- --watch",
|
112 |
"watch": "./node_modules/.bin/webpack --watch",
|
113 |
-
"test-
|
114 |
-
"test-acceptance
|
|
|
115 |
}
|
116 |
}
|
110 |
"test-unit:update": "npm run test-unit -- --updateSnapshot",
|
111 |
"test-unit:watch": "npm run test-unit -- --watch",
|
112 |
"watch": "./node_modules/.bin/webpack --watch",
|
113 |
+
"test-wpunit": "docker-compose exec -T -w /var/www/html/wp-content/plugins/ithemes-security-pro wordpress ./vendor/bin/codecept run wpunit",
|
114 |
+
"test-acceptance": "docker-compose exec -T -w /var/www/html/wp-content/plugins/ithemes-security-pro wordpress ./vendor/bin/codecept run acceptance",
|
115 |
+
"test-acceptance:build": "docker-compose exec -T -w /var/www/html/wp-content/plugins/ithemes-security-pro wordpress ./vendor/bin/codecept build"
|
116 |
}
|
117 |
}
|
readme.txt
CHANGED
@@ -3,7 +3,7 @@ Contributors: ithemes, chrisjean, 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.7
|
5 |
Tested up to: 5.3.0
|
6 |
-
Stable tag: 7.
|
7 |
Requires PHP: 5.4
|
8 |
License: GPLv2 or later
|
9 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
@@ -189,6 +189,11 @@ Free support may be available with the help of the community in the <a href="htt
|
|
189 |
|
190 |
== Changelog ==
|
191 |
|
|
|
|
|
|
|
|
|
|
|
192 |
= 7.5.0 =
|
193 |
* Breaking Change: iThemes Security requires PHP 5.4 or later.
|
194 |
* Enhancement: New Lockout Template screen.
|
@@ -560,5 +565,5 @@ Free support may be available with the help of the community in the <a href="htt
|
|
560 |
|
561 |
== Upgrade Notice ==
|
562 |
|
563 |
-
= 7.
|
564 |
-
Version 7.
|
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.7
|
5 |
Tested up to: 5.3.0
|
6 |
+
Stable tag: 7.6.0
|
7 |
Requires PHP: 5.4
|
8 |
License: GPLv2 or later
|
9 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
189 |
|
190 |
== Changelog ==
|
191 |
|
192 |
+
= 7.6.0 =
|
193 |
+
* New Feature: iThemes Security now includes Security Check Pro to automatically and correctly determine your visitors IP addresses. Enable this scan by running Security Check and opting in to Security Check Pro or activate the Security Check Pro module in Advanced Modules. H/t Jeremy Voisin
|
194 |
+
* Enhancement: Run Security Check Pro IP Detection automatically once a day.
|
195 |
+
* Enhancement: Manually re-run Security Check Pro IP Detection from the Global Settings page.
|
196 |
+
|
197 |
= 7.5.0 =
|
198 |
* Breaking Change: iThemes Security requires PHP 5.4 or later.
|
199 |
* Enhancement: New Lockout Template screen.
|
565 |
|
566 |
== Upgrade Notice ==
|
567 |
|
568 |
+
= 7.6.0 =
|
569 |
+
Version 7.6.0 contains new features and bug fixes. It is recommended for all users.
|