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 | 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
- lib/wfLog.php +0 -22
- lib/wordfenceClass.php +53 -9
- readme.txt +9 -2
- 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('
|
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($
|
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($
|
1001 |
-
self::lockOutIP($IP, "Used an invalid username '" . $
|
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: '" . $
|
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>?' ), $
|
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
|
3509 |
*
|
3510 |
* @param array $query_vars
|
3511 |
* @return array
|
3512 |
*/
|
3513 |
public static function preventAuthorNScans($query_vars) {
|
3514 |
-
if (wfConfig::get('loginSec_disableAuthorScan') && !
|
|
|
|
|
|
|
|
|
|
|
|
|
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.
|
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.
|
8 |
Author URI: http://www.wordfence.com/
|
9 |
*/
|
10 |
if(defined('WP_INSTALLING') && WP_INSTALLING){
|
11 |
return;
|
12 |
}
|
13 |
-
define('WORDFENCE_VERSION', '6.0.
|
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 |
}
|