Sucuri Security – Auditing, Malware Scanner and Security Hardening - Version 1.8.0

Version Description

  • Added error message when storage is not writable
  • Fixed option getter to migrate plugin settings if possible
  • Fixed base directory name without PHP DIR constant
  • Fixed user authentication denial when no blocked users
  • Fixed htaccess standard rules checker with no WP_Rewrite
Download this release

Release Info

Developer yorman
Plugin Icon 128x128 Sucuri Security – Auditing, Malware Scanner and Security Hardening
Version 1.8.0
Comparing to
See all releases

Code changes from version 1.7.19 to 1.8.0

Files changed (2) hide show
  1. readme.txt +8 -1
  2. sucuri.php +88 -31
readme.txt CHANGED
@@ -3,7 +3,7 @@ Contributors: dd@sucuri.net
3
Donate Link: https://sucuri.net/
4
Tags: malware, security, firewall, scan, spam, virus, sucuri, protection,WordPress Security, Login Security,Security Auditing,File Integrity,htaccess,phishing,backdoors,SQL Injection, RFI, LFI, XSS, CSRF, website firewall, Website Security, Performance Optimization, Zero Day, Software Vulnerability, Exploits, Hacks, Attackers, Bad Actors, Reverse Proxy, Two Factor Security, Two Factor Authentication, Security Logs, HeatBleed Vulnerability, Website Protection, Bash Vulnerability, RevSlider Vulnerability, MailPoet Vulnerability, Malware Prevention, Website Firewall, Website AntiVirus, Security Response, Security Detection, Security Prevention
5
Requires at least:3.2
6
- Stable tag: 1.7.19
7
Tested up to: 4.5.3
8
9
The Sucuri WordPress Security plugin is a security toolset for security integrity monitoring, malware detection and security hardening.
@@ -354,6 +354,13 @@ service from the WordPress dashboard.
354
355
== Changelog ==
356
357
= 1.7.19 =
358
* Added function to rescue HTTP requests using sockets
359
* Fixed mishandled JSON data in audit logs Ajax request
3
Donate Link: https://sucuri.net/
4
Tags: malware, security, firewall, scan, spam, virus, sucuri, protection,WordPress Security, Login Security,Security Auditing,File Integrity,htaccess,phishing,backdoors,SQL Injection, RFI, LFI, XSS, CSRF, website firewall, Website Security, Performance Optimization, Zero Day, Software Vulnerability, Exploits, Hacks, Attackers, Bad Actors, Reverse Proxy, Two Factor Security, Two Factor Authentication, Security Logs, HeatBleed Vulnerability, Website Protection, Bash Vulnerability, RevSlider Vulnerability, MailPoet Vulnerability, Malware Prevention, Website Firewall, Website AntiVirus, Security Response, Security Detection, Security Prevention
5
Requires at least:3.2
6
+ Stable tag: 1.8.0
7
Tested up to: 4.5.3
8
9
The Sucuri WordPress Security plugin is a security toolset for security integrity monitoring, malware detection and security hardening.
354
355
== Changelog ==
356
357
+ = 1.8.0 =
358
+ * Added error message when storage is not writable
359
+ * Fixed option getter to migrate plugin settings if possible
360
+ * Fixed base directory name without PHP __DIR__ constant
361
+ * Fixed user authentication denial when no blocked users
362
+ * Fixed htaccess standard rules checker with no WP_Rewrite
363
+
364
= 1.7.19 =
365
* Added function to rescue HTTP requests using sockets
366
* Fixed mishandled JSON data in audit logs Ajax request
sucuri.php CHANGED
@@ -4,7 +4,7 @@ Plugin Name: Sucuri Security - Auditing, Malware Scanner and Hardening
4
Plugin URI: https://wordpress.sucuri.net/
5
Description: The <a href="https://sucuri.net/" target="_blank">Sucuri</a> plugin provides the website owner the best Activity Auditing, SiteCheck Remote Malware Scanning, Effective Security Hardening and Post-Hack features. SiteCheck will check for malware, spam, blacklisting and other security issues like .htaccess redirects, hidden eval code, etc. The best thing about it is it's completely free.
6
Author: Sucuri, INC
7
- Version: 1.7.19
8
Author URI: https://sucuri.net
9
*/
10
@@ -65,7 +65,7 @@ define('SUCURISCAN', 'sucuriscan');
65
/**
66
* Current version of the plugin's code.
67
*/
68
- define('SUCURISCAN_VERSION', '1.7.19');
69
70
/**
71
* The name of the Sucuri plugin main file.
@@ -74,8 +74,14 @@ define('SUCURISCAN_PLUGIN_FILE', 'sucuri.php');
74
75
/**
76
* The name of the folder where the plugin's files will be located.
77
*/
78
- define('SUCURISCAN_PLUGIN_FOLDER', basename(__DIR__));
79
80
/**
81
* The fullpath where the plugin's files will be located.
@@ -1847,6 +1853,8 @@ class SucuriScanFileInfo extends SucuriScan
1847
}
1848
1849
if (is_array($tree) && !empty($tree)) {
1850
return array_map(array('SucuriScan', 'fixPath'), $tree);
1851
}
1852
}
@@ -2165,12 +2173,15 @@ class SucuriScanFileInfo extends SucuriScan
2165
foreach ($dir_tree as $filepath) {
2166
$dir_path = dirname($filepath);
2167
2168
- if (is_array($dirs)
2169
- && !in_array($dir_path, $dirs)
2170
- && array_key_exists('directories', $this->ignored_directories)
2171
- && is_array($this->ignored_directories['directories'])
2172
- && !in_array($dir_path, $this->ignored_directories['directories'])
2173
- ) {
2174
$dirs[] = $dir_path;
2175
}
2176
}
@@ -3146,14 +3157,21 @@ class SucuriScanOption extends SucuriScanRequest
3146
* If the option is not in the external file nor in the database, and
3147
* the name starts with the same prefix used by the plugin then we must
3148
* return the default value defined by the author.
3149
*/
3150
if (function_exists('get_option')) {
3151
$value = get_option($option);
3152
3153
if ($value !== false) {
3154
if (strpos($option, 'sucuriscan_') === 0) {
3155
- delete_option($option);
3156
- self::update_option($option, $value);
3157
}
3158
3159
return $value;
@@ -5076,6 +5094,22 @@ class SucuriScanAPI extends SucuriScanOption
5076
return substr($trail, 1);
5077
}
5078
5079
/**
5080
* Assign the communication protocol.
5081
*
@@ -5298,8 +5332,11 @@ class SucuriScanAPI extends SucuriScanOption
5298
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $method);
5299
curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, $timeout);
5300
curl_setopt($curl, CURLOPT_TIMEOUT, $timeout * 2);
5301
- curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
5302
- curl_setopt($curl, CURLOPT_MAXREDIRS, 2);
5303
5304
if ($method === 'POST') {
5305
curl_setopt($curl, CURLOPT_POST, true);
@@ -12544,7 +12581,10 @@ class SucuriScanBlockedUsers extends SucuriScanLastLogins
12544
$blocked = $cache->getAll();
12545
$cache_key = md5($username);
12546
12547
- if (array_key_exists($cache_key, $blocked)) {
12548
$blocked[$cache_key]->last_attempt = time();
12549
$cache->set($cache_key, $blocked[$cache_key]);
12550
@@ -12612,21 +12652,6 @@ function sucuriscan_settings_form_submissions($page_nonce = null)
12612
}
12613
12614
if ($page_nonce) {
12615
- // Save API key after it was recovered by the administrator.
12616
- if ($api_key = SucuriScanRequest::post(':manual_api_key')) {
12617
- SucuriScanAPI::setPluginKey($api_key, true);
12618
- SucuriScanEvent::schedule_task();
12619
- SucuriScanEvent::report_info_event('Sucuri API key was added manually.');
12620
- }
12621
-
12622
- // Remove API key from the local storage.
12623
- if (SucuriScanRequest::post(':remove_api_key') !== false) {
12624
- SucuriScanAPI::setPluginKey('');
12625
- wp_clear_scheduled_hook('sucuriscan_scheduled_scan');
12626
- SucuriScanEvent::report_critical_event('Sucuri API key was deleted.');
12627
- SucuriScanEvent::notify_event('plugin_change', 'Sucuri API key removed');
12628
- }
12629
-
12630
// Enable or disable the filesystem scanner.
12631
if ($fs_scanner = SucuriScanRequest::post(':fs_scanner', '(en|dis)able')) {
12632
$action_d = $fs_scanner . 'd';
@@ -12899,6 +12924,33 @@ function sucuriscan_settings_general_apikey($nonce)
12899
$display_manual_key_form = (bool) (SucuriScanRequest::post(':recover_key') !== false);
12900
12901
if ($nonce) {
12902
if (SucuriScanRequest::post(':plugin_api_key') !== false) {
12903
$user_id = SucuriScanRequest::post(':setup_user');
12904
$user_obj = SucuriScan::get_user_by_id($user_id);
@@ -14755,11 +14807,16 @@ function sucuriscan_htaccess_is_standard($rules = false)
14755
}
14756
}
14757
14758
- if (is_string($rules) && !empty($rules)) {
14759
$rewrite = new WP_Rewrite();
14760
$standard = $rewrite->mod_rewrite_rules();
14761
14762
- return (bool) (strpos($rules, $standard) !== false);
14763
}
14764
14765
return false;
4
Plugin URI: https://wordpress.sucuri.net/
5
Description: The <a href="https://sucuri.net/" target="_blank">Sucuri</a> plugin provides the website owner the best Activity Auditing, SiteCheck Remote Malware Scanning, Effective Security Hardening and Post-Hack features. SiteCheck will check for malware, spam, blacklisting and other security issues like .htaccess redirects, hidden eval code, etc. The best thing about it is it's completely free.
6
Author: Sucuri, INC
7
+ Version: 1.8.0
8
Author URI: https://sucuri.net
9
*/
10
65
/**
66
* Current version of the plugin's code.
67
*/
68
+ define('SUCURISCAN_VERSION', '1.8.0');
69
70
/**
71
* The name of the Sucuri plugin main file.
74
75
/**
76
* The name of the folder where the plugin's files will be located.
77
+ *
78
+ * Note that we are using the constant FILE instead of DIR because some
79
+ * installations of PHP are either outdated or are not supporting the access to
80
+ * that definition, to keep things simple we will select the name of the
81
+ * directory name of the current file, then select the base name of that
82
+ * directory.
83
*/
84
+ define('SUCURISCAN_PLUGIN_FOLDER', basename(dirname(__FILE__)));
85
86
/**
87
* The fullpath where the plugin's files will be located.
1853
}
1854
1855
if (is_array($tree) && !empty($tree)) {
1856
+ sort($tree); /* Sort in alphabetic order */
1857
+
1858
return array_map(array('SucuriScan', 'fixPath'), $tree);
1859
}
1860
}
2173
foreach ($dir_tree as $filepath) {
2174
$dir_path = dirname($filepath);
2175
2176
+ if (!in_array($dir_path, $dirs)) {
2177
+ if (is_array($this->ignored_directories)
2178
+ && array_key_exists('directories', $this->ignored_directories)
2179
+ && is_array($this->ignored_directories['directories'])
2180
+ && in_array($dir_path, $this->ignored_directories['directories'])
2181
+ ) {
2182
+ continue;
2183
+ }
2184
+
2185
$dirs[] = $dir_path;
2186
}
2187
}
3157
* If the option is not in the external file nor in the database, and
3158
* the name starts with the same prefix used by the plugin then we must
3159
* return the default value defined by the author.
3160
+ *
3161
+ * Note that if the plain text file is not writable the function should
3162
+ * not delete the option from the database to keep backward compatibility
3163
+ * with previous installations of the plugin.
3164
*/
3165
if (function_exists('get_option')) {
3166
$value = get_option($option);
3167
3168
if ($value !== false) {
3169
if (strpos($option, 'sucuriscan_') === 0) {
3170
+ $written = self::update_option($option, $value);
3171
+
3172
+ if ($written === true) {
3173
+ delete_option($option);
3174
+ }
3175
}
3176
3177
return $value;
5094
return substr($trail, 1);
5095
}
5096
5097
+ private static function canCurlFollowRedirection()
5098
+ {
5099
+ $safe_mode = ini_get('safe_mode');
5100
+ $open_basedir = ini_get('open_basedir');
5101
+
5102
+ if ($safe_mode === '1' || $safe_mode === 'On') {
5103
+ return false;
5104
+ }
5105
+
5106
+ if (!empty($open_basedir)) {
5107
+ return false;
5108
+ }
5109
+
5110
+ return true;
5111
+ }
5112
+
5113
/**
5114
* Assign the communication protocol.
5115
*
5332
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $method);
5333
curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, $timeout);
5334
curl_setopt($curl, CURLOPT_TIMEOUT, $timeout * 2);
5335
+
5336
+ if (self::canCurlFollowRedirection()) {
5337
+ curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
5338
+ curl_setopt($curl, CURLOPT_MAXREDIRS, 2);
5339
+ }
5340
5341
if ($method === 'POST') {
5342
curl_setopt($curl, CURLOPT_POST, true);
12581
$blocked = $cache->getAll();
12582
$cache_key = md5($username);
12583
12584
+ if (is_array($blocked)
12585
+ && is_string($cache_key)
12586
+ && array_key_exists($cache_key, $blocked)
12587
+ ) {
12588
$blocked[$cache_key]->last_attempt = time();
12589
$cache->set($cache_key, $blocked[$cache_key]);
12590
12652
}
12653
12654
if ($page_nonce) {
12655
// Enable or disable the filesystem scanner.
12656
if ($fs_scanner = SucuriScanRequest::post(':fs_scanner', '(en|dis)able')) {
12657
$action_d = $fs_scanner . 'd';
12924
$display_manual_key_form = (bool) (SucuriScanRequest::post(':recover_key') !== false);
12925
12926
if ($nonce) {
12927
+ if (!empty($_POST)) {
12928
+ $fpath = SucuriScanOption::optionsFilePath();
12929
+
12930
+ if (!is_writable($fpath)) {
12931
+ SucuriScanInterface::error(
12932
+ 'Storage is not writable: <code>'
12933
+ . $fpath . '</code>'
12934
+ );
12935
+ }
12936
+ }
12937
+
12938
+ // Remove API key from the local storage.
12939
+ if (SucuriScanRequest::post(':remove_api_key') !== false) {
12940
+ SucuriScanAPI::setPluginKey('');
12941
+ wp_clear_scheduled_hook('sucuriscan_scheduled_scan');
12942
+ SucuriScanEvent::report_critical_event('Sucuri API key was deleted.');
12943
+ SucuriScanEvent::notify_event('plugin_change', 'Sucuri API key removed');
12944
+ }
12945
+
12946
+ // Save API key after it was recovered by the administrator.
12947
+ if ($api_key = SucuriScanRequest::post(':manual_api_key')) {
12948
+ SucuriScanAPI::setPluginKey($api_key, true);
12949
+ SucuriScanEvent::schedule_task();
12950
+ SucuriScanEvent::report_info_event('Sucuri API key was added manually.');
12951
+ }
12952
+
12953
+ // Generate new API key from the API service.
12954
if (SucuriScanRequest::post(':plugin_api_key') !== false) {
12955
$user_id = SucuriScanRequest::post(':setup_user');
12956
$user_obj = SucuriScan::get_user_by_id($user_id);
14807
}
14808
}
14809
14810
+ if (class_exists('WP_Rewrite')
14811
+ && is_string($rules)
14812
+ && !empty($rules)
14813
+ ) {
14814
$rewrite = new WP_Rewrite();
14815
$standard = $rewrite->mod_rewrite_rules();
14816
14817
+ if (!empty($standard)) {
14818
+ return (bool) (strpos($rules, $standard) !== false);
14819
+ }
14820
}
14821
14822
return false;