Wordfence Security – Firewall & Malware Scan - Version 3.1.1

Version Description

  • Added another fix for "mysql server has gone away" error. Wordfence now makes sure the DB is still connected and reconnects if not.
  • Added new detection for encoded malicious code in files.
  • Fixed bug introduced yesterday that prevented permanent blocking of IP's.
  • Improved ability to detect if we're running on Windows (but we don't support Windows yet).
  • Issue intelligent warning if Wordfence can't read base WordPress directory.
  • Don't activate Wordfence if user is running Windows.
  • Cleaned up errors if a file can't be scanned due to permission restrictions.
  • Improved reporting of which user scan is running as and how we determined who the admin user is.
Download this release

Release Info

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

Code changes from version 3.1.0 to 3.1.1

lib/wfDB.php CHANGED
@@ -6,8 +6,10 @@ class wfDB {
6
  private $dbpassword = false;
7
  private $dbname = false;
8
  private $dbuser = false;
 
9
  public $errorMsg = false;
10
  public function __construct($createNewHandle = false, $dbhost = false, $dbuser = false, $dbpassword = false, $dbname = false){
 
11
  if($dbhost && $dbuser && $dbpassword && $dbname){
12
  $this->dbhost = $dbhost;
13
  $this->dbuser = $dbuser;
@@ -37,14 +39,23 @@ class wfDB {
37
  }
38
  }
39
  }
 
 
 
40
  //We tried reusing wpdb but got disconnection errors from many users.
41
- $handleKey = md5($dbhost . $dbuser . $dbpassword . $dbname);
42
- if( (! $createNewHandle) && isset(self::$dbhCache[$handleKey]) && mysql_ping(self::$dbhCache[$handleKey]) ){
 
43
  $this->dbh = self::$dbhCache[$handleKey];
44
  } else {
45
- $dbh = mysql_connect( $this->dbhost, $this->dbuser, $this->dbpassword, true );
 
 
 
 
 
46
  mysql_select_db($this->dbname, $dbh);
47
- if($createNewHandle){
48
  $this->dbh = $dbh;
49
  } else {
50
  self::$dbhCache[$handleKey] = $dbh;
@@ -56,7 +67,13 @@ class wfDB {
56
  $this->queryIgnoreError("SET @@wait_timeout=30800"); //Changing to session setting bc user may not have super privilege
57
  }
58
  }
 
 
 
 
 
59
  public function querySingleRec(){
 
60
  $this->errorMsg = false;
61
  $args = func_get_args();
62
  if(sizeof($args) == 1){
@@ -81,6 +98,7 @@ class wfDB {
81
  $msg = "Wordfence DB error in " . $caller['file'] . " line " . $caller['line'] . ": $err";
82
  global $wpdb;
83
  $statusTable = $wpdb->base_prefix . 'wfStatus';
 
84
  mysql_query(sprintf("insert into " . $statusTable . " (ctime, level, type, msg) values (%s, %d, '%s', '%s')",
85
  mysql_real_escape_string(sprintf('%.6f', microtime(true))),
86
  mysql_real_escape_string(1),
@@ -91,6 +109,7 @@ class wfDB {
91
  }
92
  }
93
  public function querySingle(){
 
94
  $this->errorMsg = false;
95
  $args = func_get_args();
96
  if(sizeof($args) == 1){
@@ -113,6 +132,7 @@ class wfDB {
113
  return $row[0];
114
  }
115
  public function query(){ //sprintfString, arguments
 
116
  $this->errorMsg = false;
117
  $args = func_get_args();
118
  $isStatusQuery = false;
@@ -136,6 +156,7 @@ class wfDB {
136
  return $res;
137
  }
138
  public function queryIgnoreError(){ //sprintfString, arguments
 
139
  $this->errorMsg = false;
140
  $args = func_get_args();
141
  if(sizeof($args) == 1){
6
  private $dbpassword = false;
7
  private $dbname = false;
8
  private $dbuser = false;
9
+ private $createNewHandle = false;
10
  public $errorMsg = false;
11
  public function __construct($createNewHandle = false, $dbhost = false, $dbuser = false, $dbpassword = false, $dbname = false){
12
+ $this->createNewHandle = $createNewHandle;
13
  if($dbhost && $dbuser && $dbpassword && $dbname){
14
  $this->dbhost = $dbhost;
15
  $this->dbuser = $dbuser;
39
  }
40
  }
41
  }
42
+ $this->connectHandle();
43
+ }
44
+ private function connectHandle(){
45
  //We tried reusing wpdb but got disconnection errors from many users.
46
+ $handleKey = md5($this->dbhost . $this->dbuser . $this->dbpassword . $this->dbname);
47
+ //Use a cached handle if it exists and is still connected
48
+ if( (! $this->createNewHandle) && isset(self::$dbhCache[$handleKey]) && mysql_ping(self::$dbhCache[$handleKey]) ){
49
  $this->dbh = self::$dbhCache[$handleKey];
50
  } else {
51
+ //This close call is to deal with versions of mysql prior to 5.0.3 which auto-recommend when callig ping. So the conditional above may have reconnected this handle, so we disconnect it before reconnecting, if it's connected.
52
+ if(isset(self::$dbhCache[$handleKey]) && mysql_ping(self::$dbhCache[$handleKey])){
53
+ mysql_close(self::$dbhCache[$handleKey]);
54
+ unset(self::$dbhCache[$handleKey]);
55
+ }
56
+ $dbh = mysql_connect($this->dbhost, $this->dbuser, $this->dbpassword, true );
57
  mysql_select_db($this->dbname, $dbh);
58
+ if($this->createNewHandle){
59
  $this->dbh = $dbh;
60
  } else {
61
  self::$dbhCache[$handleKey] = $dbh;
67
  $this->queryIgnoreError("SET @@wait_timeout=30800"); //Changing to session setting bc user may not have super privilege
68
  }
69
  }
70
+ private function reconnect(){
71
+ if(! mysql_ping($this->dbh)){
72
+ $this->connectHandle();
73
+ }
74
+ }
75
  public function querySingleRec(){
76
+ $this->reconnect();
77
  $this->errorMsg = false;
78
  $args = func_get_args();
79
  if(sizeof($args) == 1){
98
  $msg = "Wordfence DB error in " . $caller['file'] . " line " . $caller['line'] . ": $err";
99
  global $wpdb;
100
  $statusTable = $wpdb->base_prefix . 'wfStatus';
101
+ $this->reconnect(); //Putting reconnect here so it doesn't mess with the mysql_error() call
102
  mysql_query(sprintf("insert into " . $statusTable . " (ctime, level, type, msg) values (%s, %d, '%s', '%s')",
103
  mysql_real_escape_string(sprintf('%.6f', microtime(true))),
104
  mysql_real_escape_string(1),
109
  }
110
  }
111
  public function querySingle(){
112
+ $this->reconnect();
113
  $this->errorMsg = false;
114
  $args = func_get_args();
115
  if(sizeof($args) == 1){
132
  return $row[0];
133
  }
134
  public function query(){ //sprintfString, arguments
135
+ $this->reconnect();
136
  $this->errorMsg = false;
137
  $args = func_get_args();
138
  $isStatusQuery = false;
156
  return $res;
157
  }
158
  public function queryIgnoreError(){ //sprintfString, arguments
159
+ $this->reconnect();
160
  $this->errorMsg = false;
161
  $args = func_get_args();
162
  if(sizeof($args) == 1){
lib/wfLog.php CHANGED
@@ -160,15 +160,28 @@ class wfLog {
160
  public function blockIP($IP, $reason, $wfsn = false, $permanent = false){ //wfsn indicates it comes from Wordfence secure network
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
  }
174
  public function lockOutIP($IP, $reason){
160
  public function blockIP($IP, $reason, $wfsn = false, $permanent = false){ //wfsn indicates it comes from Wordfence secure network
161
  if($this->isWhitelisted($IP)){ return false; }
162
  $wfsn = $wfsn ? 1 : 0;
163
+ if($permanent){
164
+ //Insert permanent=1 or update existing perm or non-per block to be permanent
165
+ $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",
166
+ wfUtils::inet_aton($IP),
167
+ $reason,
168
+ $wfsn,
169
+ 1,
170
+ $reason,
171
+ $wfsn,
172
+ 1
173
+ );
174
+ } else {
175
+ //insert perm=0 but don't update and make perm blocks non-perm.
176
+ $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",
177
+ wfUtils::inet_aton($IP),
178
+ $reason,
179
+ $wfsn,
180
+ 0,
181
+ $reason,
182
+ $wfsn
183
+ );
184
+ }
185
  return true;
186
  }
187
  public function lockOutIP($IP, $reason){
lib/wfScanEngine.php CHANGED
@@ -176,6 +176,9 @@ class wfScanEngine {
176
  $this->hasher = new wordfenceHash(strlen(ABSPATH));
177
  $baseWPStuff = array( '.htaccess', 'index.php', 'license.txt', 'readme.html', 'wp-activate.php', 'wp-admin', 'wp-app.php', 'wp-blog-header.php', 'wp-comments-post.php', 'wp-config-sample.php', 'wp-content', 'wp-cron.php', 'wp-includes', 'wp-links-opml.php', 'wp-load.php', 'wp-login.php', 'wp-mail.php', 'wp-pass.php', 'wp-register.php', 'wp-settings.php', 'wp-signup.php', 'wp-trackback.php', 'xmlrpc.php');
178
  $baseContents = scandir(ABSPATH);
 
 
 
179
  $scanOutside = wfConfig::get('other_scanOutside');
180
  if($scanOutside){
181
  wordfence::status(2, 'info', "Including files that are outside the WordPress installation in the scan.");
176
  $this->hasher = new wordfenceHash(strlen(ABSPATH));
177
  $baseWPStuff = array( '.htaccess', 'index.php', 'license.txt', 'readme.html', 'wp-activate.php', 'wp-admin', 'wp-app.php', 'wp-blog-header.php', 'wp-comments-post.php', 'wp-config-sample.php', 'wp-content', 'wp-cron.php', 'wp-includes', 'wp-links-opml.php', 'wp-load.php', 'wp-login.php', 'wp-mail.php', 'wp-pass.php', 'wp-register.php', 'wp-settings.php', 'wp-signup.php', 'wp-trackback.php', 'xmlrpc.php');
178
  $baseContents = scandir(ABSPATH);
179
+ if(! is_array($baseContents)){
180
+ throw new Exception("Wordfence could not read the contents of your base WordPress directory. This usually indicates your permissions are so strict that your web server can't read your WordPress directory.");
181
+ }
182
  $scanOutside = wfConfig::get('other_scanOutside');
183
  if($scanOutside){
184
  wordfence::status(2, 'info', "Including files that are outside the WordPress installation in the scan.");
lib/wfUtils.php CHANGED
@@ -246,7 +246,7 @@ class wfUtils {
246
  }
247
  public static function isWindows(){
248
  if(! self::$isWindows){
249
- if(preg_match('/^win/', PHP_OS)){
250
  self::$isWindows = 'yes';
251
  } else {
252
  self::$isWindows = 'no';
@@ -392,7 +392,9 @@ class wfUtils {
392
  if(class_exists('wfScan')){ wfScan::$errorHandlingOn = true; }
393
  }
394
  public static function fileTooBig($file){
 
395
  $fh = @fopen($file, 'r');
 
396
  if(! $fh){ return false; }
397
  $offset = WORDFENCE_MAX_FILE_SIZE_TO_PROCESS + 1;
398
  $tooBig = false;
246
  }
247
  public static function isWindows(){
248
  if(! self::$isWindows){
249
+ if(preg_match('/^win/i', PHP_OS)){
250
  self::$isWindows = 'yes';
251
  } else {
252
  self::$isWindows = 'no';
392
  if(class_exists('wfScan')){ wfScan::$errorHandlingOn = true; }
393
  }
394
  public static function fileTooBig($file){
395
+ wfUtils::errorsOff();
396
  $fh = @fopen($file, 'r');
397
+ wfUtils::errorsOn();
398
  if(! $fh){ return false; }
399
  $offset = WORDFENCE_MAX_FILE_SIZE_TO_PROCESS + 1;
400
  $tooBig = false;
lib/wordfenceClass.php CHANGED
@@ -25,6 +25,10 @@ class wordfence {
25
  private static $statusStartMsgs = array();
26
  private static $debugOn = null;
27
  public static function installPlugin(){
 
 
 
 
28
  self::runInstall();
29
  //Used by MU code below
30
  update_option('wordfenceActivated', 1);
25
  private static $statusStartMsgs = array();
26
  private static $debugOn = null;
27
  public static function installPlugin(){
28
+ if(wfUtils::isWindows()){
29
+ die("You are running Windows. Unfortunately Wordfence is not supported on Windows at this time. We may add Windows support in future, but have no ETA at present.");
30
+ }
31
+
32
  self::runInstall();
33
  //Used by MU code below
34
  update_option('wordfenceActivated', 1);
lib/wordfenceHash.php CHANGED
@@ -169,7 +169,7 @@ class wordfenceHash {
169
  $this->writeHashingStatus();
170
  }
171
  } else {
172
- wordfence::status(2, 'error', "Could not gen hash for file: $file");
173
  }
174
  }
175
  private function sendHashPacket(){
@@ -199,7 +199,10 @@ class wordfenceHash {
199
  return $this->hashStorageID;
200
  }
201
  public function wfHash($file){
 
202
  $md5 = @md5_file($file, false);
 
 
203
  if(! $md5){ return false; }
204
  $fp = @fopen($file, "rb");
205
  if(! $fp){
169
  $this->writeHashingStatus();
170
  }
171
  } else {
172
+ wordfence::status(2, 'error', "Could not gen hash for file (probably because we don't have permission to access the file): $file");
173
  }
174
  }
175
  private function sendHashPacket(){
199
  return $this->hashStorageID;
200
  }
201
  public function wfHash($file){
202
+ wfUtils::errorsOff();
203
  $md5 = @md5_file($file, false);
204
+ wfUtils::errorsOn();
205
+
206
  if(! $md5){ return false; }
207
  $fp = @fopen($file, "rb");
208
  if(! $fp){
lib/wordfenceScanner.php CHANGED
@@ -135,7 +135,23 @@ class wordfenceScanner {
135
  ));
136
  break;
137
  }
138
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
139
  $this->urlHoover->hoover($file, $data);
140
  } else {
141
  $this->urlHoover->hoover($file, $data);
@@ -170,7 +186,7 @@ class wordfenceScanner {
170
  'ignoreP' => $this->path . $file,
171
  'ignoreC' => md5_file($this->path . $file),
172
  'shortMsg' => "File contains suspected malware URL: " . $this->path . $file,
173
- 'longMsg' => "This file contains a suspected malware URL listed on Google's list of malware sites. Wordfence decodes base64 when scanning files so the URL may not be visible if you view this file. The URL is: " . $result['URL'] . " - More info available at <a href=\"http://safebrowsing.clients.google.com/safebrowsing/diagnostic?site=" . urlencode($result['URL']) . "&client=googlechrome&hl=en-US\" target=\"_blank\">Google Safe Browsing diagnostic page</a>.",
174
  'data' => array(
175
  'file' => $file,
176
  'badURL' => $result['URL'],
@@ -225,7 +241,7 @@ class wordfenceScanner {
225
  }
226
  public static function containsCode($arr){
227
  foreach($arr as $elem){
228
- if(preg_match('/(?:base64_decode|base64_encode|eval|if|exists|isset|close|file|implode|fopen|while|feof|fread|fclose|fsockopen|fwrite|explode|chr|gethostbyname|strstr|filemtime|time|count|trim|rand|stristr|dir|mkdir|urlencode|ord|substr|unpack|strpos|sprintf)[\r\n\s\t]*\(/i', $elem)){
229
  return true;
230
  }
231
  }
135
  ));
136
  break;
137
  }
138
+ if(preg_match('/eval.*base'.'64_decode/i', $data)){
139
+ $this->addResult(array(
140
+ 'type' => 'file',
141
+ 'severity' => 1,
142
+ 'ignoreP' => $this->path . $file,
143
+ 'ignoreC' => $fileSum,
144
+ 'shortMsg' => "This file may contain malicious executable code",
145
+ 'longMsg' => "This file is a PHP executable file and contains an evaluation function and base"."64 decoding function on the same line. This is a common technique used by hackers to hide and execute code. If you know about this file you can choose to ignore it to exclude it from future scans.",
146
+ 'data' => array(
147
+ 'file' => $file,
148
+ 'canDiff' => false,
149
+ 'canFix' => false,
150
+ 'canDelete' => true
151
+ )
152
+ ));
153
+ break;
154
+ }
155
  $this->urlHoover->hoover($file, $data);
156
  } else {
157
  $this->urlHoover->hoover($file, $data);
186
  'ignoreP' => $this->path . $file,
187
  'ignoreC' => md5_file($this->path . $file),
188
  'shortMsg' => "File contains suspected malware URL: " . $this->path . $file,
189
+ 'longMsg' => "This file contains a suspected malware URL listed on Google's list of malware sites. Wordfence decodes base"."64 when scanning files so the URL may not be visible if you view this file. The URL is: " . $result['URL'] . " - More info available at <a href=\"http://safebrowsing.clients.google.com/safebrowsing/diagnostic?site=" . urlencode($result['URL']) . "&client=googlechrome&hl=en-US\" target=\"_blank\">Google Safe Browsing diagnostic page</a>.",
190
  'data' => array(
191
  'file' => $file,
192
  'badURL' => $result['URL'],
241
  }
242
  public static function containsCode($arr){
243
  foreach($arr as $elem){
244
+ if(preg_match('/(?:base'.'64_decode|base'.'64_encode|eval|if|exists|isset|close|file|implode|fopen|while|feof|fread|fclose|fsockopen|fwrite|explode|chr|gethostbyname|strstr|filemtime|time|count|trim|rand|stristr|dir|mkdir|urlencode|ord|substr|unpack|strpos|sprintf)[\r\n\s\t]*\(/i', $elem)){
245
  return true;
246
  }
247
  }
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.1.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,16 @@ 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.1.0 =
156
  * Changed the way we monitor disk space from % to warning on 20 megs and critical on 5 megs remaining. This deals with very large disks in a more rational way. (Thanks Yael M. and Ola A.)
157
  * We now deal with cases where the $_SERVER variable contains an array instead of string for IP address. It seems that some installations modify the value into an array. (Thanks S.S.)
@@ -468,6 +478,9 @@ or a theme, because often these have been updated to fix a security hole.
468
  * Initial public release of Wordfence.
469
 
470
  == Upgrade Notice ==
 
 
 
471
  = 3.0.9 =
472
  Upgrade immediately. Fixes two critical bugs: Could not get admin ID bug and permanent IP blocks not staying permanent.
473
 
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.1.1
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.1.1 =
156
+ * Added another fix for "mysql server has gone away" error. Wordfence now makes sure the DB is still connected and reconnects if not.
157
+ * Added new detection for encoded malicious code in files.
158
+ * Fixed bug introduced yesterday that prevented permanent blocking of IP's.
159
+ * Improved ability to detect if we're running on Windows (but we don't support Windows yet).
160
+ * Issue intelligent warning if Wordfence can't read base WordPress directory.
161
+ * Don't activate Wordfence if user is running Windows.
162
+ * Cleaned up errors if a file can't be scanned due to permission restrictions.
163
+ * Improved reporting of which user scan is running as and how we determined who the admin user is.
164
+
165
  = 3.1.0 =
166
  * Changed the way we monitor disk space from % to warning on 20 megs and critical on 5 megs remaining. This deals with very large disks in a more rational way. (Thanks Yael M. and Ola A.)
167
  * We now deal with cases where the $_SERVER variable contains an array instead of string for IP address. It seems that some installations modify the value into an array. (Thanks S.S.)
478
  * Initial public release of Wordfence.
479
 
480
  == Upgrade Notice ==
481
+ = 3.1.1 =
482
+ Upgrade immediately. Fixes bug introduced in last release that broke permenent IP blocking.
483
+
484
  = 3.0.9 =
485
  Upgrade immediately. Fixes two critical bugs: Could not get admin ID bug and permanent IP blocks not staying permanent.
486
 
wfscan.php CHANGED
@@ -152,10 +152,13 @@ class wfScan {
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);
@@ -167,12 +170,13 @@ class wfScan {
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'");
173
  wp_set_current_user($adminUserID);
174
  if(! is_user_logged_in()){
175
- self::status(1, 'error', "Scan could not sign in as user '$adminUsername' with ID '$adminUserID'. Scan can't continue.");
176
  exit();
177
  }
178
  self::status(4, 'info', "Scan authentication complete.");
152
  $db = new wfDB();
153
  global $wpdb;
154
  $adminUserID = false;
155
+ $userSource = '';
156
  if(is_multisite()){
157
  $users = get_users('role=super&fields=ID');
158
+ $userSource = 'multisite get_users() function';
159
  } else {
160
  $users = get_users('role=administrator&fields=ID');
161
+ $userSource = 'singlesite get_users() function';
162
  }
163
  if(sizeof($users) > 1){
164
  sort($users, SORT_NUMERIC);
170
  self::status(1, 'error', "Could not get the administrator's user ID. Scan can't continue.");
171
  exit();
172
  }
173
+ $userSource = 'manual DB query';
174
  }
175
+ $adminUsername = $db->querySingle("select user_login from " . $wpdb->users . " where ID=%d", $adminUserID);
176
+ self::status(4, 'info', "Scan will run as admin user '$adminUsername' with ID '$adminUserID' sourced from: $userSource");
177
  wp_set_current_user($adminUserID);
178
  if(! is_user_logged_in()){
179
+ self::status(1, 'error', "Scan could not sign in as user '$adminUsername' with ID '$adminUserID' from source '$userSource'. Scan can't continue.");
180
  exit();
181
  }
182
  self::status(4, 'info', "Scan authentication complete.");
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.1.0
8
  Author URI: http://wordfence.com/
9
  */
10
- define('WORDFENCE_VERSION', '3.1.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.1.1
8
  Author URI: http://wordfence.com/
9
  */
10
+ define('WORDFENCE_VERSION', '3.1.1');
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.