Wordfence Security – Firewall & Malware Scan - Version 6.0.17

Version Description

  • Fix: Resolved issue where 301 redirects count as 404s with throttling applied.
  • Fix: Fixed Falcon .htaccess code writing to .htaccess when 'Immediately block IP's that access these URLs' option is modified.
  • Fix: Fixed issue where filtering posts by author in wp-admin no longer works due to change in /?author=N scan prevention logic.
  • Fix: Fixed issue in Live Traffic where 404s display as 200s.
  • Fix: Resolved issue with throttling logins via XMLRPC are not applied.
Download this release

Release Info

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

Code changes from version 6.0.16 to 6.0.17

Files changed (4) hide show
  1. lib/wfLog.php +0 -22
  2. lib/wordfenceClass.php +53 -9
  3. readme.txt +9 -2
  4. wordfence.php +2 -2
lib/wfLog.php CHANGED
@@ -123,23 +123,6 @@ class wfLog {
123
124
//Range blocking was here. Moved to wordfenceClass::veryFirstAction
125
126
- if(wfConfig::get('blockFakeBots')){
127
- if(wfCrawl::isGooglebot() && (! wfCrawl::verifyCrawlerPTR($this->googlePattern, $IP) )){
128
- $this->blockIP($IP, "Fake Google crawler automatically blocked");
129
- wordfence::status(2, 'info', "Blocking fake Googlebot at IP $IP");
130
- }
131
- }
132
- if(wfConfig::get('bannedURLs', false)){
133
- $URLs = explode(',', wfConfig::get('bannedURLs'));
134
- foreach($URLs as $URL){
135
- if($_SERVER['REQUEST_URI'] == trim($URL)){
136
- $this->blockIP($IP, "Accessed a banned URL.");
137
- $this->do503(3600, "Accessed a banned URL.");
138
- //exits
139
- }
140
- }
141
- }
142
-
143
if(wfConfig::get('maxGlobalRequests') != 'DISABLED' && $hitsPerMinute > wfConfig::get('maxGlobalRequests')){ //Applies to 404 or pageview
144
$this->takeBlockingAction('maxGlobalRequests', "Exceeded the maximum global requests per minute for crawlers or humans.");
145
}
@@ -165,11 +148,6 @@ class wfLog {
165
}
166
}
167
}
168
- if(wfConfig::get('other_blockBadPOST') == '1' && $_SERVER['REQUEST_METHOD'] == 'POST' && empty($_SERVER['HTTP_USER_AGENT']) && empty($_SERVER['HTTP_REFERER'])){
169
- $this->blockIP($IP, "POST received with blank user-agent and referer");
170
- $this->do503(3600, "POST received with blank user-agent and referer");
171
- //exits
172
- }
173
if(isset($_SERVER['HTTP_USER_AGENT']) && wfCrawl::isCrawler($_SERVER['HTTP_USER_AGENT'])){
174
if($type == 'hit' && wfConfig::get('maxRequestsCrawlers') != 'DISABLED' && $hitsPerMinute > wfConfig::get('maxRequestsCrawlers')){
175
$this->takeBlockingAction('maxRequestsCrawlers', "Exceeded the maximum number of requests per minute for crawlers."); //may not exit
123
124
//Range blocking was here. Moved to wordfenceClass::veryFirstAction
125
126
if(wfConfig::get('maxGlobalRequests') != 'DISABLED' && $hitsPerMinute > wfConfig::get('maxGlobalRequests')){ //Applies to 404 or pageview
127
$this->takeBlockingAction('maxGlobalRequests', "Exceeded the maximum global requests per minute for crawlers or humans.");
128
}
148
}
149
}
150
}
151
if(isset($_SERVER['HTTP_USER_AGENT']) && wfCrawl::isCrawler($_SERVER['HTTP_USER_AGENT'])){
152
if($type == 'hit' && wfConfig::get('maxRequestsCrawlers') != 'DISABLED' && $hitsPerMinute > wfConfig::get('maxRequestsCrawlers')){
153
$this->takeBlockingAction('maxRequestsCrawlers', "Exceeded the maximum number of requests per minute for crawlers."); //may not exit
lib/wordfenceClass.php CHANGED
@@ -486,7 +486,7 @@ class wordfence {
486
add_action('wordfence_hourly_cron', 'wordfence::hourlyCron');
487
add_action('plugins_loaded', 'wordfence::veryFirstAction');
488
add_action('init', 'wordfence::initAction');
489
- add_action('wp_loaded', 'wordfence::templateRedir', 0);
490
add_action('shutdown', 'wordfence::shutdownAction');
491
492
if(version_compare(PHP_VERSION, '5.4.0') >= 0){
@@ -495,6 +495,9 @@ class wordfence {
495
add_action('wp_authenticate','wordfence::authActionOld', 1, 2);
496
}
497
add_filter('authenticate', 'wordfence::authenticateFilter', 99, 3);
498
499
add_action('login_init','wordfence::loginInitAction');
500
add_action('wp_login','wordfence::loginAction');
@@ -851,6 +854,41 @@ class wordfence {
851
if(wfConfig::get('firewallEnabled')){
852
$wfLog = self::getLog();
853
$wfLog->firewallBadIPs();
854
}
855
}
856
public static function loginAction($username){
@@ -988,7 +1026,7 @@ class wordfence {
988
if($blacklist = wfConfig::get('loginSec_userBlacklist')){
989
$users = explode(',', $blacklist);
990
foreach($users as $user){
991
- if(strtolower($_POST['log']) == strtolower($user)){
992
self::getLog()->blockIP($IP, "Blocked by login security setting.");
993
$secsToGo = wfConfig::get('blockedTime');
994
self::getLog()->do503($secsToGo, "Blocked by login security setting.");
@@ -997,8 +1035,8 @@ class wordfence {
997
}
998
}
999
if(wfConfig::get('loginSec_lockInvalidUsers')){
1000
- if(strlen($_POST['log']) > 0 && preg_match('/[^\r\s\n\t]+/', $_POST['log'])){
1001
- self::lockOutIP($IP, "Used an invalid username '" . $_POST['log'] . "' to try to sign in.");
1002
}
1003
require('wfLockedOut.php');
1004
}
@@ -1012,7 +1050,7 @@ class wordfence {
1012
$tries = 1;
1013
}
1014
if($tries >= wfConfig::get('loginSec_maxFailures')){
1015
- self::lockOutIP($IP, "Exceeded the maximum number of login failures which is: " . wfConfig::get('loginSec_maxFailures') . ". The last username they tried to sign in with was: '" . $_POST['log'] . "'");
1016
require('wfLockedOut.php');
1017
}
1018
set_transient($tKey, $tries, wfConfig::get('loginSec_countFailMins') * 60);
@@ -1029,7 +1067,7 @@ class wordfence {
1029
}
1030
1031
if(is_wp_error($authUser) && ($authUser->get_error_code() == 'invalid_username' || $authUser->get_error_code() == 'incorrect_password') && wfConfig::get('loginSec_maskLoginErrors')){
1032
- return new WP_Error( 'incorrect_password', sprintf( __( '<strong>ERROR</strong>: The username or password you entered is incorrect. <a href="%2$s" title="Password Lost and Found">Lost your password</a>?' ), $_POST['log'], wp_lostpassword_url() ) );
1033
}
1034
return $authUser;
1035
}
@@ -1857,7 +1895,7 @@ class wordfence {
1857
wfConfig::set($key, $val);
1858
}
1859
}
1860
- if($regenerateHtaccess){
1861
wfCache::addHtaccessCode('add');
1862
}
1863
@@ -3505,13 +3543,19 @@ HTML;
3505
3506
3507
/**
3508
- * Modify the query to look for scenarios
3509
*
3510
* @param array $query_vars
3511
* @return array
3512
*/
3513
public static function preventAuthorNScans($query_vars) {
3514
- if (wfConfig::get('loginSec_disableAuthorScan') && !empty($query_vars['author']) && is_numeric(preg_replace('/[^0-9]/', '', $query_vars['author']))) {
3515
$query_vars['author'] = -1;
3516
}
3517
return $query_vars;
486
add_action('wordfence_hourly_cron', 'wordfence::hourlyCron');
487
add_action('plugins_loaded', 'wordfence::veryFirstAction');
488
add_action('init', 'wordfence::initAction');
489
+ add_action('template_redirect', 'wordfence::templateRedir', 1001);
490
add_action('shutdown', 'wordfence::shutdownAction');
491
492
if(version_compare(PHP_VERSION, '5.4.0') >= 0){
495
add_action('wp_authenticate','wordfence::authActionOld', 1, 2);
496
}
497
add_filter('authenticate', 'wordfence::authenticateFilter', 99, 3);
498
+ if (self::isLockedOut(wfUtils::getIP())) {
499
+ add_filter('xmlrpc_enabled', '__return_false');
500
+ }
501
502
add_action('login_init','wordfence::loginInitAction');
503
add_action('wp_login','wordfence::loginAction');
854
if(wfConfig::get('firewallEnabled')){
855
$wfLog = self::getLog();
856
$wfLog->firewallBadIPs();
857
+
858
+ $IP = wfUtils::getIP();
859
+ if($wfLog->isWhitelisted($IP)){
860
+ return;
861
+ }
862
+ if (wfConfig::get('neverBlockBG') == 'neverBlockUA' && wfCrawl::isGoogleCrawler()) {
863
+ return;
864
+ }
865
+ if (wfConfig::get('neverBlockBG') == 'neverBlockVerified' && wfCrawl::isVerifiedGoogleCrawler()) {
866
+ return;
867
+ }
868
+
869
+ if(wfConfig::get('blockFakeBots')){
870
+ if(wfCrawl::isGooglebot() && (! wfCrawl::verifyCrawlerPTR($wfLog->getGooglePattern(), $IP) )){
871
+ $wfLog->blockIP($IP, "Fake Google crawler automatically blocked");
872
+ wordfence::status(2, 'info', "Blocking fake Googlebot at IP $IP");
873
+ $wfLog->do503(3600, "Fake Google crawler automatically blocked.");
874
+ }
875
+ }
876
+ if(wfConfig::get('bannedURLs', false)){
877
+ $URLs = explode(',', wfConfig::get('bannedURLs'));
878
+ foreach($URLs as $URL){
879
+ if($_SERVER['REQUEST_URI'] == trim($URL)){
880
+ $wfLog->blockIP($IP, "Accessed a banned URL.");
881
+ $wfLog->do503(3600, "Accessed a banned URL.");
882
+ //exits
883
+ }
884
+ }
885
+ }
886
+
887
+ if(wfConfig::get('other_blockBadPOST') == '1' && $_SERVER['REQUEST_METHOD'] == 'POST' && empty($_SERVER['HTTP_USER_AGENT']) && empty($_SERVER['HTTP_REFERER'])){
888
+ $wfLog->blockIP($IP, "POST received with blank user-agent and referer");
889
+ $wfLog->do503(3600, "POST received with blank user-agent and referer");
890
+ //exits
891
+ }
892
}
893
}
894
public static function loginAction($username){
1026
if($blacklist = wfConfig::get('loginSec_userBlacklist')){
1027
$users = explode(',', $blacklist);
1028
foreach($users as $user){
1029
+ if(strtolower($username) == strtolower($user)){
1030
self::getLog()->blockIP($IP, "Blocked by login security setting.");
1031
$secsToGo = wfConfig::get('blockedTime');
1032
self::getLog()->do503($secsToGo, "Blocked by login security setting.");
1035
}
1036
}
1037
if(wfConfig::get('loginSec_lockInvalidUsers')){
1038
+ if(strlen($username) > 0 && preg_match('/[^\r\s\n\t]+/', $username)){
1039
+ self::lockOutIP($IP, "Used an invalid username '" . $username . "' to try to sign in.");
1040
}
1041
require('wfLockedOut.php');
1042
}
1050
$tries = 1;
1051
}
1052
if($tries >= wfConfig::get('loginSec_maxFailures')){
1053
+ self::lockOutIP($IP, "Exceeded the maximum number of login failures which is: " . wfConfig::get('loginSec_maxFailures') . ". The last username they tried to sign in with was: '" . $username . "'");
1054
require('wfLockedOut.php');
1055
}
1056
set_transient($tKey, $tries, wfConfig::get('loginSec_countFailMins') * 60);
1067
}
1068
1069
if(is_wp_error($authUser) && ($authUser->get_error_code() == 'invalid_username' || $authUser->get_error_code() == 'incorrect_password') && wfConfig::get('loginSec_maskLoginErrors')){
1070
+ return new WP_Error( 'incorrect_password', sprintf( __( '<strong>ERROR</strong>: The username or password you entered is incorrect. <a href="%2$s" title="Password Lost and Found">Lost your password</a>?' ), $username, wp_lostpassword_url() ) );
1071
}
1072
return $authUser;
1073
}
1895
wfConfig::set($key, $val);
1896
}
1897
}
1898
+ if($regenerateHtaccess && wfConfig::get('cacheType') == 'falcon'){
1899
wfCache::addHtaccessCode('add');
1900
}
1901
3543
3544
3545
/**
3546
+ * Modify the query to prevent username enumeration.
3547
*
3548
* @param array $query_vars
3549
* @return array
3550
*/
3551
public static function preventAuthorNScans($query_vars) {
3552
+ if (wfConfig::get('loginSec_disableAuthorScan') && !is_admin() &&
3553
+ !empty($query_vars['author']) && is_numeric(preg_replace('/[^0-9]/', '', $query_vars['author'])) &&
3554
+ (
3555
+ (isset($_GET['author']) && is_numeric(preg_replace('/[^0-9]/', '', $_GET['author']))) ||
3556
+ (isset($_POST['author']) && is_numeric(preg_replace('/[^0-9]/', '', $_POST['author'])))
3557
+ )
3558
+ ) {
3559
$query_vars['author'] = -1;
3560
}
3561
return $query_vars;
readme.txt CHANGED
@@ -3,7 +3,7 @@ Contributors: mmaunder
3
Tags: wordpress, security, 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, 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.3
6
- Stable tag: 6.0.16
7
8
The Wordfence WordPress security plugin provides free enterprise-class WordPress security, protecting your website from hacks and malware.
9
== Description ==
@@ -183,8 +183,15 @@ fully compatible with both IPv4 and IPv6 whether you run both or only one addres
183
184
== Changelog ==
185
186
= 6.0.16 =
187
- * Fix: Resolved issue with some variations of author=N scans not being caught.
188
* Fix: Updated typo in author=N option.
189
* Fix: Resolved issue with Falcon not writing to .htaccess with WP installed in subdirectory.
190
* Fix: Added width to logo in activity report email.
3
Tags: wordpress, security, 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, 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.3
6
+ Stable tag: 6.0.17
7
8
The Wordfence WordPress security plugin provides free enterprise-class WordPress security, protecting your website from hacks and malware.
9
== Description ==
183
184
== Changelog ==
185
186
+ = 6.0.17 =
187
+ * Fix: Resolved issue where 301 redirects count as 404s with throttling applied.
188
+ * Fix: Fixed Falcon .htaccess code writing to .htaccess when 'Immediately block IP's that access these URLs' option is modified.
189
+ * Fix: Fixed issue where filtering posts by author in wp-admin no longer works due to change in /?author=N scan prevention logic.
190
+ * Fix: Fixed issue in Live Traffic where 404s display as 200s.
191
+ * Fix: Resolved issue with throttling logins via XMLRPC are not applied.
192
+
193
= 6.0.16 =
194
+ * Fix: Resolved issue with some variations of author=N scans not being caught. Thanks James Golovich.
195
* Fix: Updated typo in author=N option.
196
* Fix: Resolved issue with Falcon not writing to .htaccess with WP installed in subdirectory.
197
* Fix: Added width to logo in activity report email.
wordfence.php CHANGED
@@ -4,13 +4,13 @@ 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.0.16
8
Author URI: http://www.wordfence.com/
9
*/
10
if(defined('WP_INSTALLING') && WP_INSTALLING){
11
return;
12
}
13
- define('WORDFENCE_VERSION', '6.0.16');
14
if(get_option('wordfenceActivated') != 1){
15
add_action('activated_plugin','wordfence_save_activation_error'); function wordfence_save_activation_error(){ update_option('wf_plugin_act_error', ob_get_contents()); }
16
}
4
Plugin URI: http://www.wordfence.com/
5
Description: Wordfence Security - Anti-virus, Firewall and High Speed Cache
6
Author: Wordfence
7
+ Version: 6.0.17
8
Author URI: http://www.wordfence.com/
9
*/
10
if(defined('WP_INSTALLING') && WP_INSTALLING){
11
return;
12
}
13
+ define('WORDFENCE_VERSION', '6.0.17');
14
if(get_option('wordfenceActivated') != 1){
15
add_action('activated_plugin','wordfence_save_activation_error'); function wordfence_save_activation_error(){ update_option('wf_plugin_act_error', ob_get_contents()); }
16
}