Wordfence Security – Firewall & Malware Scan - Version 3.0.5

Version Description

  • Fixed "The key used to start a scan has expired." error and added data to help diagnose future issues like this.
  • Removed HTTPHeaders from wfHits table which was using a lot of disk space and not used much.
  • Removed limiting wfHits table size because it was unreliable.
  • We're now limiting wfHits to 20,000 rows and the rows are much smaller. About 2 to 8 megs.
  • Fixed bug that could have caused install routine to run repeatedly.
  • Fixed typo bug in blocking code that didn't have any impact but was sloppy.
  • Changed wfscan.php message when accessed directly to be more helpful.
Download this release

Release Info

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

Code changes from version 3.0.4 to 3.0.5

lib/IPTraf.php CHANGED
@@ -22,14 +22,6 @@
22
<?php echo $v['loc']['countryName']; ?>
23
</td></tr>
24
<?php } ?>
25
- <tr><th>HTTP Headers:</th><td>
26
- <table border="0" class="HTTP">
27
- <?php foreach($v['HTTPHeaders'] as $key => $val){
28
- echo "<tr><th class=\"HTTP\">$key</th><td class=\"HTTP\">"."$val</td></tr>";
29
- }
30
- ?>
31
- </table>
32
- </td></tr>
33
<tr><td colspan="2"><hr></td></tr>
34
<?php } ?>
35
22
<?php echo $v['loc']['countryName']; ?>
23
</td></tr>
24
<?php } ?>
25
<tr><td colspan="2"><hr></td></tr>
26
<?php } ?>
27
lib/menu_options.php CHANGED
@@ -62,7 +62,6 @@ var WFSLevels = <?php echo json_encode(wfConfig::$securityLevels); ?>;
62
<tr><th>List of comma separated usernames to ignore:</th><td><input type="text" name="liveTraf_ignoreUsers" id="liveTraf_ignoreUsers" value="<?php echo $w->getHTML('liveTraf_ignoreUsers'); ?>" /></td></tr>
63
<tr><th>List of comma separated IP addresses to ignore:</th><td><input type="text" name="liveTraf_ignoreIPs" id="liveTraf_ignoreIPs" value="<?php echo $w->getHTML('liveTraf_ignoreIPs'); ?>" /></td></tr>
64
<tr><th>Browser user-agent to ignore:</th><td><input type="text" name="liveTraf_ignoreUA" id="liveTraf_ignoreUA" value="<?php echo $w->getHTML('liveTraf_ignoreUA'); ?>" /></td></tr>
65
- <tr><th>Limit size of hits table to</th><td><input type="text" name="liveTraf_hitsMaxSize" class="wfConfigElem" name="liveTraf_hitsMaxSize" value="<?php $w->f('liveTraf_hitsMaxSize'); ?>" size="6" />Megabytes</td></tr>
66
<tr><td colspan="2"><h3 class="wfConfigHeading">Scans to include</h3></td></tr>
67
<tr><th class="wfConfigEnable">Enable automatic scheduled scans</th><td><input type="checkbox" id="scheduledScansEnabled" class="wfConfigElem" name="scheduledScansEnabled" value="1" <?php $w->cb('scheduledScansEnabled'); ?> /></td></tr>
68
<tr><th>Scan core files against repository versions for changes</th><td><input type="checkbox" id="scansEnabled_core" class="wfConfigElem" name="scansEnabled_core" value="1" <?php $w->cb('scansEnabled_core'); ?>/></td></tr>
62
<tr><th>List of comma separated usernames to ignore:</th><td><input type="text" name="liveTraf_ignoreUsers" id="liveTraf_ignoreUsers" value="<?php echo $w->getHTML('liveTraf_ignoreUsers'); ?>" /></td></tr>
63
<tr><th>List of comma separated IP addresses to ignore:</th><td><input type="text" name="liveTraf_ignoreIPs" id="liveTraf_ignoreIPs" value="<?php echo $w->getHTML('liveTraf_ignoreIPs'); ?>" /></td></tr>
64
<tr><th>Browser user-agent to ignore:</th><td><input type="text" name="liveTraf_ignoreUA" id="liveTraf_ignoreUA" value="<?php echo $w->getHTML('liveTraf_ignoreUA'); ?>" /></td></tr>
65
<tr><td colspan="2"><h3 class="wfConfigHeading">Scans to include</h3></td></tr>
66
<tr><th class="wfConfigEnable">Enable automatic scheduled scans</th><td><input type="checkbox" id="scheduledScansEnabled" class="wfConfigElem" name="scheduledScansEnabled" value="1" <?php $w->cb('scheduledScansEnabled'); ?> /></td></tr>
67
<tr><th>Scan core files against repository versions for changes</th><td><input type="checkbox" id="scansEnabled_core" class="wfConfigElem" name="scansEnabled_core" value="1" <?php $w->cb('scansEnabled_core'); ?>/></td></tr>
lib/wfConfig.php CHANGED
@@ -48,7 +48,6 @@ class wfConfig {
48
"otherParams" => array(
49
'securityLevel' => '0',
50
"alertEmails" => "", "liveTraf_ignoreUsers" => "", "liveTraf_ignoreIPs" => "", "liveTraf_ignoreUA" => "", "apiKey" => "", "maxMem" => '256', 'whitelisted' => '',
51
- "liveTraf_hitsMaxSize" => 10,
52
"neverBlockBG" => "neverBlockVerified",
53
"loginSec_countFailMins" => "5",
54
"loginSec_lockoutMins" => "5",
@@ -111,7 +110,6 @@ class wfConfig {
111
"otherParams" => array(
112
'securityLevel' => '1',
113
"alertEmails" => "", "liveTraf_ignoreUsers" => "", "liveTraf_ignoreIPs" => "", "liveTraf_ignoreUA" => "", "apiKey" => "", "maxMem" => '256', 'whitelisted' => '',
114
- "liveTraf_hitsMaxSize" => 10,
115
"neverBlockBG" => "neverBlockVerified",
116
"loginSec_countFailMins" => "5",
117
"loginSec_lockoutMins" => "5",
@@ -174,7 +172,6 @@ class wfConfig {
174
"otherParams" => array(
175
'securityLevel' => '2',
176
"alertEmails" => "", "liveTraf_ignoreUsers" => "", "liveTraf_ignoreIPs" => "", "liveTraf_ignoreUA" => "", "apiKey" => "", "maxMem" => '256', 'whitelisted' => '',
177
- "liveTraf_hitsMaxSize" => 10,
178
"neverBlockBG" => "neverBlockVerified",
179
"loginSec_countFailMins" => "240",
180
"loginSec_lockoutMins" => "240",
@@ -237,7 +234,6 @@ class wfConfig {
237
"otherParams" => array(
238
'securityLevel' => '3',
239
"alertEmails" => "", "liveTraf_ignoreUsers" => "", "liveTraf_ignoreIPs" => "", "liveTraf_ignoreUA" => "", "apiKey" => "", "maxMem" => '256', 'whitelisted' => '',
240
- "liveTraf_hitsMaxSize" => 10,
241
"neverBlockBG" => "neverBlockVerified",
242
"loginSec_countFailMins" => "1440",
243
"loginSec_lockoutMins" => "1440",
@@ -300,7 +296,6 @@ class wfConfig {
300
"otherParams" => array(
301
'securityLevel' => '4',
302
"alertEmails" => "", "liveTraf_ignoreUsers" => "", "liveTraf_ignoreIPs" => "", "liveTraf_ignoreUA" => "", "apiKey" => "", "maxMem" => '256', 'whitelisted' => '',
303
- "liveTraf_hitsMaxSize" => 10,
304
"neverBlockBG" => "neverBlockVerified",
305
"loginSec_countFailMins" => "1440",
306
"loginSec_lockoutMins" => "1440",
48
"otherParams" => array(
49
'securityLevel' => '0',
50
"alertEmails" => "", "liveTraf_ignoreUsers" => "", "liveTraf_ignoreIPs" => "", "liveTraf_ignoreUA" => "", "apiKey" => "", "maxMem" => '256', 'whitelisted' => '',
51
"neverBlockBG" => "neverBlockVerified",
52
"loginSec_countFailMins" => "5",
53
"loginSec_lockoutMins" => "5",
110
"otherParams" => array(
111
'securityLevel' => '1',
112
"alertEmails" => "", "liveTraf_ignoreUsers" => "", "liveTraf_ignoreIPs" => "", "liveTraf_ignoreUA" => "", "apiKey" => "", "maxMem" => '256', 'whitelisted' => '',
113
"neverBlockBG" => "neverBlockVerified",
114
"loginSec_countFailMins" => "5",
115
"loginSec_lockoutMins" => "5",
172
"otherParams" => array(
173
'securityLevel' => '2',
174
"alertEmails" => "", "liveTraf_ignoreUsers" => "", "liveTraf_ignoreIPs" => "", "liveTraf_ignoreUA" => "", "apiKey" => "", "maxMem" => '256', 'whitelisted' => '',
175
"neverBlockBG" => "neverBlockVerified",
176
"loginSec_countFailMins" => "240",
177
"loginSec_lockoutMins" => "240",
234
"otherParams" => array(
235
'securityLevel' => '3',
236
"alertEmails" => "", "liveTraf_ignoreUsers" => "", "liveTraf_ignoreIPs" => "", "liveTraf_ignoreUA" => "", "apiKey" => "", "maxMem" => '256', 'whitelisted' => '',
237
"neverBlockBG" => "neverBlockVerified",
238
"loginSec_countFailMins" => "1440",
239
"loginSec_lockoutMins" => "1440",
296
"otherParams" => array(
297
'securityLevel' => '4',
298
"alertEmails" => "", "liveTraf_ignoreUsers" => "", "liveTraf_ignoreIPs" => "", "liveTraf_ignoreUA" => "", "apiKey" => "", "maxMem" => '256', 'whitelisted' => '',
299
"neverBlockBG" => "neverBlockVerified",
300
"loginSec_countFailMins" => "1440",
301
"loginSec_lockoutMins" => "1440",
lib/wfDB.php CHANGED
@@ -155,6 +155,22 @@ class wfDB {
155
error_log($msg);
156
return;
157
}
158
public function createKeyIfNotExists($table, $col, $keyName){
159
global $wpdb; $prefix = $wpdb->base_prefix;
160
$table = $prefix . $table;
155
error_log($msg);
156
return;
157
}
158
+ public function columnExists($table, $col){
159
+ global $wpdb; $prefix = $wpdb->base_prefix;
160
+ $table = $prefix . $table;
161
+ $q = $this->query("desc $table");
162
+ while($row = mysql_fetch_assoc($q)){
163
+ if($row['Field'] == $col){
164
+ return true;
165
+ }
166
+ }
167
+ return false;
168
+ }
169
+ public function dropColumn($table, $col){
170
+ global $wpdb; $prefix = $wpdb->base_prefix;
171
+ $table = $prefix . $table;
172
+ $this->query("alter table $table drop column $col");
173
+ }
174
public function createKeyIfNotExists($table, $col, $keyName){
175
global $wpdb; $prefix = $wpdb->base_prefix;
176
$table = $prefix . $table;
lib/wfLog.php CHANGED
@@ -280,7 +280,7 @@ class wfLog {
280
$headers[$matches[1]] = $v;
281
}
282
}
283
- $this->getDB()->query("insert into " . $this->hitsTable . " (ctime, is404, isGoogle, IP, userID, newVisit, URL, referer, UA, HTTPHeaders) values (%f, %d, %d, %s, %s, %d, '%s', '%s', '%s', '%s')",
284
sprintf('%.6f', microtime(true)),
285
(is_404() ? 1 : 0),
286
(wfCrawl::isGoogleCrawler() ? 1 : 0),
@@ -289,8 +289,7 @@ class wfLog {
289
(wordfence::$newVisit ? 1 : 0),
290
wfUtils::getRequestedURL(),
291
(isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : ''),
292
- (isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : ''),
293
- serialize($headers)
294
);
295
return $this->getDB()->querySingle("select last_insert_id()");
296
}
@@ -345,9 +344,6 @@ class wfLog {
345
$browscap = new wfBrowscap();
346
foreach($results as &$res){
347
$res['type'] = $type;
348
- if(isset($res['HTTPHeaders'])){
349
- $res['HTTPHeaders'] = unserialize($res['HTTPHeaders']);
350
- }
351
$res['timeAgo'] = wfUtils::makeTimeAgo($serverTime - $res['ctime']);
352
$res['blocked'] = $this->getDB()->querySingle("select blockedTime from " . $this->blocksTable . " where IP=%s and blockedTime + %s > unix_timestamp()", $res['IP'], wfConfig::get('blockedTime'));
353
$res['IP'] = wfUtils::inet_ntoa($res['IP']);
@@ -476,10 +472,8 @@ class wfLog {
476
public function firewallBadIPs(){
477
$IP = wfUtils::inet_aton(wfUtils::getIP());
478
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'))){
479
- $secsToGo = $rec['secsToGo'];
480
- $reason = $rec[1];
481
$this->getDB()->query("update " . $this->blocksTable . " set lastAttempt=unix_timestamp(), blockedHits = blockedHits + 1 where IP=%s", $IP);
482
- $this->do503($secsToGo, $rec['reason']);
483
}
484
}
485
private function takeBlockingAction($configVar, $reason){
280
$headers[$matches[1]] = $v;
281
}
282
}
283
+ $this->getDB()->query("insert into " . $this->hitsTable . " (ctime, is404, isGoogle, IP, userID, newVisit, URL, referer, UA) values (%f, %d, %d, %s, %s, %d, '%s', '%s', '%s')",
284
sprintf('%.6f', microtime(true)),
285
(is_404() ? 1 : 0),
286
(wfCrawl::isGoogleCrawler() ? 1 : 0),
289
(wordfence::$newVisit ? 1 : 0),
290
wfUtils::getRequestedURL(),
291
(isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : ''),
292
+ (isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : '')
293
);
294
return $this->getDB()->querySingle("select last_insert_id()");
295
}
344
$browscap = new wfBrowscap();
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']);
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){
lib/wfSchema.php CHANGED
@@ -52,7 +52,6 @@ class wfSchema {
52
URL text,
53
referer text,
54
UA text,
55
- HTTPHeaders text,
56
KEY k1(ctime),
57
KEY k2(IP, ctime)
58
) default charset=latin1",
52
URL text,
53
referer text,
54
UA text,
55
KEY k1(ctime),
56
KEY k2(IP, ctime)
57
) default charset=latin1",
lib/wordfenceClass.php CHANGED
@@ -116,25 +116,10 @@ class wordfence {
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
- if(wfConfig::get('liveTraf_hitsMaxSize') && wfConfig::get('liveTraf_hitsMaxSize') > 0){
120
- $gotTableSize = false;
121
- $tableSizeQ = $wfdb->query("show table status like '$p"."wfHits'");
122
- if($tableSizeQ){
123
- $tableSizeRec = mysql_fetch_assoc($tableSizeQ);
124
- if($tableSizeRec && isset($tableSizeRec['Data_length']) && $tableSizeRec['Data_length'] > 0){
125
- $gotTableSize = true;
126
- if($tableSizeRec['Data_length'] > (wfConfig::get('liveTraf_hitsMaxSize') * 1024 * 1024) ){ //convert to bytes
127
- $count = $wfdb->querySingle("select count(*) as cnt from $p"."wfHits");
128
- $wfdb->query("delete from $p"."wfHits order by id asc limit %d", floor($count / 10)); //Delete 10% of rows. If we're still bigger than max, then next delete will reduce by further 10% and so on.
129
- }
130
- }
131
- } else {
132
- error_log("Wordfence could not get wfHits table data size for cleanup. Query returned false.");
133
- }
134
}
135
-
136
-
137
-
138
$maxRows = 1000; //affects stuff further down too
139
foreach(array('wfLeechers', 'wfScanners') as $table){
140
//This is time based per IP so shouldn't get too big
@@ -167,6 +152,7 @@ class wordfence {
167
168
}
169
public static function runInstall(){
170
//EVERYTHING HERE MUST BE IDEMPOTENT
171
$schema = new wfSchema();
172
$schema->createAll(); //if not exists
@@ -192,6 +178,16 @@ class wordfence {
192
wp_schedule_event(time(), 'hourly', 'wordfence_hourly_cron');
193
$db = new wfDB();
194
195
//Upgrading from 1.5.6 or earlier needs:
196
$db->createKeyIfNotExists('wfStatus', 'level', 'k2');
197
if(wfConfig::get('isPaid') == 'free'){
@@ -214,7 +210,6 @@ class wordfence {
214
$db->queryIgnoreError("alter table $prefix"."wfStatus modify column msg varchar(1000) NOT NULL");
215
216
//Must be the final line
217
- update_option('wordfence_version', WORDFENCE_VERSION);
218
}
219
public static function install_actions(){
220
$versionInOptions = get_option('wordfence_version', false);
@@ -240,9 +235,7 @@ class wordfence {
240
add_action('wp_logout','wordfence::logoutAction');
241
add_action('profile_update', 'wordfence::profileUpdateAction', '99', 2);
242
add_action('lostpassword_post', 'wordfence::lostPasswordPost', '1');
243
- /* For testing cron jobs
244
- add_filter('cron_schedules', 'wordfence::moreCronReccurences');
245
- */
246
add_filter('pre_comment_approved', 'wordfence::preCommentApprovedFilter', '99', 2);
247
add_filter('authenticate', 'wordfence::authenticateFilter', 99, 3);
248
//html|xhtml|atom|rss2|rdf|comment|export
@@ -1342,10 +1335,10 @@ class wordfence {
1342
}
1343
return self::$debugOn;
1344
}
1345
- /* For testing cron jobs
1346
public static function moreCronReccurences(){
1347
return array(
1348
- Feveryminute' => array('interval' => 60, 'display' => 'Once Every Minute'),
1349
);
1350
}
1351
*/
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");
120
+ if($count > 20000){
121
+ $wfdb->query("delete from $p"."wfHits order by id asc limit " . ($count - 20000));
122
}
123
$maxRows = 1000; //affects stuff further down too
124
foreach(array('wfLeechers', 'wfScanners') as $table){
125
//This is time based per IP so shouldn't get too big
152
153
}
154
public static function runInstall(){
155
+ update_option('wordfence_version', WORDFENCE_VERSION); //In case we have a fatal error we don't want to keep running install.
156
//EVERYTHING HERE MUST BE IDEMPOTENT
157
$schema = new wfSchema();
158
$schema->createAll(); //if not exists
178
wp_schedule_event(time(), 'hourly', 'wordfence_hourly_cron');
179
$db = new wfDB();
180
181
+ if($db->columnExists('wfHits', 'HTTPHeaders')){ //Upgrade from 3.0.4
182
+ global $wpdb;
183
+ $prefix = $wpdb->base_prefix;
184
+ $count = $db->querySingle("select count(*) as cnt from $prefix"."wfHits");
185
+ if($count > 20000){
186
+ $db->query("delete from $prefix"."wfHits order by id asc limit " . ($count - 20000));
187
+ }
188
+ $db->dropColumn('wfHits', 'HTTPHeaders');
189
+ }
190
+
191
//Upgrading from 1.5.6 or earlier needs:
192
$db->createKeyIfNotExists('wfStatus', 'level', 'k2');
193
if(wfConfig::get('isPaid') == 'free'){
210
$db->queryIgnoreError("alter table $prefix"."wfStatus modify column msg varchar(1000) NOT NULL");
211
212
//Must be the final line
213
}
214
public static function install_actions(){
215
$versionInOptions = get_option('wordfence_version', false);
235
add_action('wp_logout','wordfence::logoutAction');
236
add_action('profile_update', 'wordfence::profileUpdateAction', '99', 2);
237
add_action('lostpassword_post', 'wordfence::lostPasswordPost', '1');
238
+ //add_filter('cron_schedules', 'wordfence::moreCronReccurences');
239
add_filter('pre_comment_approved', 'wordfence::preCommentApprovedFilter', '99', 2);
240
add_filter('authenticate', 'wordfence::authenticateFilter', 99, 3);
241
//html|xhtml|atom|rss2|rdf|comment|export
1335
}
1336
return self::$debugOn;
1337
}
1338
+ /*
1339
public static function moreCronReccurences(){
1340
return array(
1341
+ 'everyminute' => array('interval' => 60, 'display' => 'Once Every Minute'),
1342
);
1343
}
1344
*/
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.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,6 +152,15 @@ 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.4 =
156
* Detects if the Wordfence app (not scanner) is short on memory and requests more
157
* Fixes an issue where scan breaks if all scanning options are disabled
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.5
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.5 =
156
+ * Fixed "The key used to start a scan has expired." error and added data to help diagnose future issues like this.
157
+ * Removed HTTPHeaders from wfHits table which was using a lot of disk space and not used much.
158
+ * Removed limiting wfHits table size because it was unreliable.
159
+ * We're now limiting wfHits to 20,000 rows and the rows are much smaller. About 2 to 8 megs.
160
+ * Fixed bug that could have caused install routine to run repeatedly.
161
+ * Fixed typo bug in blocking code that didn't have any impact but was sloppy.
162
+ * Changed wfscan.php message when accessed directly to be more helpful.
163
+
164
= 3.0.4 =
165
* Detects if the Wordfence app (not scanner) is short on memory and requests more
166
* Fixes an issue where scan breaks if all scanning options are disabled
wfscan.php CHANGED
@@ -47,7 +47,9 @@ class wfScan {
47
wordfence::status(4, 'info', "Scan engine received request.");
48
wordfence::status(4, 'info', "Checking cronkey header");
49
if(! $_SERVER['HTTP_X_WORDFENCE_CRONKEY']){
50
- self::errorExit("The Wordfence scanner did not receive the x_wordfence_cronkey secure header.");
51
}
52
wordfence::status(4, 'info', "Fetching stored cronkey for comparison.");
53
$currentCronKey = wfConfig::get('currentCronKey', false);
@@ -57,8 +59,8 @@ class wfScan {
57
58
wordfence::status(4, 'info', "Exploding stored cronkey");
59
$savedKey = explode(',',$currentCronKey);
60
- if(time() - $savedKey[0] > 60){
61
- self::errorExit("The key used to start a scan has expired.");
62
} //keys only last 60 seconds and are used within milliseconds of creation
63
wordfence::status(4, 'info', "Checking saved cronkey against cronkey header");
64
if($savedKey[1] != $_SERVER['HTTP_X_WORDFENCE_CRONKEY']){
47
wordfence::status(4, 'info', "Scan engine received request.");
48
wordfence::status(4, 'info', "Checking cronkey header");
49
if(! $_SERVER['HTTP_X_WORDFENCE_CRONKEY']){
50
+ wordfence::status(2, 'error', "Wordfence wfscan.php accessed directly, or WF did not receive the secure HTTP header.");
51
+ echo "If you see this message it means Wordfence is working correctly. You should not access this URL directly. It is part of the Wordfence security plugin and is designed for internal use only.";
52
+ exit();
53
}
54
wordfence::status(4, 'info', "Fetching stored cronkey for comparison.");
55
$currentCronKey = wfConfig::get('currentCronKey', false);
59
60
wordfence::status(4, 'info', "Exploding stored cronkey");
61
$savedKey = explode(',',$currentCronKey);
62
+ if(time() - $savedKey[0] > 86400){
63
+ self::errorExit("The key used to start a scan expired. The value is: " . $savedKey[0] . " and split is: " . $currentCronKey . " and time is: " . time());
64
} //keys only last 60 seconds and are used within milliseconds of creation
65
wordfence::status(4, 'info', "Checking saved cronkey against cronkey header");
66
if($savedKey[1] != $_SERVER['HTTP_X_WORDFENCE_CRONKEY']){
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.4
8
Author URI: http://wordfence.com/
9
*/
10
- define('WORDFENCE_VERSION', '3.0.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.
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.5
8
Author URI: http://wordfence.com/
9
*/
10
+ define('WORDFENCE_VERSION', '3.0.5');
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.