Wordfence Security – Firewall & Malware Scan - Version 6.1.3

Version Description

  • Improvement: Added dismiss button to the Wordfence WAF setup admin notice.
  • Fix: Removed .htaccess and .user.ini from publicly accessible config and backup file scan.
  • Fix: Removed the disallow file mods for admins created outside of WordPress.
  • Fix: Fixed bug with 'Hide WordPress version' causing issues with reCAPTCHA.
  • Improvement: Added instructions for NGINX users to restrict access to .user.ini during Firewall configuration.
  • Fix: Fixed bug with multiple API calls to 'get_known_files'.
Download this release

Release Info

Developer wfmatt
Plugin Icon 128x128 Wordfence Security – Firewall & Malware Scan
Version 6.1.3
Comparing to
See all releases

Code changes from version 6.1.2 to 6.1.3

Files changed (7) hide show
  1. css/main.css +15 -0
  2. js/tourTip.js +12 -0
  3. lib/menu_waf.php +17 -0
  4. lib/wfScanEngine.php +17 -8
  5. lib/wordfenceClass.php +50 -12
  6. readme.txt +9 -1
  7. wordfence.php +2 -2
css/main.css CHANGED
@@ -576,6 +576,21 @@ table.block-ranges-table tr td {
576
border: 1px solid #ffd975;
577
border-width: 1px 1px 1px 10px;
578
}
579
.wf-success {
580
margin: 12px 0;
581
padding: 8px;
576
border: 1px solid #ffd975;
577
border-width: 1px 1px 1px 10px;
578
}
579
+ .wf-success-text,
580
+ .wf-notice-text {
581
+ display: inline-block;
582
+ vertical-align: middle;
583
+ line-height: 1.3;
584
+ font-size: 16px;
585
+ font-weight: bold;
586
+ font-style: italic;
587
+ }
588
+ .wf-notice-text {
589
+ color: #6d798c;
590
+ }
591
+ .wf-success-text {
592
+ color: #11967A;
593
+ }
594
.wf-success {
595
margin: 12px 0;
596
padding: 8px;
js/tourTip.js CHANGED
@@ -172,5 +172,17 @@ if(WordfenceAdminVars.tourClosed != '1' && WordfenceAdminVars.welcomeClosed != '
172
173
});
174
}
175
});
176
172
173
});
174
}
175
+
176
+ (function($) {
177
+ $('.wf-dismiss-link').on('click', function() {
178
+ $('#wf-extended-protection-notice').css({
179
+ opacity: .75
180
+ });
181
+ $.get(this.href, function() {
182
+ $('#wf-extended-protection-notice').fadeOut(1000);
183
+ });
184
+ return false;
185
+ });
186
+ })(jQuery);
187
});
188
lib/menu_waf.php CHANGED
@@ -1,6 +1,7 @@
1
<?php
2
$waf = wfWAF::getInstance();
3
$config = $waf->getStorageEngine();
4
/** @var array $wafData */
5
?>
6
<div class="wrap" id="paidWrap">
@@ -61,6 +62,22 @@ $config = $waf->getStorageEngine();
61
<form action="javascript:void(0)" id="waf-config-form">
62
63
<table class="wfConfigForm">
64
<tr>
65
<td><h2>Firewall Status:<a href="http://docs.wordfence.com/en/WAF#Firewall_Status"
66
target="_blank" class="wfhelp"></a></h2></td>
1
<?php
2
$waf = wfWAF::getInstance();
3
$config = $waf->getStorageEngine();
4
+ $wafConfigURL = network_admin_url('admin.php?page=WordfenceWAF&wafAction=configureAutoPrepend');
5
/** @var array $wafData */
6
?>
7
<div class="wrap" id="paidWrap">
62
<form action="javascript:void(0)" id="waf-config-form">
63
64
<table class="wfConfigForm">
65
+ <tr>
66
+ <td>
67
+ <h2>Protection Level:<a href="http://docs.wordfence.com/en/WAF#Protection_Level"
68
+ target="_blank" class="wfhelp"></a></h2>
69
+ </td>
70
+ <td colspan="2">
71
+ <?php if (!WFWAF_AUTO_PREPEND): ?>
72
+ <span class="wf-notice-text">Basic WordPress Protection</span>
73
+ &nbsp;&nbsp;&nbsp;
74
+ <a style="vertical-align: middle" class="button button-primary"
75
+ href="<?php echo $wafConfigURL ?>">Optimize the Wordfence Firewall</a>
76
+ <?php else: ?>
77
+ <span class="wf-success-text">Extended Protection</span>
78
+ <?php endif ?>
79
+ </td>
80
+ </tr>
81
<tr>
82
<td><h2>Firewall Status:<a href="http://docs.wordfence.com/en/WAF#Firewall_Status"
83
target="_blank" class="wfhelp"></a></h2></td>
lib/wfScanEngine.php CHANGED
@@ -71,7 +71,7 @@ class wfScanEngine {
71
}
72
73
public function __sleep(){ //Same order here as above for properties that are included in serialization
74
- return array('hasher', 'jobList', 'i', 'wp_version', 'apiKey', 'startTime', 'maxExecTime', 'publicScanEnabled', 'fileContentsResults', 'scanner', 'scanQueue', 'hoover', 'scanData', 'statusIDX', 'userPasswdQueue', 'passwdHasIssues', 'dbScanner');
75
}
76
public function __construct(){
77
$this->startTime = time();
@@ -247,8 +247,8 @@ class wfScanEngine {
247
$status = wordfence::statusStart("Check for publicly accessible configuration files, backup files and logs");
248
249
$backupFileTests = array(
250
- wfCommonBackupFileTest::createFromRootPath('.user.ini'),
251
- wfCommonBackupFileTest::createFromRootPath('.htaccess'),
252
wfCommonBackupFileTest::createFromRootPath('wp-config.php.bak'),
253
wfCommonBackupFileTest::createFromRootPath('wp-config.php.swo'),
254
wfCommonBackupFileTest::createFromRootPath('wp-config.php.save'),
@@ -273,10 +273,10 @@ class wfScanEngine {
273
),
274
)),
275
);
276
- $userIniFilename = ini_get('user_ini.filename');
277
- if ($userIniFilename && $userIniFilename !== '.user.ini') {
278
- $backupFileTests[] = wfCommonBackupFileTest::createFromRootPath($userIniFilename);
279
- }
280
281
282
/** @var wfCommonBackupFileTest $test */
@@ -1427,7 +1427,16 @@ class wfCommonBackupFileTest {
1427
*/
1428
public function isPubliclyAccessible() {
1429
$this->response = wp_remote_get($this->url, $this->requestArgs);
1430
- return wp_remote_retrieve_response_code($this->response) === 200;
1431
}
1432
1433
/**
71
}
72
73
public function __sleep(){ //Same order here as above for properties that are included in serialization
74
+ return array('hasher', 'jobList', 'i', 'wp_version', 'apiKey', 'startTime', 'maxExecTime', 'publicScanEnabled', 'fileContentsResults', 'scanner', 'scanQueue', 'hoover', 'scanData', 'statusIDX', 'userPasswdQueue', 'passwdHasIssues', 'dbScanner', 'knownFilesLoader');
75
}
76
public function __construct(){
77
$this->startTime = time();
247
$status = wordfence::statusStart("Check for publicly accessible configuration files, backup files and logs");
248
249
$backupFileTests = array(
250
+ // wfCommonBackupFileTest::createFromRootPath('.user.ini'),
251
+ // wfCommonBackupFileTest::createFromRootPath('.htaccess'),
252
wfCommonBackupFileTest::createFromRootPath('wp-config.php.bak'),
253
wfCommonBackupFileTest::createFromRootPath('wp-config.php.swo'),
254
wfCommonBackupFileTest::createFromRootPath('wp-config.php.save'),
273
),
274
)),
275
);
276
+ // $userIniFilename = ini_get('user_ini.filename');
277
+ // if ($userIniFilename && $userIniFilename !== '.user.ini') {
278
+ // $backupFileTests[] = wfCommonBackupFileTest::createFromRootPath($userIniFilename);
279
+ // }
280
281
282
/** @var wfCommonBackupFileTest $test */
1427
*/
1428
public function isPubliclyAccessible() {
1429
$this->response = wp_remote_get($this->url, $this->requestArgs);
1430
+ if ((int) floor(((int) wp_remote_retrieve_response_code($this->response) / 100)) === 2) {
1431
+ $handle = @fopen($this->path, 'r');
1432
+ if ($handle) {
1433
+ $contents = fread($handle, 700);
1434
+ fclose($handle);
1435
+ $remoteContents = substr(wp_remote_retrieve_body($this->response), 0, 700);
1436
+ return $contents === $remoteContents;
1437
+ }
1438
+ }
1439
+ return false;
1440
}
1441
1442
/**
lib/wordfenceClass.php CHANGED
@@ -3355,12 +3355,12 @@ HTML;
3355
self::setCookie();
3356
}
3357
// This is more of a hurdle, but might stop an automated process.
3358
- if (current_user_can('administrator')) {
3359
- $adminUsers = new wfAdminUserMonitor();
3360
- if ($adminUsers->isEnabled() && !$adminUsers->isAdminUserLogged(get_current_user_id())) {
3361
- define('DISALLOW_FILE_MODS', true);
3362
- }
3363
- }
3364
3365
$currentUserID = get_current_user_id();
3366
$role = wordfence::getCurrentUserRole();
@@ -3474,7 +3474,7 @@ HTML;
3474
}
3475
3476
if (!WFWAF_AUTO_PREPEND || WFWAF_SUBDIRECTORY_INSTALL) {
3477
- if (empty($_GET['wafAction'])) {
3478
if (is_multisite()) {
3479
add_action('network_admin_notices', 'wordfence::wafAutoPrependNotice');
3480
} else {
@@ -3690,6 +3690,12 @@ HTML;
3690
3691
if (!empty($_GET['wafAction'])) {
3692
switch ($_GET['wafAction']) {
3693
case 'configureAutoPrepend':
3694
if (WFWAF_AUTO_PREPEND && !WFWAF_SUBDIRECTORY_INSTALL) {
3695
break;
@@ -3854,14 +3860,42 @@ list below:</p>";
3854
you know your web server's configuration, please select it now.</p>";
3855
}
3856
3857
$wafActionContent .= "
3858
<form action='$adminURL' method='post'>
3859
<input type='hidden' name='wfnonce' value='$wfnonce'>
3860
- <select name='serverConfiguration'>
3861
$wafPrependOptions
3862
</select>
3863
<button class='button button-primary' type='submit'>Continue</button>
3864
</form>
3865
";
3866
3867
$wafActionContent .= "
@@ -3943,12 +3977,12 @@ $wafPrependOptions
3943
}
3944
3945
public static function replaceVersion($url) {
3946
- return preg_replace_callback("/([&;\?]ver)=(.+?)(?:&|$)/", "wordfence::replaceVersionCallback", $url);
3947
}
3948
3949
public static function replaceVersionCallback($matches) {
3950
global $wp_version;
3951
- return $matches[1] . '=' . ($wp_version === $matches[2] ? wp_hash($matches[2]) : $matches[2]);
3952
}
3953
3954
public static function genFilter($gen, $type){
@@ -4951,8 +4985,12 @@ LIMIT %d", $lastSendTime, $limit));
4951
4952
public static function wafAutoPrependNotice() {
4953
$url = network_admin_url('admin.php?page=WordfenceWAF&wafAction=configureAutoPrepend');
4954
- echo '<div class="update-nag">To make your site as secure as possible, take a moment to setup the Wordfence Web
4955
- Application Firewall: &nbsp;<a class="button button-small" href="' . esc_url($url) . '">Click here to configure.</a><br>
4956
<em style="font-size: 85%;">If you cannot complete the setup process,
4957
<a target="_blank" href="https://docs.wordfence.com/en/Web_Application_Firewall_Setup">click here for help</a>.</em>
4958
</div>';
3355
self::setCookie();
3356
}
3357
// This is more of a hurdle, but might stop an automated process.
3358
+ // if (current_user_can('administrator')) {
3359
+ // $adminUsers = new wfAdminUserMonitor();
3360
+ // if ($adminUsers->isEnabled() && !$adminUsers->isAdminUserLogged(get_current_user_id())) {
3361
+ // define('DISALLOW_FILE_MODS', true);
3362
+ // }
3363
+ // }
3364
3365
$currentUserID = get_current_user_id();
3366
$role = wordfence::getCurrentUserRole();
3474
}
3475
3476
if (!WFWAF_AUTO_PREPEND || WFWAF_SUBDIRECTORY_INSTALL) {
3477
+ if (empty($_GET['wafAction']) && !wfConfig::get('dismissAutoPrependNotice')) {
3478
if (is_multisite()) {
3479
add_action('network_admin_notices', 'wordfence::wafAutoPrependNotice');
3480
} else {
3690
3691
if (!empty($_GET['wafAction'])) {
3692
switch ($_GET['wafAction']) {
3693
+ case 'dismissAutoPrependNotice':
3694
+ check_admin_referer('wfDismissAutoPrependNotice', 'nonce');
3695
+ wfConfig::set('dismissAutoPrependNotice', 1);
3696
+
3697
+ break;
3698
+
3699
case 'configureAutoPrepend':
3700
if (WFWAF_AUTO_PREPEND && !WFWAF_SUBDIRECTORY_INSTALL) {
3701
break;
3860
you know your web server's configuration, please select it now.</p>";
3861
}
3862
3863
+ $userIni = ini_get('user_ini.filename');
3864
+ $nginxIniWarning = '';
3865
+ if ($userIni) {
3866
+ $nginxIniWarning = "<div class='wf-notice wf-nginx-waf-config'>
3867
+ Part of the Firewall configuration procedure for NGINX depends on creating a <code>" . esc_html($userIni) . "</code> file
3868
+ in the root of your WordPress installation. This file can contain sensitive information and public access to it should
3869
+ be restricted. We have
3870
+ <a href='https://docs.wordfence.com/en/Web_Application_Firewall_FAQ#NGINX'>instructions on our documentation site</a> on what
3871
+ directives to put in your nginx.conf to fix this.
3872
+ ";
3873
+ }
3874
+
3875
+
3876
$wafActionContent .= "
3877
<form action='$adminURL' method='post'>
3878
<input type='hidden' name='wfnonce' value='$wfnonce'>
3879
+ <select name='serverConfiguration' id='wf-waf-server-config'>
3880
$wafPrependOptions
3881
</select>
3882
<button class='button button-primary' type='submit'>Continue</button>
3883
</form>
3884
+ $nginxIniWarning
3885
+ </div>
3886
+ <script>
3887
+ (function($) {
3888
+ var nginxNotice = $('.wf-nginx-waf-config').hide();
3889
+ $('#wf-waf-server-config').on('change', function() {
3890
+ var el = $(this);
3891
+ if (el.val() == 'nginx') {
3892
+ nginxNotice.fadeIn();
3893
+ } else {
3894
+ nginxNotice.fadeOut();
3895
+ }
3896
+ }).triggerHandler('change');
3897
+ })(jQuery);
3898
+ </script>
3899
";
3900
3901
$wafActionContent .= "
3977
}
3978
3979
public static function replaceVersion($url) {
3980
+ return preg_replace_callback("/([&;\?]ver)=(.+?)(&|$)/", "wordfence::replaceVersionCallback", $url);
3981
}
3982
3983
public static function replaceVersionCallback($matches) {
3984
global $wp_version;
3985
+ return $matches[1] . '=' . ($wp_version === $matches[2] ? wp_hash($matches[2]) : $matches[2]) . $matches[3];
3986
}
3987
3988
public static function genFilter($gen, $type){
4985
4986
public static function wafAutoPrependNotice() {
4987
$url = network_admin_url('admin.php?page=WordfenceWAF&wafAction=configureAutoPrepend');
4988
+ $dismissURL = network_admin_url('admin.php?page=WordfenceWAF&wafAction=dismissAutoPrependNotice&nonce=' .
4989
+ rawurlencode(wp_create_nonce('wfDismissAutoPrependNotice')));
4990
+ echo '<div class="update-nag" id="wf-extended-protection-notice">To make your site as secure as possible, take a moment to optimize the Wordfence Web
4991
+ Application Firewall: &nbsp;<a class="button button-small" href="' . esc_url($url) . '">Click here to configure.</a>
4992
+ <a class="button button-small wf-dismiss-link" href="' . esc_url($dismissURL) . '">Dismiss</a>
4993
+ <br>
4994
<em style="font-size: 85%;">If you cannot complete the setup process,
4995
<a target="_blank" href="https://docs.wordfence.com/en/Web_Application_Firewall_Setup">click here for help</a>.</em>
4996
</div>';
readme.txt CHANGED
@@ -3,7 +3,7 @@ Contributors: mmaunder
3
Tags: wordpress, security, web application firewall, waf, performance, speed, caching, cache, caching plugin, wordpress cache, wordpress caching, wordpress security, security plugin, secure, anti-virus, malware, firewall, antivirus, virus, google safe browsing, phishing, scrapers, hacking, wordfence, securty, secrity, secure, two factor, cellphone sign-in, cellphone signin, cellphone, twofactor, security, secure, htaccess, login, log, users, login alerts, lock, chmod, maintenance, plugin, private, privacy, protection, permissions, 503, base64, injection, code, encode, script, attack, hack, hackers, block, blocked, prevent, prevention, RFI, XSS, CRLF, CSRF, SQL Injection, vulnerability, website security, WordPress security, security log, logging, HTTP log, error log, login security, personal security, infrastructure security, firewall security, front-end security, web server security, proxy security, reverse proxy security, secure website, secure login, two factor security, two factor authentication, maximum login security, heartbleed, heart bleed, heartbleed vulnerability, openssl vulnerability, nginx, litespeed, php5-fpm, woocommerce support, woocommerce caching, IPv6, IP version 6
4
Requires at least: 3.9
5
Tested up to: 4.5
6
- Stable tag: 6.1.2
7
8
The Wordfence WordPress security plugin provides free enterprise-class WordPress security, protecting your website from hacks and malware.
9
== Description ==
@@ -195,6 +195,14 @@ Designed for every skill level, [The WordPress Security Learning Center](https:/
195
196
== Changelog ==
197
198
= 6.1.2 =
199
* Fix: Fixed fatal error when using a whitelisted IPv6 range and connecting with an IPv6 address.
200
3
Tags: wordpress, security, web application firewall, waf, performance, speed, caching, cache, caching plugin, wordpress cache, wordpress caching, wordpress security, security plugin, secure, anti-virus, malware, firewall, antivirus, virus, google safe browsing, phishing, scrapers, hacking, wordfence, securty, secrity, secure, two factor, cellphone sign-in, cellphone signin, cellphone, twofactor, security, secure, htaccess, login, log, users, login alerts, lock, chmod, maintenance, plugin, private, privacy, protection, permissions, 503, base64, injection, code, encode, script, attack, hack, hackers, block, blocked, prevent, prevention, RFI, XSS, CRLF, CSRF, SQL Injection, vulnerability, website security, WordPress security, security log, logging, HTTP log, error log, login security, personal security, infrastructure security, firewall security, front-end security, web server security, proxy security, reverse proxy security, secure website, secure login, two factor security, two factor authentication, maximum login security, heartbleed, heart bleed, heartbleed vulnerability, openssl vulnerability, nginx, litespeed, php5-fpm, woocommerce support, woocommerce caching, IPv6, IP version 6
4
Requires at least: 3.9
5
Tested up to: 4.5
6
+ Stable tag: 6.1.3
7
8
The Wordfence WordPress security plugin provides free enterprise-class WordPress security, protecting your website from hacks and malware.
9
== Description ==
195
196
== Changelog ==
197
198
+ = 6.1.3 =
199
+ * Improvement: Added dismiss button to the Wordfence WAF setup admin notice.
200
+ * Fix: Removed .htaccess and .user.ini from publicly accessible config and backup file scan.
201
+ * Fix: Removed the disallow file mods for admins created outside of WordPress.
202
+ * Fix: Fixed bug with 'Hide WordPress version' causing issues with reCAPTCHA.
203
+ * Improvement: Added instructions for NGINX users to restrict access to .user.ini during Firewall configuration.
204
+ * Fix: Fixed bug with multiple API calls to 'get_known_files'.
205
+
206
= 6.1.2 =
207
* Fix: Fixed fatal error when using a whitelisted IPv6 range and connecting with an IPv6 address.
208
wordfence.php CHANGED
@@ -4,14 +4,14 @@ Plugin Name: Wordfence Security
4
Plugin URI: http://www.wordfence.com/
5
Description: Wordfence Security - Anti-virus, Firewall and High Speed Cache
6
Author: Wordfence
7
- Version: 6.1.2
8
Author URI: http://www.wordfence.com/
9
Network: true
10
*/
11
if(defined('WP_INSTALLING') && WP_INSTALLING){
12
return;
13
}
14
- define('WORDFENCE_VERSION', '6.1.2');
15
define('WORDFENCE_BASENAME', function_exists('plugin_basename') ? plugin_basename(__FILE__) :
16
basename(dirname(__FILE__)) . '/' . basename(__FILE__));
17
4
Plugin URI: http://www.wordfence.com/
5
Description: Wordfence Security - Anti-virus, Firewall and High Speed Cache
6
Author: Wordfence
7
+ Version: 6.1.3
8
Author URI: http://www.wordfence.com/
9
Network: true
10
*/
11
if(defined('WP_INSTALLING') && WP_INSTALLING){
12
return;
13
}
14
+ define('WORDFENCE_VERSION', '6.1.3');
15
define('WORDFENCE_BASENAME', function_exists('plugin_basename') ? plugin_basename(__FILE__) :
16
basename(dirname(__FILE__)) . '/' . basename(__FILE__));
17