Version Description
- Fixed problem where scan process can't get admin ID.
- Fixed issue that caused permanent IP's to not be permanent.
- Fixed SQL error when calculating if IP block has expired.
- Fixed incorrect calling of is_404 that caused intermittent issues.
- Fixed basedir warnings when scan tries to scan files it does not have access to.
- Fixed warning and incorrect calculation of rows in DB.
- Added ability to get IP from "HTTP_X_REAL_IP" header of a front-end proxy is sending it.
- Fixed warning about HTTPS element not existing in getRequestedURL()
- Fixed problem with paid vs free keys getting confused.
- Fixed error with fetching vulnerability patterns.
Download this release
Release Info
Developer | mmaunder |
Plugin | Wordfence Security – Firewall & Malware Scan |
Version | 3.0.9 |
Comparing to | |
See all releases |
Code changes from version 3.0.8 to 3.0.9
- lib/wfConfig.php +0 -3
- lib/wfIssues.php +3 -1
- lib/wfLog.php +9 -8
- lib/wfScanEngine.php +1 -1
- lib/wfUtils.php +11 -3
- lib/wordfenceClass.php +22 -15
- readme.txt +16 -1
- wfscan.php +16 -4
- wordfence.php +2 -2
lib/wfConfig.php
CHANGED
@@ -329,9 +329,6 @@ class wfConfig {
|
|
329 |
}
|
330 |
}
|
331 |
self::set('encKey', substr(wfUtils::bigRandomHex(),0 ,16) );
|
332 |
-
if(! self::get('isPaid', false)){
|
333 |
-
self::set('isPaid', 'free');
|
334 |
-
}
|
335 |
if(self::get('maxMem', false) === false ){
|
336 |
self::set('maxMem', '256');
|
337 |
}
|
329 |
}
|
330 |
}
|
331 |
self::set('encKey', substr(wfUtils::bigRandomHex(),0 ,16) );
|
|
|
|
|
|
|
332 |
if(self::get('maxMem', false) === false ){
|
333 |
self::set('maxMem', '256');
|
334 |
}
|
lib/wfIssues.php
CHANGED
@@ -227,7 +227,9 @@ class wfIssues {
|
|
227 |
$totalRows = 0;
|
228 |
foreach($res1 as $table){
|
229 |
$res2 = $wpdb->get_col($wpdb->prepare("select count(*) from $table"));
|
230 |
-
$
|
|
|
|
|
231 |
}
|
232 |
$dat['totalRows'] = $totalRows;
|
233 |
$arr = wfConfig::get_ser('wf_summaryItems', array());
|
227 |
$totalRows = 0;
|
228 |
foreach($res1 as $table){
|
229 |
$res2 = $wpdb->get_col($wpdb->prepare("select count(*) from $table"));
|
230 |
+
if(isset($res2[0]) ){
|
231 |
+
$totalRows += $res2[0];
|
232 |
+
}
|
233 |
}
|
234 |
$dat['totalRows'] = $totalRows;
|
235 |
$arr = wfConfig::get_ser('wf_summaryItems', array());
|
lib/wfLog.php
CHANGED
@@ -161,14 +161,13 @@ class wfLog {
|
|
161 |
if($this->isWhitelisted($IP)){ return false; }
|
162 |
$wfsn = $wfsn ? 1 : 0;
|
163 |
$permanent = $permanent ? 1 : 0;
|
164 |
-
$this->getDB()->query("insert into " . $this->blocksTable . " (IP, blockedTime, reason, wfsn, permanent) values (%s, unix_timestamp(), '%s', %d, %d) ON DUPLICATE KEY update blockedTime=unix_timestamp(), reason='%s', wfsn=%d
|
165 |
wfUtils::inet_aton($IP),
|
166 |
$reason,
|
167 |
$wfsn,
|
168 |
$permanent,
|
169 |
$reason,
|
170 |
-
$wfsn
|
171 |
-
$permanent
|
172 |
);
|
173 |
return true;
|
174 |
}
|
@@ -266,7 +265,7 @@ class wfLog {
|
|
266 |
$this->resolveIPs($results);
|
267 |
foreach($results as &$elem){
|
268 |
$elem['timeAgo'] = wfUtils::makeTimeAgo($this->getDB()->querySingle("select unix_timestamp() - (eMin * 60) from $table where IP=%s", $elem['IP']));
|
269 |
-
$elem['blocked'] = $this->getDB()->querySingle("select blockedTime from " . $this->blocksTable . " where IP=%s and blockedTime + %s > unix_timestamp()", $elem['IP'], wfConfig::get('blockedTime'));
|
270 |
//take action
|
271 |
$elem['IP'] = wfUtils::inet_ntoa($elem['IP']);
|
272 |
}
|
@@ -345,7 +344,7 @@ class wfLog {
|
|
345 |
foreach($results as &$res){
|
346 |
$res['type'] = $type;
|
347 |
$res['timeAgo'] = wfUtils::makeTimeAgo($serverTime - $res['ctime']);
|
348 |
-
$res['blocked'] = $this->getDB()->querySingle("select blockedTime from " . $this->blocksTable . " where IP=%s and blockedTime + %s > unix_timestamp()", $res['IP'], wfConfig::get('blockedTime'));
|
349 |
$res['IP'] = wfUtils::inet_ntoa($res['IP']);
|
350 |
$res['extReferer'] = false;
|
351 |
if($res['referer']){
|
@@ -471,9 +470,11 @@ class wfLog {
|
|
471 |
}
|
472 |
public function firewallBadIPs(){
|
473 |
$IP = wfUtils::inet_aton(wfUtils::getIP());
|
474 |
-
if($rec = $this->getDB()->querySingleRec("select
|
475 |
-
$this->getDB()->query("update " . $this->blocksTable . " set lastAttempt=unix_timestamp(), blockedHits = blockedHits + 1 where IP=%s", $IP);
|
476 |
-
$this->
|
|
|
|
|
477 |
}
|
478 |
}
|
479 |
private function takeBlockingAction($configVar, $reason){
|
161 |
if($this->isWhitelisted($IP)){ return false; }
|
162 |
$wfsn = $wfsn ? 1 : 0;
|
163 |
$permanent = $permanent ? 1 : 0;
|
164 |
+
$this->getDB()->query("insert into " . $this->blocksTable . " (IP, blockedTime, reason, wfsn, permanent) values (%s, unix_timestamp(), '%s', %d, %d) ON DUPLICATE KEY update blockedTime=unix_timestamp(), reason='%s', wfsn=%d",
|
165 |
wfUtils::inet_aton($IP),
|
166 |
$reason,
|
167 |
$wfsn,
|
168 |
$permanent,
|
169 |
$reason,
|
170 |
+
$wfsn
|
|
|
171 |
);
|
172 |
return true;
|
173 |
}
|
265 |
$this->resolveIPs($results);
|
266 |
foreach($results as &$elem){
|
267 |
$elem['timeAgo'] = wfUtils::makeTimeAgo($this->getDB()->querySingle("select unix_timestamp() - (eMin * 60) from $table where IP=%s", $elem['IP']));
|
268 |
+
$elem['blocked'] = $this->getDB()->querySingle("select blockedTime from " . $this->blocksTable . " where IP=%s and ((blockedTime + %s > unix_timestamp()) OR permanent = 1)", $elem['IP'], wfConfig::get('blockedTime'));
|
269 |
//take action
|
270 |
$elem['IP'] = wfUtils::inet_ntoa($elem['IP']);
|
271 |
}
|
344 |
foreach($results as &$res){
|
345 |
$res['type'] = $type;
|
346 |
$res['timeAgo'] = wfUtils::makeTimeAgo($serverTime - $res['ctime']);
|
347 |
+
$res['blocked'] = $this->getDB()->querySingle("select blockedTime from " . $this->blocksTable . " where IP=%s and (permanent = 1 OR (blockedTime + %s > unix_timestamp()))", $res['IP'], wfConfig::get('blockedTime'));
|
348 |
$res['IP'] = wfUtils::inet_ntoa($res['IP']);
|
349 |
$res['extReferer'] = false;
|
350 |
if($res['referer']){
|
470 |
}
|
471 |
public function firewallBadIPs(){
|
472 |
$IP = wfUtils::inet_aton(wfUtils::getIP());
|
473 |
+
if($rec = $this->getDB()->querySingleRec("select blockedTime, reason from " . $this->blocksTable . " where IP=%s and (permanent=1 OR (blockedTime + %s > unix_timestamp()))", wfConfig::get('blockedTime'), $IP, wfConfig::get('blockedTime'))){
|
474 |
+
$this->getDB()->query("update " . $this->blocksTable . " set lastAttempt=unix_timestamp(), blockedHits = blockedHits + 1 where IP=%s", $IP);
|
475 |
+
$now = $this->getDB()->querySingle("select unix_timestamp()");
|
476 |
+
$secsToGo = ($rec['blockedTime'] + wfConfig::get('blockedTime')) - $now;
|
477 |
+
$this->do503($secsToGo, $rec['reason']);
|
478 |
}
|
479 |
}
|
480 |
private function takeBlockingAction($configVar, $reason){
|
lib/wfScanEngine.php
CHANGED
@@ -184,7 +184,7 @@ class wfScanEngine {
|
|
184 |
$fullFile = rtrim(ABSPATH, '/') . '/' . $file;
|
185 |
if($scanOutside){
|
186 |
$includeInScan[] = $file;
|
187 |
-
} else if(in_array($file, $baseWPStuff) || (is_file($fullFile) && is_readable($fullFile) && (! wfUtils::fileTooBig($fullFile)) ) ){
|
188 |
$includeInScan[] = $file;
|
189 |
}
|
190 |
}
|
184 |
$fullFile = rtrim(ABSPATH, '/') . '/' . $file;
|
185 |
if($scanOutside){
|
186 |
$includeInScan[] = $file;
|
187 |
+
} else if(in_array($file, $baseWPStuff) || (@is_file($fullFile) && @is_readable($fullFile) && (! wfUtils::fileTooBig($fullFile)) ) ){
|
188 |
$includeInScan[] = $file;
|
189 |
}
|
190 |
}
|
lib/wfUtils.php
CHANGED
@@ -78,12 +78,20 @@ class wfUtils {
|
|
78 |
if(isset($_SERVER['HTTP_X_FORWARDED_FOR'])){
|
79 |
$IP = $_SERVER['HTTP_X_FORWARDED_FOR'];
|
80 |
}
|
|
|
|
|
|
|
81 |
if((! preg_match('/(\d+)\.(\d+)\.(\d+)\.(\d+)/', $IP)) && isset($_SERVER['REMOTE_ADDR'])){
|
82 |
$IP = $_SERVER['REMOTE_ADDR'];
|
83 |
}
|
84 |
if(preg_match('/,/', $IP)){
|
85 |
-
$parts = explode(',', $IP);
|
86 |
-
$
|
|
|
|
|
|
|
|
|
|
|
87 |
}
|
88 |
if(preg_match('/:\d+$/', $IP)){
|
89 |
$IP = preg_replace('/:\d+$/', '', $IP);
|
@@ -125,7 +133,7 @@ class wfUtils {
|
|
125 |
return false;
|
126 |
}
|
127 |
public static function getRequestedURL(){
|
128 |
-
return (
|
129 |
}
|
130 |
|
131 |
public static function editUserLink($userID){
|
78 |
if(isset($_SERVER['HTTP_X_FORWARDED_FOR'])){
|
79 |
$IP = $_SERVER['HTTP_X_FORWARDED_FOR'];
|
80 |
}
|
81 |
+
if((! preg_match('/(\d+)\.(\d+)\.(\d+)\.(\d+)/', $IP)) && isset($_SERVER['HTTP_X_REAL_IP'])){
|
82 |
+
$IP = $_SERVER['HTTP_X_REAL_IP'];
|
83 |
+
}
|
84 |
if((! preg_match('/(\d+)\.(\d+)\.(\d+)\.(\d+)/', $IP)) && isset($_SERVER['REMOTE_ADDR'])){
|
85 |
$IP = $_SERVER['REMOTE_ADDR'];
|
86 |
}
|
87 |
if(preg_match('/,/', $IP)){
|
88 |
+
$parts = explode(',', $IP); //Some users have "unknown,100.100.100.100" for example so we take the first thing that looks like an IP.
|
89 |
+
foreach($parts as $part){
|
90 |
+
if(preg_match('/(\d+)\.(\d+)\.(\d+)\.(\d+)/', $part)){
|
91 |
+
$IP = trim($part);
|
92 |
+
break;
|
93 |
+
}
|
94 |
+
}
|
95 |
}
|
96 |
if(preg_match('/:\d+$/', $IP)){
|
97 |
$IP = preg_replace('/:\d+$/', '', $IP);
|
133 |
return false;
|
134 |
}
|
135 |
public static function getRequestedURL(){
|
136 |
+
return (@$_SERVER['HTTPS'] ? 'https' : 'http') . '://' . $_SERVER['SERVER_NAME'] . $_SERVER['REQUEST_URI'];
|
137 |
}
|
138 |
|
139 |
public static function editUserLink($userID){
|
lib/wordfenceClass.php
CHANGED
@@ -46,16 +46,6 @@ class wordfence {
|
|
46 |
public static function hourlyCron(){
|
47 |
global $wpdb; $p = $wpdb->base_prefix;
|
48 |
$api = new wfAPI(wfConfig::get('apiKey'), wfUtils::getWPVersion());
|
49 |
-
try {
|
50 |
-
$patData = $api->call('get_known_vuln_pattern');
|
51 |
-
if(is_array($patData) && $patData['pat']){
|
52 |
-
if(@preg_match($patData['pat'], 'wordfence_test_vuln_match')){
|
53 |
-
wfConfig::set('vulnRegex', $pat);
|
54 |
-
}
|
55 |
-
}
|
56 |
-
} catch(Exception $e){
|
57 |
-
wordfence::status(2, 'error', "Could not fetch vulnerability patterns in hourly scheduled job: " . $e->getMessage());
|
58 |
-
}
|
59 |
|
60 |
|
61 |
if(wfConfig::get('other_WFNet')){
|
@@ -93,7 +83,7 @@ class wordfence {
|
|
93 |
if($resp['code'] == 200){
|
94 |
$len = strlen($resp['data']);
|
95 |
$reason = "WFSN: Blocked by Wordfence Security Network";
|
96 |
-
$wfdb->query("delete from $p"."wfBlocks where wfsn=1");
|
97 |
if($len > 0 && $len % 4 == 0){
|
98 |
for($i = 0; $i < $len; $i += 4){
|
99 |
list($ipLong) = array_values(unpack('N', substr($resp['data'], $i, 4)));
|
@@ -111,9 +101,21 @@ class wordfence {
|
|
111 |
public static function dailyCron(){
|
112 |
$wfdb = new wfDB();
|
113 |
global $wpdb; $p = $wpdb->base_prefix;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
114 |
$wfdb->query("delete from $p"."wfLocs where ctime < unix_timestamp() - %d", WORDFENCE_MAX_IPLOC_AGE);
|
115 |
$wfdb->query("truncate table $p"."wfBadLeechers"); //only uses date that's less than 1 minute old
|
116 |
-
$wfdb->query("delete from $p"."wfBlocks where blockedTime + %s < unix_timestamp() and permanent=0", wfConfig::get('blockedTime'));
|
117 |
$wfdb->query("delete from $p"."wfCrawlers where lastUpdate < unix_timestamp() - (86400 * 7)");
|
118 |
|
119 |
$count = $wfdb->querySingle("select count(*) as cnt from $p"."wfHits");
|
@@ -376,6 +378,7 @@ class wordfence {
|
|
376 |
header('Location: ' . wp_login_url());
|
377 |
exit();
|
378 |
} else if($_GET['func'] == 'unlockAllIPs'){
|
|
|
379 |
$wfLog->unblockAllIPs();
|
380 |
$wfLog->unlockAllIPs();
|
381 |
header('Location: ' . wp_login_url());
|
@@ -383,6 +386,7 @@ class wordfence {
|
|
383 |
} else if($_GET['func'] == 'disableRules'){
|
384 |
wfConfig::set('firewallEnabled', 0);
|
385 |
wfConfig::set('loginSecurityEnabled', 0);
|
|
|
386 |
$wfLog->unblockAllIPs();
|
387 |
$wfLog->unlockAllIPs();
|
388 |
header('Location: ' . wp_login_url());
|
@@ -619,7 +623,7 @@ class wordfence {
|
|
619 |
if($res['ok'] && isset($res['isPaid'])){
|
620 |
wfConfig::set('apiKey', $opts['apiKey']);
|
621 |
$reload = 'reload';
|
622 |
-
wfConfig::set('isPaid', $res['isPaid']);
|
623 |
if($res['isPaid']){
|
624 |
$paidKeyMsg = true;
|
625 |
}
|
@@ -640,7 +644,7 @@ class wordfence {
|
|
640 |
$wfdb = new wfDB();
|
641 |
global $wpdb;
|
642 |
$p = $wpdb->base_prefix;
|
643 |
-
$wfdb->query("delete from $p"."wfBlocks where wfsn=1");
|
644 |
}
|
645 |
foreach($opts as $key => $val){
|
646 |
wfConfig::set($key, $val);
|
@@ -658,6 +662,7 @@ class wordfence {
|
|
658 |
$op = $_POST['op'];
|
659 |
$wfLog = self::getLog();
|
660 |
if($op == 'blocked'){
|
|
|
661 |
$wfLog->unblockAllIPs();
|
662 |
} else if($op == 'locked'){
|
663 |
$wfLog->unlockAllIPs();
|
@@ -889,7 +894,7 @@ class wordfence {
|
|
889 |
$wfFunc = get_query_var('_wfsf');
|
890 |
$wfLog = self::getLog();
|
891 |
if($wfLog->logHitOK()){
|
892 |
-
if(is_404() ){
|
893 |
$wfLog->logLeechAndBlock('404');
|
894 |
} else {
|
895 |
$wfLog->logLeechAndBlock('hit');
|
@@ -1084,6 +1089,8 @@ class wordfence {
|
|
1084 |
}
|
1085 |
public static function initAction(){
|
1086 |
global $wp;
|
|
|
|
|
1087 |
$wp->add_query_var('_wfsf');
|
1088 |
//add_rewrite_rule('wfStaticFunc/([a-zA-Z0-9]+)/?$', 'index.php?wfStaticFunc=' . $matches[1], 'top');
|
1089 |
$cookieName = 'wfvt_' . crc32(site_url());
|
46 |
public static function hourlyCron(){
|
47 |
global $wpdb; $p = $wpdb->base_prefix;
|
48 |
$api = new wfAPI(wfConfig::get('apiKey'), wfUtils::getWPVersion());
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
49 |
|
50 |
|
51 |
if(wfConfig::get('other_WFNet')){
|
83 |
if($resp['code'] == 200){
|
84 |
$len = strlen($resp['data']);
|
85 |
$reason = "WFSN: Blocked by Wordfence Security Network";
|
86 |
+
$wfdb->query("delete from $p"."wfBlocks where wfsn=1 and permanent=0");
|
87 |
if($len > 0 && $len % 4 == 0){
|
88 |
for($i = 0; $i < $len; $i += 4){
|
89 |
list($ipLong) = array_values(unpack('N', substr($resp['data'], $i, 4)));
|
101 |
public static function dailyCron(){
|
102 |
$wfdb = new wfDB();
|
103 |
global $wpdb; $p = $wpdb->base_prefix;
|
104 |
+
$api = new wfAPI(wfConfig::get('apiKey'), wfUtils::getWPVersion());
|
105 |
+
try {
|
106 |
+
$patData = $api->call('get_known_vuln_pattern');
|
107 |
+
if(is_array($patData) && $patData['pat']){
|
108 |
+
if(@preg_match($patData['pat'], 'wordfence_test_vuln_match')){
|
109 |
+
wfConfig::set('vulnRegex', $patData['pat']);
|
110 |
+
}
|
111 |
+
}
|
112 |
+
} catch(Exception $e){
|
113 |
+
wordfence::status(4, 'error', "Could not fetch vulnerability patterns in scheduled job: " . $e->getMessage());
|
114 |
+
}
|
115 |
+
|
116 |
$wfdb->query("delete from $p"."wfLocs where ctime < unix_timestamp() - %d", WORDFENCE_MAX_IPLOC_AGE);
|
117 |
$wfdb->query("truncate table $p"."wfBadLeechers"); //only uses date that's less than 1 minute old
|
118 |
+
$wfdb->query("delete from $p"."wfBlocks where (blockedTime + %s < unix_timestamp()) and permanent=0", wfConfig::get('blockedTime'));
|
119 |
$wfdb->query("delete from $p"."wfCrawlers where lastUpdate < unix_timestamp() - (86400 * 7)");
|
120 |
|
121 |
$count = $wfdb->querySingle("select count(*) as cnt from $p"."wfHits");
|
378 |
header('Location: ' . wp_login_url());
|
379 |
exit();
|
380 |
} else if($_GET['func'] == 'unlockAllIPs'){
|
381 |
+
wordfence::status(1, 'info', "Request received via unlock email link to unblock all IP's.");
|
382 |
$wfLog->unblockAllIPs();
|
383 |
$wfLog->unlockAllIPs();
|
384 |
header('Location: ' . wp_login_url());
|
386 |
} else if($_GET['func'] == 'disableRules'){
|
387 |
wfConfig::set('firewallEnabled', 0);
|
388 |
wfConfig::set('loginSecurityEnabled', 0);
|
389 |
+
wordfence::status(1, 'info', "Request received via unlock email link to unblock all IP's via disabling firewall rules.");
|
390 |
$wfLog->unblockAllIPs();
|
391 |
$wfLog->unlockAllIPs();
|
392 |
header('Location: ' . wp_login_url());
|
623 |
if($res['ok'] && isset($res['isPaid'])){
|
624 |
wfConfig::set('apiKey', $opts['apiKey']);
|
625 |
$reload = 'reload';
|
626 |
+
wfConfig::set('isPaid', $res['isPaid']); //res['isPaid'] is boolean coming back as JSON and turned back into PHP struct. Assuming JSON to PHP handles bools.
|
627 |
if($res['isPaid']){
|
628 |
$paidKeyMsg = true;
|
629 |
}
|
644 |
$wfdb = new wfDB();
|
645 |
global $wpdb;
|
646 |
$p = $wpdb->base_prefix;
|
647 |
+
$wfdb->query("delete from $p"."wfBlocks where wfsn=1 and permanent=0");
|
648 |
}
|
649 |
foreach($opts as $key => $val){
|
650 |
wfConfig::set($key, $val);
|
662 |
$op = $_POST['op'];
|
663 |
$wfLog = self::getLog();
|
664 |
if($op == 'blocked'){
|
665 |
+
wordfence::status(1, 'info', "Ajax request received to unblock All IP's including permanent blocks.");
|
666 |
$wfLog->unblockAllIPs();
|
667 |
} else if($op == 'locked'){
|
668 |
$wfLog->unlockAllIPs();
|
894 |
$wfFunc = get_query_var('_wfsf');
|
895 |
$wfLog = self::getLog();
|
896 |
if($wfLog->logHitOK()){
|
897 |
+
if( (! empty($wfFunc)) && is_404() ){
|
898 |
$wfLog->logLeechAndBlock('404');
|
899 |
} else {
|
900 |
$wfLog->logLeechAndBlock('hit');
|
1089 |
}
|
1090 |
public static function initAction(){
|
1091 |
global $wp;
|
1092 |
+
if (!is_object($wp)) return; //Suggested fix for compatability with "Portable phpmyadmin"
|
1093 |
+
|
1094 |
$wp->add_query_var('_wfsf');
|
1095 |
//add_rewrite_rule('wfStaticFunc/([a-zA-Z0-9]+)/?$', 'index.php?wfStaticFunc=' . $matches[1], 'top');
|
1096 |
$cookieName = 'wfvt_' . crc32(site_url());
|
readme.txt
CHANGED
@@ -3,7 +3,7 @@ Contributors: mmaunder
|
|
3 |
Tags: wordpress, security, wordpress security, security plugin, secure, anti-virus, malware, firewall, antivirus, virus, google safe browsing, phishing, scrapers, hacking, wordfence, securty, secrity, secure
|
4 |
Requires at least: 3.3.1
|
5 |
Tested up to: 3.4.1
|
6 |
-
Stable tag: 3.0.
|
7 |
|
8 |
Wordfence Security is a free enterprise class security plugin that includes a firewall, virus scanning, real-time traffic with geolocation and more.
|
9 |
|
@@ -152,6 +152,18 @@ or a theme, because often these have been updated to fix a security hole.
|
|
152 |
5. If you're technically minded, this is the under-the-hood view of Wordfence options where you can fine-tune your security settings.
|
153 |
|
154 |
== Changelog ==
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
155 |
= 3.0.8 =
|
156 |
* Fixed bug that caused "Could not get the administrator’s user ID. Scan can’t continue."
|
157 |
|
@@ -451,6 +463,9 @@ or a theme, because often these have been updated to fix a security hole.
|
|
451 |
* Initial public release of Wordfence.
|
452 |
|
453 |
== Upgrade Notice ==
|
|
|
|
|
|
|
454 |
= 3.0.6 =
|
455 |
Upgrade immediately. Improves malware URL detection by 20% or more.
|
456 |
|
3 |
Tags: wordpress, security, wordpress security, security plugin, secure, anti-virus, malware, firewall, antivirus, virus, google safe browsing, phishing, scrapers, hacking, wordfence, securty, secrity, secure
|
4 |
Requires at least: 3.3.1
|
5 |
Tested up to: 3.4.1
|
6 |
+
Stable tag: 3.0.9
|
7 |
|
8 |
Wordfence Security is a free enterprise class security plugin that includes a firewall, virus scanning, real-time traffic with geolocation and more.
|
9 |
|
152 |
5. If you're technically minded, this is the under-the-hood view of Wordfence options where you can fine-tune your security settings.
|
153 |
|
154 |
== Changelog ==
|
155 |
+
= 3.0.9 =
|
156 |
+
* Fixed problem where scan process can't get admin ID.
|
157 |
+
* Fixed issue that caused permanent IP's to not be permanent.
|
158 |
+
* Fixed SQL error when calculating if IP block has expired.
|
159 |
+
* Fixed incorrect calling of is_404 that caused intermittent issues.
|
160 |
+
* Fixed basedir warnings when scan tries to scan files it does not have access to.
|
161 |
+
* Fixed warning and incorrect calculation of rows in DB.
|
162 |
+
* Added ability to get IP from "HTTP_X_REAL_IP" header of a front-end proxy is sending it.
|
163 |
+
* Fixed warning about HTTPS element not existing in getRequestedURL()
|
164 |
+
* Fixed problem with paid vs free keys getting confused.
|
165 |
+
* Fixed error with fetching vulnerability patterns.
|
166 |
+
|
167 |
= 3.0.8 =
|
168 |
* Fixed bug that caused "Could not get the administrator’s user ID. Scan can’t continue."
|
169 |
|
463 |
* Initial public release of Wordfence.
|
464 |
|
465 |
== Upgrade Notice ==
|
466 |
+
= 3.0.9 =
|
467 |
+
Upgrade immediately. Fixes two critical bugs: Could not get admin ID bug and permanent IP blocks not staying permanent.
|
468 |
+
|
469 |
= 3.0.6 =
|
470 |
Upgrade immediately. Improves malware URL detection by 20% or more.
|
471 |
|
wfscan.php
CHANGED
@@ -151,10 +151,22 @@ class wfScan {
|
|
151 |
public static function becomeAdmin(){
|
152 |
$db = new wfDB();
|
153 |
global $wpdb;
|
154 |
-
$adminUserID =
|
155 |
-
if(
|
156 |
-
|
157 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
158 |
}
|
159 |
$adminUsername = $db->querySingle("select user_nicename from " . $wpdb->users . " where ID=%d", $adminUserID);
|
160 |
self::status(4, 'info', "Scan will run as admin user '$adminUsername' with ID '$adminUserID'");
|
151 |
public static function becomeAdmin(){
|
152 |
$db = new wfDB();
|
153 |
global $wpdb;
|
154 |
+
$adminUserID = false;
|
155 |
+
if(is_multisite()){
|
156 |
+
$users = get_users('role=super&fields=ID');
|
157 |
+
} else {
|
158 |
+
$users = get_users('role=administrator&fields=ID');
|
159 |
+
}
|
160 |
+
if(sizeof($users) > 1){
|
161 |
+
sort($users, SORT_NUMERIC);
|
162 |
+
$adminUserID = $users[0];
|
163 |
+
} else {
|
164 |
+
//Last ditch attempt
|
165 |
+
$adminUserID = $db->querySingle("select user_id from " . $wpdb->usermeta . " where meta_key='" . $wpdb->base_prefix . "user_level' order by meta_value desc, user_id asc limit 1");
|
166 |
+
if(! $adminUserID){
|
167 |
+
self::status(1, 'error', "Could not get the administrator's user ID. Scan can't continue.");
|
168 |
+
exit();
|
169 |
+
}
|
170 |
}
|
171 |
$adminUsername = $db->querySingle("select user_nicename from " . $wpdb->users . " where ID=%d", $adminUserID);
|
172 |
self::status(4, 'info', "Scan will run as admin user '$adminUsername' with ID '$adminUserID'");
|
wordfence.php
CHANGED
@@ -4,10 +4,10 @@ Plugin Name: Wordfence Security
|
|
4 |
Plugin URI: http://wordfence.com/
|
5 |
Description: Wordfence Security - Anti-virus and Firewall security plugin for WordPress
|
6 |
Author: Mark Maunder
|
7 |
-
Version: 3.0.
|
8 |
Author URI: http://wordfence.com/
|
9 |
*/
|
10 |
-
define('WORDFENCE_VERSION', '3.0.
|
11 |
if(! defined('WORDFENCE_VERSIONONLY_MODE')){
|
12 |
if((int) @ini_get('memory_limit') < 64){
|
13 |
@ini_set('memory_limit', '64M'); //Some hosts have ini set at as little as 32 megs. 64 is the min sane amount of memory.
|
4 |
Plugin URI: http://wordfence.com/
|
5 |
Description: Wordfence Security - Anti-virus and Firewall security plugin for WordPress
|
6 |
Author: Mark Maunder
|
7 |
+
Version: 3.0.9
|
8 |
Author URI: http://wordfence.com/
|
9 |
*/
|
10 |
+
define('WORDFENCE_VERSION', '3.0.9');
|
11 |
if(! defined('WORDFENCE_VERSIONONLY_MODE')){
|
12 |
if((int) @ini_get('memory_limit') < 64){
|
13 |
@ini_set('memory_limit', '64M'); //Some hosts have ini set at as little as 32 megs. 64 is the min sane amount of memory.
|