Wordfence Security – Firewall & Malware Scan - Version 3.0.9

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 Icon 128x128 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 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
- $totalRows += $res2[0];
 
 
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, permanent=%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 (blockedTime + %s) - unix_timestamp() as secsToGo, reason from " . $this->blocksTable . " where IP=%s and (permanent=1 OR blockedTime + %s > unix_timestamp())", wfConfig::get('blockedTime'), $IP, wfConfig::get('blockedTime'))){
475
- $this->getDB()->query("update " . $this->blocksTable . " set lastAttempt=unix_timestamp(), blockedHits = blockedHits + 1 where IP=%s", $IP);
476
- $this->do503($rec['secsToGo'], $rec['reason']);
 
 
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
- $IP = trim($parts[0]);
 
 
 
 
 
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 ($_SERVER['HTTPS'] ? 'https' : 'http') . '://' . $_SERVER['SERVER_NAME'] . $_SERVER['REQUEST_URI'];
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.8
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 = $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");
155
- if(! $adminUserID){
156
- self::status(1, 'error', "Could not get the administrator's user ID. Scan can't continue.");
157
- exit();
 
 
 
 
 
 
 
 
 
 
 
 
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
8
  Author URI: http://wordfence.com/
9
  */
10
- define('WORDFENCE_VERSION', '3.0.8');
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.