Wordfence Security – Firewall & Malware Scan - Version 3.1.4

Version Description

  • Fixed SQL error in code that checks if IP blockedTime has expired. Changed column type to signed.
  • Added detection of malicious injected titles with scripts or meta redirects.
  • Fixed bug introduced in previous release that prevents blocked IP's from being blocked.
Download this release

Release Info

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

Code changes from version 3.1.2 to 3.1.4

lib/menu_scan.php CHANGED
@@ -337,6 +337,48 @@
337
</div>
338
</div>
339
</script>
340
341
<script type="text/x-jquery-template" id="issueTmpl_postBadURL">
342
<div>
337
</div>
338
</div>
339
</script>
340
+ <script type="text/x-jquery-template" id="issueTmpl_postBadTitle">
341
+ <div>
342
+ <div class="wfIssue">
343
+ <h2>${shortMsg}</h2>
344
+ <p>
345
+ <table border="0" class="wfIssue" cellspacing="0" cellpadding="0">
346
+ <tr><th>Title:</th><td><strong class="wfWarn">${data.postTitle}</strong></td></tr>
347
+ <tr><th>Posted on:</th><td>${data.postDate}</td></tr>
348
+ {{if data.isMultisite}}
349
+ <tr><th>Multisite Blog ID:</th><td>${data.blog_id}</td></tr>
350
+ <tr><th>Multisite Blog Domain:</th><td>${data.domain}</td></tr>
351
+ <tr><th>Multisite Blog Path:</th><td>${data.path}</td></tr>
352
+ {{/if}}
353
+ <tr><th>Severity:</th><td>Critical</td></tr>
354
+ <tr><th>Status</th><td>
355
+ {{if status == 'new' }}New{{/if}}
356
+ {{if status == 'ignoreC' }}This bad title will be ignored in this ${data.type}.{{/if}}
357
+ {{if status == 'ignoreP' }}This post won't be scanned for bad titles.{{/if}}
358
+ </td></tr>
359
+ </table>
360
+ </p>
361
+ <p>
362
+ {{html longMsg}}
363
+ </p>
364
+ <div class="wfIssueOptions">
365
+ <strong>Tools:</strong>
366
+ <a target="_blank" href="${data.editPostLink}">Edit this ${data.type}</a>
367
+ </div>
368
+ <div class="wfIssueOptions">
369
+ {{if status == 'new'}}
370
+ <strong>Resolve:</strong>
371
+ <a href="#" onclick="WFAD.updateIssueStatus('${id}', 'delete'); return false;">I have fixed this issue</a>
372
+ <a href="#" onclick="WFAD.updateIssueStatus('${id}', 'ignoreC'); return false;">Ignore this title in this ${data.type}</a>
373
+ <a href="#" onclick="WFAD.updateIssueStatus('${id}', 'ignoreP'); return false;">Ignore all dangerous titles in this ${data.type}</a>
374
+ {{/if}}
375
+ {{if status == 'ignoreP' || status == 'ignoreC'}}
376
+ <a href="#" onclick="WFAD.updateIssueStatus('${id}', 'delete'); return false;">Stop ignoring this issue</a>
377
+ {{/if}}
378
+ </div>
379
+ </div>
380
+ </div>
381
+ </script>
382
383
<script type="text/x-jquery-template" id="issueTmpl_postBadURL">
384
<div>
lib/wfLog.php CHANGED
@@ -516,7 +516,7 @@ class wfLog {
516
}
517
518
$IP = wfUtils::inet_aton(wfUtils::getIP());
519
- 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'))){
520
$this->getDB()->query("update " . $this->blocksTable . " set lastAttempt=unix_timestamp(), blockedHits = blockedHits + 1 where IP=%s", $IP);
521
$now = $this->getDB()->querySingle("select unix_timestamp()");
522
$secsToGo = ($rec['blockedTime'] + wfConfig::get('blockedTime')) - $now;
516
}
517
518
$IP = wfUtils::inet_aton(wfUtils::getIP());
519
+ if($rec = $this->getDB()->querySingleRec("select blockedTime, reason from " . $this->blocksTable . " where IP=%s and (permanent=1 OR (blockedTime + %s > unix_timestamp()))", $IP, wfConfig::get('blockedTime'))){
520
$this->getDB()->query("update " . $this->blocksTable . " set lastAttempt=unix_timestamp(), blockedHits = blockedHits + 1 where IP=%s", $IP);
521
$now = $this->getDB()->querySingle("select unix_timestamp()");
522
$secsToGo = ($rec['blockedTime'] + wfConfig::get('blockedTime')) - $now;
lib/wfScanEngine.php CHANGED
@@ -336,6 +336,23 @@ class wfScanEngine {
336
$postID = $elem[1];
337
$row = $wfdb->querySingleRec("select ID, post_title, post_type, post_date, post_content from " . $blog['table'] . " where ID=%d", $postID);
338
$this->hoover->hoover($blog['blog_id'] . '-' . $row['ID'], $row['post_title'] . ' ' . $row['post_content']);
339
$this->scanData[$blog['blog_id'] . '-' . $row['ID']] = array(
340
'contentMD5' => md5($row['post_content']),
341
'title' => $row['post_title'],
336
$postID = $elem[1];
337
$row = $wfdb->querySingleRec("select ID, post_title, post_type, post_date, post_content from " . $blog['table'] . " where ID=%d", $postID);
338
$this->hoover->hoover($blog['blog_id'] . '-' . $row['ID'], $row['post_title'] . ' ' . $row['post_content']);
339
+ if(preg_match('/(?:<[\s\n\r\t]*script[\r\s\n\t]+.*>|<[\s\n\r\t]*meta.*refresh)/i', $row['post_title'])){
340
+ $postID = $row['ID'];
341
+ $this->addIssue('postBadTitle', 1, $row['ID'], md5($row['post_title']), "Post title contains suspicious code", "This post contains code that is suspicious. Please check the title of the post and confirm that the code in the title is not malicious.", array(
342
+ 'postID' => $postID,
343
+ 'postTitle' => $row['post_title'],
344
+ 'permalink' => get_permalink($postID),
345
+ 'editPostLink' => get_edit_post_link($postID),
346
+ 'type' => $row['post_type'],
347
+ 'postDate' => $row['post_date'],
348
+ 'isMultisite' => $blog['isMultisite'],
349
+ 'domain' => $blog['domain'],
350
+ 'path' => $blog['path'],
351
+ 'blog_id' => $blog['blog_id']
352
+ ));
353
+ }
354
+
355
+
356
$this->scanData[$blog['blog_id'] . '-' . $row['ID']] = array(
357
'contentMD5' => md5($row['post_content']),
358
'title' => $row['post_title'],
lib/wfUtils.php CHANGED
@@ -392,7 +392,7 @@ class wfUtils {
392
@ini_set('display_errors', self::$lastDisplayErrors);
393
if(class_exists('wfScan')){ wfScan::$errorHandlingOn = true; }
394
}
395
- public static function fileTooBig($file){
396
wfUtils::errorsOff();
397
$fh = @fopen($file, 'r');
398
wfUtils::errorsOn();
392
@ini_set('display_errors', self::$lastDisplayErrors);
393
if(class_exists('wfScan')){ wfScan::$errorHandlingOn = true; }
394
}
395
+ public static function fileTooBig($file){ //Deals with files > 2 gigs on 32 bit systems which are reported with the wrong size due to integer overflow
396
wfUtils::errorsOff();
397
$fh = @fopen($file, 'r');
398
wfUtils::errorsOn();
lib/wordfenceClass.php CHANGED
@@ -223,6 +223,8 @@ class wordfence {
223
$db->queryIgnoreError("alter table $prefix"."wfConfig modify column val longblob");
224
$db->queryIgnoreError("alter table $prefix"."wfBlocks add column permanent tinyint UNSIGNED default 0");
225
$db->queryIgnoreError("alter table $prefix"."wfStatus modify column msg varchar(1000) NOT NULL");
226
227
//Must be the final line
228
}
223
$db->queryIgnoreError("alter table $prefix"."wfConfig modify column val longblob");
224
$db->queryIgnoreError("alter table $prefix"."wfBlocks add column permanent tinyint UNSIGNED default 0");
225
$db->queryIgnoreError("alter table $prefix"."wfStatus modify column msg varchar(1000) NOT NULL");
226
+ //3.1.2 to 3.1.4
227
+ $db->queryIgnoreError("alter table $prefix"."wfBlocks modify column blockedTime bigint signed NOT NULL");
228
229
//Must be the final line
230
}
lib/wordfenceScanner.php CHANGED
@@ -64,7 +64,7 @@ class wordfenceScanner {
64
if(preg_match('/^(?:jpg|jpeg|mp3|avi|m4v|gif|png)#x2F;', $fileExt)){
65
continue;
66
}
67
- if(wfUtils::fileTooBig($this->path . $file)){
68
//We should not need this check because files > 2 gigs are not hashed and therefore won't be received back as unknowns from the API server
69
//But we do it anyway to be safe.
70
wordfence::status(2, 'error', "Encountered file that is too large: $file - Skipping.");
64
if(preg_match('/^(?:jpg|jpeg|mp3|avi|m4v|gif|png)#x2F;', $fileExt)){
65
continue;
66
}
67
+ if(wfUtils::fileTooBig($this->path . $file)){ //We can't use filesize on 32 bit systems for files > 2 gigs
68
//We should not need this check because files > 2 gigs are not hashed and therefore won't be received back as unknowns from the API server
69
//But we do it anyway to be safe.
70
wordfence::status(2, 'error', "Encountered file that is too large: $file - Skipping.");
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.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,6 +152,11 @@ 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.2 =
156
* Fixed permanent IP blocking bug which caused permanently blocked IP's to no longer display in the list after some time, even though there were still blocked. (Incorrect SQL query)
157
* Fixed "Can't get admin ID" on scan starts for both MU and single site installs.
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.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
+ = 3.1.4 =
156
+ * Fixed SQL error in code that checks if IP blockedTime has expired. Changed column type to signed.
157
+ * Added detection of malicious injected titles with scripts or meta redirects.
158
+ * Fixed bug introduced in previous release that prevents blocked IP's from being blocked.
159
+
160
= 3.1.2 =
161
* Fixed permanent IP blocking bug which caused permanently blocked IP's to no longer display in the list after some time, even though there were still blocked. (Incorrect SQL query)
162
* Fixed "Can't get admin ID" on scan starts for both MU and single site installs.
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.2
8
Author URI: http://wordfence.com/
9
*/
10
- define('WORDFENCE_VERSION', '3.1.2');
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.4
8
Author URI: http://wordfence.com/
9
*/
10
+ define('WORDFENCE_VERSION', '3.1.4');
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.