Wordfence Security – Firewall & Malware Scan - Version 2.1.4

Version Description

  • Fixed registered users not appearing in live traffic.
  • Fixed temp file deletion bug that caused warnings and loops.
  • Fixed issue that caused warning about WORDFENCE_VERSION
  • Fixed Wordfence admin area not working under SSL
  • Fixed bug that caused IP addresses of clients to be misinterpreted if there are multiple addresses from chained proxies.
  • Now stripping port numbers from IP's which we weren't doing before.
  • Added check for validity of IP's and report fatal error if it fails because this could lock users out.
  • Improved error reporting including fixing an out of memory error when a specific error condition arose in wfConfig::set()
  • Changed order of tmp dirs to be wordfence/lib protected dir first and then system temp dir. Added uploads as tmp dir for last resort.
  • Malware URL's are now marked in red in alerts so it's obvious what the offending URL in a file is.
Download this release

Release Info

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

Code changes from version 2.1.3 to 2.1.4

lib/menu_scan.php CHANGED
@@ -393,6 +393,9 @@
393
  <p>
394
  <table border="0" class="wfIssue" cellspacing="0" cellpadding="0">
395
  <tr><th>Filename:</th><td>${data.file}</td></tr>
 
 
 
396
  <tr><th>File type:</th><td>{{if data.cType}}${WFAD.ucfirst(data.cType)}{{else}}Not a core, theme or plugin file.{{/if}}</td></tr>
397
  <tr><th>Issue first detected:</th><td>${timeAgo} ago.</td></tr>
398
  <tr><th>Severity:</th><td>{{if severity == '1'}}Critical{{else}}Warning{{/if}}</td></tr>
393
  <p>
394
  <table border="0" class="wfIssue" cellspacing="0" cellpadding="0">
395
  <tr><th>Filename:</th><td>${data.file}</td></tr>
396
+ {{if ((typeof data.badURL !== 'undefined') && data.badURL)}}
397
+ <tr><th>Bad URL:</th><td><strong class="wfWarn">${data.badURL}</strong></td></tr>
398
+ {{/if}}
399
  <tr><th>File type:</th><td>{{if data.cType}}${WFAD.ucfirst(data.cType)}{{else}}Not a core, theme or plugin file.{{/if}}</td></tr>
400
  <tr><th>Issue first detected:</th><td>${timeAgo} ago.</td></tr>
401
  <tr><th>Severity:</th><td>{{if severity == '1'}}Critical{{else}}Warning{{/if}}</td></tr>
lib/wfConfig.php CHANGED
@@ -4,6 +4,7 @@ class wfConfig {
4
  private static $cache = array();
5
  private static $DB = false;
6
  private static $tmpFileHeader = "<?php\n/* Wordfence temporary file security header */\necho \"Nothing to see here!\\n\"; exit(0);\n?>";
 
7
  public static $securityLevels = array(
8
  array( //level 0
9
  "checkboxes" => array(
@@ -372,7 +373,10 @@ class wfConfig {
372
  }
373
  public static function set($key, $val){
374
  if(is_array($val)){
375
- $trace=debug_backtrace(); $caller=array_shift($trace); error_log("wfConfig::set() got array as second param. Please use set_ser(). " . $caller['file'] . " line " . $caller['line']);
 
 
 
376
  }
377
 
378
  self::getDB()->query("insert into " . self::table() . " (name, val) values ('%s', '%s') ON DUPLICATE KEY UPDATE val='%s'", $key, $val, $val);
@@ -393,28 +397,22 @@ class wfConfig {
393
  //If we can use disk, check if there are any values stored on disk first and read them instead of the DB if there are values
394
  if($canUseDisk){
395
  $filename = 'wordfence_tmpfile_' . $key . '.php';
396
- $dirs = self::getTempDirs();
397
- $obj = false;
398
- $foundFiles = false;
399
- foreach($dirs as $dir){
400
- $dir = rtrim($dir, '/') . '/';
401
  $fullFile = $dir . $filename;
402
  if(file_exists($fullFile)){
403
- $foundFiles = true;
404
  wordfence::status(4, 'info', "Loading serialized data from file $fullFile");
405
  $obj = unserialize(substr(file_get_contents($fullFile), strlen(self::$tmpFileHeader))); //Strip off security header and unserialize
406
- if($obj){
407
- break;
408
- } else {
409
  wordfence::status(2, 'error', "Could not unserialize file $fullFile");
410
  }
 
 
 
 
411
  }
412
- }
413
- if($foundFiles){
414
- self::deleteOldTempFiles($filename);
415
- }
416
- if($obj){ //If we managed to deserialize something, clean ALL tmp dirs of this file and return obj
417
- return $obj;
418
  }
419
  }
420
 
@@ -442,33 +440,37 @@ class wfConfig {
442
  $tempFilename = 'wordfence_tmpfile_' . $key . '.php';
443
  if((strlen($serialized) * 1.1) > self::getDB()->getMaxAllowedPacketBytes()){ //If it's greater than max_allowed_packet + 10% for escaping and SQL
444
  if($canUseDisk){
445
- self::deleteOldTempFiles($tempFilename);
446
- $dirs = self::getTempDirs();
447
- $fh = false;
448
- foreach($dirs as $dir){
449
- $dir = rtrim($dir, '/') . '/';
450
  $fullFile = $dir . $tempFilename;
 
451
  $fh = fopen($fullFile, 'w');
452
  if($fh){
453
  wordfence::status(4, 'info', "Serialized data for $key is " . strlen($serialized) . " bytes and is greater than max_allowed packet so writing it to disk file: " . $fullFile);
454
- break;
 
 
455
  }
 
 
 
 
 
 
 
456
  }
457
- if(! $fh){
458
- wordfence::status(1, 'error', "Your database doesn't allow big packets so we have to use files to store temporary data and Wordfence can't find a place to write them. Either ask your admin to increase max_allowed_packet on your MySQL database, or make one of the following directories writable by your web server: " . implode(', ', $dirs));
459
- exit();
460
- }
461
- fwrite($fh, self::$tmpFileHeader);
462
- fwrite($fh, $serialized);
463
- fclose($fh);
464
- return true;
465
  } else {
466
  wordfence::status(1, 'error', "Wordfence tried to save a variable with name '$key' and your database max_allowed_packet is set to be too small. This particular variable can't be saved to disk. Please ask your administrator to increase max_allowed_packet and also report this in the Wordfence forums because it may be a bug. Thanks.");
467
  exit(0);
468
  }
469
  } else {
470
  //Delete temp files on disk or else the DB will be written to but get_ser will see files on disk and read them instead
471
- self::deleteOldTempFiles($tempFilename);
 
 
 
472
  $exists = self::getDB()->querySingle("select name from " . self::table() . " where name='%s'", $key);
473
  if($exists){
474
  $res = mysql_query("update " . self::table() . " set val='" . mysql_real_escape_string($serialized) . "' where name='" . mysql_real_escape_string($key) . "'", $dbh);
@@ -485,18 +487,33 @@ class wfConfig {
485
  }
486
  return true;
487
  }
488
- private static function deleteOldTempFiles($filename){
489
- $dirs = self::getTempDirs();
490
- foreach($dirs as &$dir){ //clean out old files in all dirs
491
- $dir = rtrim($dir, '/') . '/';
492
- $fullFile = $dir . $filename;
493
- if(file_exists($fullFile)){
494
- unlink($fullFile);
495
- }
496
  }
497
  }
498
- private static function getTempDirs(){
499
- return array(sys_get_temp_dir(), wfUtils::getPluginBaseDir() . 'wordfence/tmp/');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
500
  }
501
  public static function f($key){
502
  echo esc_attr(self::get($key));
4
  private static $cache = array();
5
  private static $DB = false;
6
  private static $tmpFileHeader = "<?php\n/* Wordfence temporary file security header */\necho \"Nothing to see here!\\n\"; exit(0);\n?>";
7
+ private static $tmpDirCache = false;
8
  public static $securityLevels = array(
9
  array( //level 0
10
  "checkboxes" => array(
373
  }
374
  public static function set($key, $val){
375
  if(is_array($val)){
376
+ $msg = "wfConfig::set() got an array as second param with key: $key - Please report this bug. Exiting.";
377
+ wfstatus(1, 'error', $msg);
378
+ error_log($msg);
379
+ exit(0);
380
  }
381
 
382
  self::getDB()->query("insert into " . self::table() . " (name, val) values ('%s', '%s') ON DUPLICATE KEY UPDATE val='%s'", $key, $val, $val);
397
  //If we can use disk, check if there are any values stored on disk first and read them instead of the DB if there are values
398
  if($canUseDisk){
399
  $filename = 'wordfence_tmpfile_' . $key . '.php';
400
+ $dir = self::getTempDir();
401
+ if($dir){
402
+ $obj = false;
403
+ $foundFiles = false;
 
404
  $fullFile = $dir . $filename;
405
  if(file_exists($fullFile)){
 
406
  wordfence::status(4, 'info', "Loading serialized data from file $fullFile");
407
  $obj = unserialize(substr(file_get_contents($fullFile), strlen(self::$tmpFileHeader))); //Strip off security header and unserialize
408
+ if(! $obj){
 
 
409
  wordfence::status(2, 'error', "Could not unserialize file $fullFile");
410
  }
411
+ self::deleteOldTempFile($fullFile);
412
+ }
413
+ if($obj){ //If we managed to deserialize something, clean ALL tmp dirs of this file and return obj
414
+ return $obj;
415
  }
 
 
 
 
 
 
416
  }
417
  }
418
 
440
  $tempFilename = 'wordfence_tmpfile_' . $key . '.php';
441
  if((strlen($serialized) * 1.1) > self::getDB()->getMaxAllowedPacketBytes()){ //If it's greater than max_allowed_packet + 10% for escaping and SQL
442
  if($canUseDisk){
443
+ $dir = self::getTempDir();
444
+ if($dir){
445
+ $fh = false;
 
 
446
  $fullFile = $dir . $tempFilename;
447
+ self::deleteOldTempFile($fullFile);
448
  $fh = fopen($fullFile, 'w');
449
  if($fh){
450
  wordfence::status(4, 'info', "Serialized data for $key is " . strlen($serialized) . " bytes and is greater than max_allowed packet so writing it to disk file: " . $fullFile);
451
+ } else {
452
+ wordfence::status(1, 'error', "Your database doesn't allow big packets so we have to use files to store temporary data and Wordfence can't find a place to write them. Either ask your admin to increase max_allowed_packet on your MySQL database, or make one of the following directories writable by your web server: " . implode(', ', $dirs));
453
+ exit();
454
  }
455
+ fwrite($fh, self::$tmpFileHeader);
456
+ fwrite($fh, $serialized);
457
+ fclose($fh);
458
+ return true;
459
+ } else {
460
+ wordfence::status(1, 'error', "Wordfence tried to save a variable with name '$key' and your database max_allowed_packet is set to be too small. We then tried to save it to disk, but you don't have a temporary directory that is writable. You can fix this by making the /wp-content/plugins/wordfence/tmp/ directory writable by your web server. Or by increasing your max_allowed_packet configuration variable in your mysql database.");
461
+ exit(0);
462
  }
463
+
 
 
 
 
 
 
 
464
  } else {
465
  wordfence::status(1, 'error', "Wordfence tried to save a variable with name '$key' and your database max_allowed_packet is set to be too small. This particular variable can't be saved to disk. Please ask your administrator to increase max_allowed_packet and also report this in the Wordfence forums because it may be a bug. Thanks.");
466
  exit(0);
467
  }
468
  } else {
469
  //Delete temp files on disk or else the DB will be written to but get_ser will see files on disk and read them instead
470
+ $tempDir = self::getTempDir();
471
+ if($tempDir){
472
+ self::deleteOldTempFile($tempDir . $tempFilename);
473
+ }
474
  $exists = self::getDB()->querySingle("select name from " . self::table() . " where name='%s'", $key);
475
  if($exists){
476
  $res = mysql_query("update " . self::table() . " set val='" . mysql_real_escape_string($serialized) . "' where name='" . mysql_real_escape_string($key) . "'", $dbh);
487
  }
488
  return true;
489
  }
490
+ private static function deleteOldTempFile($filename){
491
+ if(file_exists($filename)){
492
+ unlink($filename);
 
 
 
 
 
493
  }
494
  }
495
+ private static function getTempDir(){
496
+ if(! self::$tmpDirCache){
497
+ $dirs = array(wfUtils::getPluginBaseDir() . 'wordfence/tmp/', sys_get_temp_dir(), ABSPATH . 'wp-content/uploads/');
498
+ $finalDir = 'notmp';
499
+ foreach($dirs as $dir){
500
+ $dir = rtrim($dir, '/') . '/';
501
+ $fh = fopen($dir . 'wftmptest.txt', 'w');
502
+ if(! $fh){ continue; }
503
+ $bytes = fwrite($fh, 'test');
504
+ if($bytes != 4){ fclose($fh); continue; }
505
+ fclose($fh);
506
+ if(! unlink($dir . 'wftmptest.txt')){ continue; }
507
+ $finalDir = $dir;
508
+ break;
509
+ }
510
+ self::$tmpDirCache = $finalDir;
511
+ }
512
+ if(self::$tmpDirCache == 'notmp'){
513
+ return false;
514
+ } else {
515
+ return self::$tmpDirCache;
516
+ }
517
  }
518
  public static function f($key){
519
  echo esc_attr(self::get($key));
lib/wfDB.php CHANGED
@@ -35,8 +35,9 @@ class wfDB {
35
  mysql_select_db($this->dbname, $dbh);
36
  $this->dbh = $dbh;
37
  $this->query("SET NAMES 'utf8'");
 
38
  //Set big packets for set_ser when it serializes a scan in between forks
39
- //$this->queryIgnoreError("SET GLOBAL max_allowed_packet=256*1024*1024");
40
  } else {
41
  $handleKey = md5($dbhost . $dbuser . $dbpassword . $dbname);
42
  if(isset(self::$dbhCache[$handleKey])){
@@ -51,8 +52,9 @@ class wfDB {
51
  self::$dbhCache[$handleKey] = $dbh;
52
  $this->dbh = self::$dbhCache[$handleKey];
53
  $this->query("SET NAMES 'utf8'");
 
54
  //Set big packets for set_ser when it serializes a scan in between forks
55
- //$this->queryIgnoreError("SET GLOBAL max_allowed_packet=256*1024*1024");
56
  }
57
  }
58
  }
35
  mysql_select_db($this->dbname, $dbh);
36
  $this->dbh = $dbh;
37
  $this->query("SET NAMES 'utf8'");
38
+
39
  //Set big packets for set_ser when it serializes a scan in between forks
40
+ $this->queryIgnoreError("SET GLOBAL max_allowed_packet=256*1024*1024");
41
  } else {
42
  $handleKey = md5($dbhost . $dbuser . $dbpassword . $dbname);
43
  if(isset(self::$dbhCache[$handleKey])){
52
  self::$dbhCache[$handleKey] = $dbh;
53
  $this->dbh = self::$dbhCache[$handleKey];
54
  $this->query("SET NAMES 'utf8'");
55
+
56
  //Set big packets for set_ser when it serializes a scan in between forks
57
+ $this->queryIgnoreError("SET GLOBAL max_allowed_packet=256*1024*1024");
58
  }
59
  }
60
  }
lib/wfUtils.php CHANGED
@@ -1,4 +1,5 @@
1
  <?php
 
2
  class wfUtils {
3
  private static $isWindows = false;
4
  public static $scanLockFH = false;
@@ -78,7 +79,34 @@ class wfUtils {
78
  if((! $ip) && isset($_SERVER['REMOTE_ADDR'])){
79
  $ip = $_SERVER['REMOTE_ADDR'];
80
  }
81
- return $ip;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
82
  }
83
  public static function getRequestedURL(){
84
  return ($_SERVER['HTTPS'] ? 'https' : 'http') . '://' . $_SERVER['SERVER_NAME'] . $_SERVER['REQUEST_URI'];
1
  <?php
2
+ require_once('wfConfig.php');
3
  class wfUtils {
4
  private static $isWindows = false;
5
  public static $scanLockFH = false;
79
  if((! $ip) && isset($_SERVER['REMOTE_ADDR'])){
80
  $ip = $_SERVER['REMOTE_ADDR'];
81
  }
82
+ if(preg_match('/,/', $ip)){
83
+ $parts = explode(',', $ip);
84
+ $ip = trim($parts[0]);
85
+ }
86
+ if(preg_match('/:\d+$/', $ip)){
87
+ $ip = preg_replace('/:\d+$/', '', $ip);
88
+ }
89
+ if(self::isValidIP($ip)){
90
+ return $ip;
91
+ } else {
92
+ $msg = "Wordfence is not able to determine the IP addresses of visitors to your site and can't operate. We received IP: $ip from header1: " . $_SERVER['HTTP_X_FORWARDED_FOR'] . " and header2: " . $_SERVER['REMOTE_ADDR'];
93
+ wordfence::status(1, 'error', $msg);
94
+ error_log($msg);
95
+ exit(0);
96
+ }
97
+ }
98
+ public static function isValidIP($IP){
99
+ if(preg_match('/^(\d+)\.(\d+)\.(\d+)\.(\d+)$/', $IP, $m)){
100
+ if(
101
+ $m[0] >= 0 && $m[0] <= 255 &&
102
+ $m[1] >= 0 && $m[1] <= 255 &&
103
+ $m[2] >= 0 && $m[2] <= 255 &&
104
+ $m[3] >= 0 && $m[3] <= 255
105
+ ){
106
+ return true;
107
+ }
108
+ }
109
+ return false;
110
  }
111
  public static function getRequestedURL(){
112
  return ($_SERVER['HTTPS'] ? 'https' : 'http') . '://' . $_SERVER['SERVER_NAME'] . $_SERVER['REQUEST_URI'];
lib/wordfenceClass.php CHANGED
@@ -754,7 +754,7 @@ class wordfence {
754
  );
755
  $events = array();
756
  $alsoGet = $_POST['alsoGet'];
757
- if(preg_match('/^logList_(404|hit|human|crawler|gCrawler|loginLogout)$/', $alsoGet, $m)){
758
  $type = $m[1];
759
  $newestEventTime = $_POST['otherParams'];
760
  $listType = 'hits';
@@ -1105,9 +1105,9 @@ class wordfence {
1105
 
1106
  if(preg_match('/^Wordfence/', @$_GET['page'])){
1107
 
1108
- wp_enqueue_style('wordfence-main-style', WP_PLUGIN_URL . '/wordfence/css/main.css', '', WORDFENCE_VERSION);
1109
- wp_enqueue_style('wordfence-colorbox-style', WP_PLUGIN_URL . '/wordfence/css/colorbox.css', '', WORDFENCE_VERSION);
1110
- wp_enqueue_style('wordfence-dttable-style', WP_PLUGIN_URL . '/wordfence/css/dt_table.css', '', WORDFENCE_VERSION);
1111
 
1112
  wp_enqueue_script('json2');
1113
  wp_enqueue_script('jquery.tmpl', wfUtils::getBaseURL() . 'js/jquery.tmpl.min.js', array('jquery'), WORDFENCE_VERSION);
@@ -1144,7 +1144,7 @@ class wordfence {
1144
  }
1145
  }
1146
  add_submenu_page("Wordfence", "Scan", "Scan", "activate_plugins", "Wordfence", 'wordfence::menu_scan');
1147
- add_menu_page('Wordfence', 'Wordfence', 'activate_plugins', 'Wordfence', 'wordfence::menu_scan', WP_PLUGIN_URL . '/wordfence/images/wordfence-logo-16x16.png');
1148
  if(wfConfig::get('liveTrafficEnabled')){
1149
  add_submenu_page("Wordfence", "Live Traffic", "Live Traffic", "activate_plugins", "WordfenceActivity", 'wordfence::menu_activity');
1150
  }
754
  );
755
  $events = array();
756
  $alsoGet = $_POST['alsoGet'];
757
+ if(preg_match('/^logList_(404|hit|human|ruser|crawler|gCrawler|loginLogout)$/', $alsoGet, $m)){
758
  $type = $m[1];
759
  $newestEventTime = $_POST['otherParams'];
760
  $listType = 'hits';
1105
 
1106
  if(preg_match('/^Wordfence/', @$_GET['page'])){
1107
 
1108
+ wp_enqueue_style('wordfence-main-style', wfUtils::getBaseURL() . 'css/main.css', '', WORDFENCE_VERSION);
1109
+ wp_enqueue_style('wordfence-colorbox-style', wfUtils::getBaseURL() . 'css/colorbox.css', '', WORDFENCE_VERSION);
1110
+ wp_enqueue_style('wordfence-dttable-style', wfUtils::getBaseURL() . 'css/dt_table.css', '', WORDFENCE_VERSION);
1111
 
1112
  wp_enqueue_script('json2');
1113
  wp_enqueue_script('jquery.tmpl', wfUtils::getBaseURL() . 'js/jquery.tmpl.min.js', array('jquery'), WORDFENCE_VERSION);
1144
  }
1145
  }
1146
  add_submenu_page("Wordfence", "Scan", "Scan", "activate_plugins", "Wordfence", 'wordfence::menu_scan');
1147
+ add_menu_page('Wordfence', 'Wordfence', 'activate_plugins', 'Wordfence', 'wordfence::menu_scan', wfUtils::getBaseURL() . 'images/wordfence-logo-16x16.png');
1148
  if(wfConfig::get('liveTrafficEnabled')){
1149
  add_submenu_page("Wordfence", "Live Traffic", "Live Traffic", "activate_plugins", "WordfenceActivity", 'wordfence::menu_activity');
1150
  }
lib/wordfenceScanner.php CHANGED
@@ -143,6 +143,7 @@ class wordfenceScanner {
143
  '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>.",
144
  'data' => array(
145
  'file' => $file,
 
146
  'canDiff' => false,
147
  'canFix' => false,
148
  'canDelete' => true,
@@ -159,6 +160,7 @@ class wordfenceScanner {
159
  'longMsg' => "This file contains a URL that is a suspected phishing site that is currently listed on Google's list of known phishing sites. The URL is: " . $result['URL'],
160
  'data' => array(
161
  'file' => $file,
 
162
  'canDiff' => false,
163
  'canFix' => false,
164
  'canDelete' => true,
143
  '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>.",
144
  'data' => array(
145
  'file' => $file,
146
+ 'badURL' => $result['URL'],
147
  'canDiff' => false,
148
  'canFix' => false,
149
  'canDelete' => true,
160
  'longMsg' => "This file contains a URL that is a suspected phishing site that is currently listed on Google's list of known phishing sites. The URL is: " . $result['URL'],
161
  'data' => array(
162
  'file' => $file,
163
+ 'badURL' => $result['URL'],
164
  'canDiff' => false,
165
  'canFix' => false,
166
  'canDelete' => true,
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.3.2
6
- Stable tag: 2.1.2
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,7 +152,19 @@ 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
- = 2.1.3: June 5, 2012 dev release =
 
 
 
 
 
 
 
 
 
 
 
 
156
  * Added fix for hosts that have max_allowed_packet set too small. We will write a temp file to disk instead if possible.
157
  * Increased size of status column to 1000 chars
158
 
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.3.2
6
+ Stable tag: 2.1.4
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
+ = 2.1.4 =
156
+ * Fixed registered users not appearing in live traffic.
157
+ * Fixed temp file deletion bug that caused warnings and loops.
158
+ * Fixed issue that caused warning about WORDFENCE_VERSION
159
+ * Fixed Wordfence admin area not working under SSL
160
+ * Fixed bug that caused IP addresses of clients to be misinterpreted if there are multiple addresses from chained proxies.
161
+ * Now stripping port numbers from IP's which we weren't doing before.
162
+ * Added check for validity of IP's and report fatal error if it fails because this could lock users out.
163
+ * Improved error reporting including fixing an out of memory error when a specific error condition arose in wfConfig::set()
164
+ * Changed order of tmp dirs to be wordfence/lib protected dir first and then system temp dir. Added uploads as tmp dir for last resort.
165
+ * Malware URL's are now marked in red in alerts so it's obvious what the offending URL in a file is.
166
+
167
+ = 2.1.3 =
168
  * Added fix for hosts that have max_allowed_packet set too small. We will write a temp file to disk instead if possible.
169
  * Increased size of status column to 1000 chars
170
 
visitor.php CHANGED
@@ -1,4 +1,5 @@
1
  <?php
 
2
  ignore_user_abort(true);
3
  if ( !defined('ABSPATH') ) {
4
  /** Set up WordPress environment */
@@ -15,6 +16,7 @@ if ( !defined('ABSPATH') ) {
15
  }
16
 
17
  }
 
18
  require_once('lib/wfUtils.php');
19
  require_once('lib/wfDB.php');
20
  function wfVisitor(){
1
  <?php
2
+ define('WORDFENCE_VERSIONONLY_MODE', true); //So that we can include wordfence.php and get the version constant
3
  ignore_user_abort(true);
4
  if ( !defined('ABSPATH') ) {
5
  /** Set up WordPress environment */
16
  }
17
 
18
  }
19
+ require_once('wordfence.php');
20
  require_once('lib/wfUtils.php');
21
  require_once('lib/wfDB.php');
22
  function wfVisitor(){
wfscan.php CHANGED
@@ -1,6 +1,6 @@
1
  <?php
2
  /* Don't remove this line. WFSOURCEVISIBLE */
3
- define('WORDFENCE_SCAN_MODE', true); //So that we can include wordfence.php and get the version constant
4
  ignore_user_abort(true);
5
  $wordfence_wp_version = false;
6
  if ( !defined('ABSPATH') ) {
1
  <?php
2
  /* Don't remove this line. WFSOURCEVISIBLE */
3
+ define('WORDFENCE_VERSIONONLY_MODE', true); //So that we can include wordfence.php and get the version constant
4
  ignore_user_abort(true);
5
  $wordfence_wp_version = false;
6
  if ( !defined('ABSPATH') ) {
wordfence.php CHANGED
@@ -4,12 +4,11 @@ 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: 2.1.3
8
  Author URI: http://wordfence.com/
9
  */
10
- define('WORDFENCE_VERSION', '2.1.3');
11
-
12
- if(! defined('WORDFENCE_SCAN_MODE')){
13
  require_once('lib/wordfenceConstants.php');
14
  require_once('lib/wordfenceClass.php');
15
  register_activation_hook(WP_PLUGIN_DIR . '/wordfence/wordfence.php', 'wordfence::installPlugin');
4
  Plugin URI: http://wordfence.com/
5
  Description: Wordfence Security - Anti-virus and Firewall security plugin for WordPress
6
  Author: Mark Maunder
7
+ Version: 2.1.4
8
  Author URI: http://wordfence.com/
9
  */
10
+ define('WORDFENCE_VERSION', '2.1.4');
11
+ if(! defined('WORDFENCE_VERSIONONLY_MODE')){
 
12
  require_once('lib/wordfenceConstants.php');
13
  require_once('lib/wordfenceClass.php');
14
  register_activation_hook(WP_PLUGIN_DIR . '/wordfence/wordfence.php', 'wordfence::installPlugin');