Wordfence Security – Firewall & Malware Scan - Version 5.0.7

Version Description

  • Feature: Immediately block IP if hacker tries any of the following usernames. (Comma separated list that you can specify on the Wordfence options page)
  • Feature: Exclude exact URL's from caching. Specifically, this allows you to exclude the home page which was not possible before.
  • Feature: Exclude browsers or partial browser matches and specific cookies from caching.
  • Fix: Fixed issue where /.. dirs would be included in certain scandir operations.
  • Fix: logHuman function was not analyzing user-agent strings correctly which would allow some crawlers that execute JS to be logged as humans.
  • Fix: Removed ob_end_clean warnings about empty buffers when a human is being logged.
  • Fix: Removed warning in lib/wfCache.php caused by unset $_SERVER['QUERY_STRING'] when we check it.
  • Fix: Fixed "logged out as ''" blank username logout messages.
  • Fix: Improved security of config cache by adding a PHP header to file that we strip. Already secure because we have a .htaccess denying access, but more is better.
  • Fix: Falcon Engine option to clear Falcon cache when a post scheduled to be published in future is published.
  • Fix: Fixed Heartbleed scans hanging.
Download this release

Release Info

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

Code changes from version 5.0.6 to 5.0.7

js/admin.js CHANGED
@@ -1264,7 +1264,8 @@ window['wordfenceAdmin'] = {
1264
var self = this;
1265
this.ajax('wordfence_saveCacheOptions', {
1266
allowHTTPSCaching: (jQuery('#wfallowHTTPSCaching').is(':checked') ? 1 : 0),
1267
- addCacheComment: (jQuery('#wfaddCacheComment').is(':checked') ? 1 : 0)
1268
}, function(res){
1269
if(res.updateErr){
1270
self.colorbox('400px', "You need to manually update your .htaccess", res.updateErr + "<br />Your option was updated but you need to change the Wordfence code in your .htaccess to the following:<br /><textarea style='width: 300px; height: 120px;'>" + jQuery('<div/>').text(res.code).html() + '</textarea>');
@@ -1582,7 +1583,9 @@ window['wordfenceAdmin'] = {
1582
patternType: patternType,
1583
pattern: pattern
1584
}, function(res){
1585
- window.location.reload(true);
1586
});
1587
},
1588
loadCacheExclusions: function(){
1264
var self = this;
1265
this.ajax('wordfence_saveCacheOptions', {
1266
allowHTTPSCaching: (jQuery('#wfallowHTTPSCaching').is(':checked') ? 1 : 0),
1267
+ addCacheComment: (jQuery('#wfaddCacheComment').is(':checked') ? 1 : 0),
1268
+ clearCacheSched: (jQuery('#wfclearCacheSched').is(':checked') ? 1 : 0)
1269
}, function(res){
1270
if(res.updateErr){
1271
self.colorbox('400px', "You need to manually update your .htaccess", res.updateErr + "<br />Your option was updated but you need to change the Wordfence code in your .htaccess to the following:<br /><textarea style='width: 300px; height: 120px;'>" + jQuery('<div/>').text(res.code).html() + '</textarea>');
1583
patternType: patternType,
1584
pattern: pattern
1585
}, function(res){
1586
+ if(res.ok){ //Otherwise errorMsg will get caught
1587
+ window.location.reload(true);
1588
+ }
1589
});
1590
},
1591
loadCacheExclusions: function(){
lib/email_genericAlert.php CHANGED
@@ -1,10 +1,25 @@
1
- This alert was generated by Wordfence on "<?php echo $blogName; ?>" at <?php echo $date; ?>
2
3
The Wordfence administrative URL for this site is: <?php echo $adminURL; ?>admin.php?page=Wordfence
4
5
<?php echo $alertMsg; ?>
6
<?php if($IPMsg){ echo "\n$IPMsg\n"; } ?>
7
8
--
9
To change your alert options for Wordfence, visit:
10
<?php echo $myOptionsURL; ?>
1
+ This email was sent from your website "<?php echo $blogName; ?>" by the Wordfence plugin at <?php echo $date; ?>
2
3
The Wordfence administrative URL for this site is: <?php echo $adminURL; ?>admin.php?page=Wordfence
4
5
<?php echo $alertMsg; ?>
6
<?php if($IPMsg){ echo "\n$IPMsg\n"; } ?>
7
8
+ <?php if(! $isPaid){ ?>
9
+ NOTE: You are using the free version of Wordfence. Upgrading to the paid version of Wordfence gives you
10
+ two factor authentication (sign-in via cellphone) and country blocking which are both effective methods to block attacks.
11
+ A Premium Wordfence license also includes remote scanning with each scan of your site which can detect
12
+ several additional website infections. Premium members can also schedule when website scans occur and
13
+ can scan more than once per day.
14
+
15
+ As a Premium member you also get access to our priority support system located at http://support.wordfence.com/ and can file
16
+ priority support tickets using our ticketing system.
17
+
18
+ Click here to sign-up for the Premium version of Wordfence now.
19
+ https://www.wordfence.com/wordfence-signup/
20
+
21
+ <?php } ?>
22
+
23
--
24
To change your alert options for Wordfence, visit:
25
<?php echo $myOptionsURL; ?>
lib/email_newIssues.php CHANGED
@@ -1,3 +1,5 @@
1
Wordfence found the following new issues on "<?php echo get_bloginfo('name', 'raw'); ?>".
2
3
Alert generated at <?php echo wfUtils::localHumanDate(); ?>
@@ -19,5 +21,20 @@ Warnings:
19
<?php } } } ?>
20
21
22
23
1
+ This email was sent from your website "<?php echo get_bloginfo('name', 'raw'); ?>" by the Wordfence plugin.
2
+
3
Wordfence found the following new issues on "<?php echo get_bloginfo('name', 'raw'); ?>".
4
5
Alert generated at <?php echo wfUtils::localHumanDate(); ?>
21
<?php } } } ?>
22
23
24
+ <?php if(! $isPaid){ ?>
25
+ NOTE: You are using the free version of Wordfence. Upgrading to the paid version of Wordfence gives you
26
+ two factor authentication (sign-in via cellphone) and country blocking which are both effective methods to block attacks.
27
+ A Premium Wordfence license also includes remote scanning with each scan of your site which can detect
28
+ several additional website infections. Premium members can also schedule when website scans occur and
29
+ can scan more than once per day.
30
+
31
+ As a Premium member you also get access to our priority support system located at http://support.wordfence.com/ and can file
32
+ priority support tickets using our ticketing system.
33
+
34
+ Click here to sign-up for the Premium version of Wordfence now.
35
+ https://www.wordfence.com/wordfence-signup/
36
+
37
+ <?php } ?>
38
+
39
40
lib/menu_options.php CHANGED
@@ -244,6 +244,7 @@ var WFSLevels = <?php echo json_encode(wfConfig::$securityLevels); ?>;
244
<tr><th>Don't let WordPress reveal valid users in login errors</th><td><input type="checkbox" id="loginSec_maskLoginErrors" class="wfConfigElem" name="loginSec_maskLoginErrors" <?php $w->cb('loginSec_maskLoginErrors'); ?> /></td></tr>
245
<tr><th>Prevent users registering 'admin' username if it doesn't exist</th><td><input type="checkbox" id="loginSec_blockAdminReg" class="wfConfigElem" name="loginSec_blockAdminReg" <?php $w->cb('loginSec_blockAdminReg'); ?> /></td></tr>
246
<tr><th>Prevent discovery of usernames through '?/author=N' scans</th><td><input type="checkbox" id="loginSec_disableAuthorScan" class="wfConfigElem" name="loginSec_disableAuthorScan" <?php $w->cb('loginSec_disableAuthorScan'); ?> /></td></tr>
247
<tr><td colspan="2">
248
<div class="wfMarker" id="wfMarkerOtherOptions"></div>
249
<h3 class="wfConfigHeading">Other Options</h3>
244
<tr><th>Don't let WordPress reveal valid users in login errors</th><td><input type="checkbox" id="loginSec_maskLoginErrors" class="wfConfigElem" name="loginSec_maskLoginErrors" <?php $w->cb('loginSec_maskLoginErrors'); ?> /></td></tr>
245
<tr><th>Prevent users registering 'admin' username if it doesn't exist</th><td><input type="checkbox" id="loginSec_blockAdminReg" class="wfConfigElem" name="loginSec_blockAdminReg" <?php $w->cb('loginSec_blockAdminReg'); ?> /></td></tr>
246
<tr><th>Prevent discovery of usernames through '?/author=N' scans</th><td><input type="checkbox" id="loginSec_disableAuthorScan" class="wfConfigElem" name="loginSec_disableAuthorScan" <?php $w->cb('loginSec_disableAuthorScan'); ?> /></td></tr>
247
+ <tr><th>Immediately block the IP of users who try to sign in as these usernames</th><td><input type="text" name="loginSec_userBlacklist" id="loginSec_userBlacklist" value="<?php echo $w->getHTML('loginSec_userBlacklist'); ?>" size="40" />&nbsp;(Comma separated. Existing users won't be blocked.)</td></tr>
248
<tr><td colspan="2">
249
<div class="wfMarker" id="wfMarkerOtherOptions"></div>
250
<h3 class="wfConfigHeading">Other Options</h3>
lib/menu_sitePerf.php CHANGED
@@ -18,6 +18,7 @@ $w = new wfConfig();
18
<table border="0">
19
<tr><td>Allow SSL (secure HTTPS pages) to be cached:</td><td><input type="checkbox" id="wfallowHTTPSCaching" value="1" <?php $w->cb('allowHTTPSCaching'); ?> />We recommend you leave this disabled unless your<br />site uses HTTPS but does not receive/send sensitive user info.</td></tr>
20
<tr><td>Add hidden debugging data to the bottom of the HTML source of cached pages:</td><td><input type="checkbox" id="wfaddCacheComment" value="1" <?php $w->cb('addCacheComment'); ?> />Message appears as an HTML comment below the closing HTML tag.</td></tr>
21
</table>
22
<br />
23
<input type="button" id="button1" name="button1" class="button-primary" value="Save Changes to the the caching options above" onclick="WFAD.saveCacheOptions();" />
@@ -32,15 +33,19 @@ $w = new wfConfig();
32
of the actions that will automatically clear the cache are:<br />
33
Publishing a post, creating a new page, updating general settings, creating a new category, updating menus, updating widgets and installing a new plugin.
34
</p>
35
- <h2>You can add URLs to exclude from caching</h2>
36
<p style="width: 500px; white-space:nowrap;">
37
- If a URL
38
<select id="wfPatternType">
39
- <option value="s">Starts with</option>
40
- <option value="e">Ends with</option>
41
- <option value="c">Contains</option>
42
</select>
43
- this text then don't cache it:
44
<input type="text" id="wfPattern" value="" size="20" maxlength="1000" />e.g. /my/dynamic/page/
45
<input type="button" class="button-primary" value="Add exclusion" onclick="WFAD.addCacheExclusion(jQuery('#wfPatternType').val(), jQuery('#wfPattern').val()); return false;" />
46
</p>
@@ -52,17 +57,29 @@ $w = new wfConfig();
52
</div>
53
<script type="text/x-jquery-template" id="wfCacheExclusionTmpl">
54
<div>
55
- If the URL
56
<strong style="color: #0A0;">
57
{{if pt == 's'}}
58
- STARTS WITH
59
{{else pt == 'e'}}
60
- ENDS WITH
61
{{else pt =='c'}}
62
- CONTAINS
63
{{/if}}
64
</strong>
65
- the text (without quotes):
66
<strong style="color: #F00;">
67
"${p}"
68
</strong>
18
<table border="0">
19
<tr><td>Allow SSL (secure HTTPS pages) to be cached:</td><td><input type="checkbox" id="wfallowHTTPSCaching" value="1" <?php $w->cb('allowHTTPSCaching'); ?> />We recommend you leave this disabled unless your<br />site uses HTTPS but does not receive/send sensitive user info.</td></tr>
20
<tr><td>Add hidden debugging data to the bottom of the HTML source of cached pages:</td><td><input type="checkbox" id="wfaddCacheComment" value="1" <?php $w->cb('addCacheComment'); ?> />Message appears as an HTML comment below the closing HTML tag.</td></tr>
21
+ <tr><td>Clear cache when a scheduled post is published</td><td><input type="checkbox" id="wfclearCacheSched" value="1" <?php $w->cb('clearCacheSched'); ?> />The entire Falcon cache will be cleared when WordPress publishes a post you've scheduled to be published in future.</td></tr>
22
</table>
23
<br />
24
<input type="button" id="button1" name="button1" class="button-primary" value="Save Changes to the the caching options above" onclick="WFAD.saveCacheOptions();" />
33
of the actions that will automatically clear the cache are:<br />
34
Publishing a post, creating a new page, updating general settings, creating a new category, updating menus, updating widgets and installing a new plugin.
35
</p>
36
+ <h2>You can add items like URLs, cookies and browsers (user-agents) to exclude from caching</h2>
37
<p style="width: 500px; white-space:nowrap;">
38
+ If a
39
<select id="wfPatternType">
40
+ <option value="s">URL Starts with</option>
41
+ <option value="e">URL Ends with</option>
42
+ <option value="c">URL Contains</option>
43
+ <option value="eq">URL Exactly Matches</option>
44
+ <option value="uac">User-Agent Contains</option>
45
+ <option value="uaeq">User-Agent Exactly Matches</option>
46
+ <option value="cc">Cookie Name Contains</option>
47
</select>
48
+ this value then don't cache it:
49
<input type="text" id="wfPattern" value="" size="20" maxlength="1000" />e.g. /my/dynamic/page/
50
<input type="button" class="button-primary" value="Add exclusion" onclick="WFAD.addCacheExclusion(jQuery('#wfPatternType').val(), jQuery('#wfPattern').val()); return false;" />
51
</p>
57
</div>
58
<script type="text/x-jquery-template" id="wfCacheExclusionTmpl">
59
<div>
60
+ If the
61
<strong style="color: #0A0;">
62
{{if pt == 's'}}
63
+ URL starts with
64
{{else pt == 'e'}}
65
+ URL ends with
66
{{else pt =='c'}}
67
+ URL contains
68
+ {{else pt == 'eq'}}
69
+ URL equals
70
+ {{else pt == 'uac'}}
71
+ User-Agent contains
72
+ {{else pt == 'uaeq'}}
73
+ User-Agent equals
74
+ {{else pt == 'cc'}}
75
+ Cookie Name contains
76
+ {{else pt == 'ceq'}}
77
+ Cookie Name equals
78
+ {{else pt == 'ipeq'}}
79
+ IP Address equals
80
{{/if}}
81
</strong>
82
+ (without quotes):
83
<strong style="color: #F00;">
84
"${p}"
85
</strong>
lib/wfCache.php CHANGED
@@ -83,7 +83,7 @@ class wfCache {
83
return false;
84
}
85
if($_SERVER['REQUEST_METHOD'] != 'GET'){ return false; } //Only cache GET's
86
- if(strlen($_SERVER['QUERY_STRING']) > 0 && (! preg_match('/^\d+=\d+#x2F;', $_SERVER['QUERY_STRING'])) ){ //Don't cache query strings unless they are /?123132423=123123234 DDoS style.
87
return false;
88
}
89
//wordpress_logged_in_[hash] cookies indicates logged in
@@ -98,9 +98,19 @@ class wfCache {
98
if($ex){
99
$ex = unserialize($ex);
100
foreach($ex as $v){
101
- if($v['pt'] == 's'){ if(strpos($uri, $v['p']) === 0){ return false; } }
102
- if($v['pt'] == 'e'){ if(strpos($uri, $v['p']) === (strlen($uri) - strlen($v['p'])) ){ return false; } }
103
- if($v['pt'] == 'c'){ if(strpos($uri, $v['p']) !== false){ return false; } }
104
}
105
}
106
return true;
@@ -417,6 +427,23 @@ class wfCache {
417
if(wfConfig::get('allowHTTPSCaching')){
418
$sslString = "";
419
}
420
$code = <<<EOT
421
#WFCACHECODE - Do not remove this line. Disable Web Caching in Wordfence to remove this data.
422
<IfModule mod_deflate.c>
@@ -453,7 +480,7 @@ class wfCache {
453
RewriteCond %{QUERY_STRING} ^(?:\d+=\d+)?$
454
RewriteCond %{REQUEST_URI} (?:\/|\.html)$ [NC]
455
RewriteCond %{HTTP_COOKIE} !(comment_author|wp\-postpass|wf_logout|wordpress_logged_in|wptouch_switch_toggle|wpmp_switcher) [NC]
456
-
457
RewriteCond %{REQUEST_URI} \/*([^\/]*)\/*([^\/]*)\/*([^\/]*)\/*([^\/]*)\/*([^\/]*)(.*)$
458
RewriteCond "%{DOCUMENT_ROOT}{$pathPrefix}/wp-content/wfcache/%{HTTP_HOST}_%1/%2~%3~%4~%5~%6_wfcache%{ENV:WRDFNC_HTTPS}.html%{ENV:WRDFNC_ENC}" -f
459
RewriteRule \/*([^\/]*)\/*([^\/]*)\/*([^\/]*)\/*([^\/]*)\/*([^\/]*)(.*)$ "{$pathPrefix}/wp-content/wfcache/%{HTTP_HOST}_{$matchCaps}_wfcache%{ENV:WRDFNC_HTTPS}.html%{ENV:WRDFNC_ENC}" [L]
@@ -462,6 +489,9 @@ class wfCache {
462
EOT;
463
return $code;
464
}
465
public static function scheduleUpdateBlockedIPs(){
466
wp_clear_scheduled_hook('wordfence_update_blocked_IPs');
467
if(wfConfig::get('cacheType') != 'falcon'){
83
return false;
84
}
85
if($_SERVER['REQUEST_METHOD'] != 'GET'){ return false; } //Only cache GET's
86
+ if(isset($_SERVER['QUERY_STRING']) && strlen($_SERVER['QUERY_STRING']) > 0 && (! preg_match('/^\d+=\d+#x2F;', $_SERVER['QUERY_STRING'])) ){ //Don't cache query strings unless they are /?123132423=123123234 DDoS style.
87
return false;
88
}
89
//wordpress_logged_in_[hash] cookies indicates logged in
98
if($ex){
99
$ex = unserialize($ex);
100
foreach($ex as $v){
101
+ if($v['pt'] == 'eq'){ if(strtolower($uri) == strtolower($v['p'])){ return false; } }
102
+ if($v['pt'] == 's'){ if(stripos($uri, $v['p']) === 0){ return false; } }
103
+ if($v['pt'] == 'e'){ if(stripos($uri, $v['p']) === (strlen($uri) - strlen($v['p'])) ){ return false; } }
104
+ if($v['pt'] == 'c'){ if(stripos($uri, $v['p']) !== false){ return false; } }
105
+ if($v['pt'] == 'uac'){ if(stripos($_SERVER['HTTP_USER_AGENT'], $v['p']) !== false){ return false; } } //User-agent contains
106
+ if($v['pt'] == 'uaeq'){ if(strtolower($_SERVER['HTTP_USER_AGENT']) == strtolower($v['p'])){ return false; } } //user-agent equals
107
+ if($v['pt'] == 'cc'){
108
+ foreach($_COOKIE as $cookieName){
109
+ if(stripos($cookieName, $v['p']) !== false){ //Cookie name contains pattern
110
+ return false;
111
+ }
112
+ }
113
+ }
114
}
115
}
116
return true;
427
if(wfConfig::get('allowHTTPSCaching')){
428
$sslString = "";
429
}
430
+ $otherRewriteConds = "";
431
+ $ex = wfConfig::get('cacheExclusions', false);
432
+ if($ex){
433
+ $ex = unserialize($ex);
434
+ foreach($ex as $v){
435
+ if($v['pt'] == 'uac'){
436
+ $otherRewriteConds .= "\n\tRewriteCond %{HTTP_USER_AGENT} !" . self::regexSpaceFix(preg_quote($v['p'])) . " [NC]";
437
+ }
438
+ if($v['pt'] == 'uaeq'){
439
+ $otherRewriteConds .= "\n\tRewriteCond %{HTTP_USER_AGENT} !^" . self::regexSpaceFix(preg_quote($v['p'])) . "$ [NC]";
440
+ }
441
+ if($v['pt'] == 'cc'){
442
+ $otherRewriteConds .= "\n\tRewriteCond %{HTTP_COOKIE} !" . self::regexSpaceFix(preg_quote($v['p'])) . " [NC]";
443
+ }
444
+ }
445
+ }
446
+
447
$code = <<<EOT
448
#WFCACHECODE - Do not remove this line. Disable Web Caching in Wordfence to remove this data.
449
<IfModule mod_deflate.c>
480
RewriteCond %{QUERY_STRING} ^(?:\d+=\d+)?$
481
RewriteCond %{REQUEST_URI} (?:\/|\.html)$ [NC]
482
RewriteCond %{HTTP_COOKIE} !(comment_author|wp\-postpass|wf_logout|wordpress_logged_in|wptouch_switch_toggle|wpmp_switcher) [NC]
483
+ {$otherRewriteConds}
484
RewriteCond %{REQUEST_URI} \/*([^\/]*)\/*([^\/]*)\/*([^\/]*)\/*([^\/]*)\/*([^\/]*)(.*)$
485
RewriteCond "%{DOCUMENT_ROOT}{$pathPrefix}/wp-content/wfcache/%{HTTP_HOST}_%1/%2~%3~%4~%5~%6_wfcache%{ENV:WRDFNC_HTTPS}.html%{ENV:WRDFNC_ENC}" -f
486
RewriteRule \/*([^\/]*)\/*([^\/]*)\/*([^\/]*)\/*([^\/]*)\/*([^\/]*)(.*)$ "{$pathPrefix}/wp-content/wfcache/%{HTTP_HOST}_{$matchCaps}_wfcache%{ENV:WRDFNC_HTTPS}.html%{ENV:WRDFNC_ENC}" [L]
489
EOT;
490
return $code;
491
}
492
+ private static function regexSpaceFix($str){
493
+ return str_replace(' ', '\\s', $str);
494
+ }
495
public static function scheduleUpdateBlockedIPs(){
496
wp_clear_scheduled_hook('wordfence_update_blocked_IPs');
497
if(wfConfig::get('cacheType') != 'falcon'){
lib/wfConfig.php CHANGED
@@ -61,7 +61,7 @@ class wfConfig {
61
),
62
"otherParams" => array(
63
'securityLevel' => '0',
64
- "alertEmails" => "", "liveTraf_ignoreUsers" => "", "liveTraf_ignoreIPs" => "", "liveTraf_ignoreUA" => "", "apiKey" => "", "maxMem" => '256', 'scan_exclude' => '', 'whitelisted' => '', 'maxExecutionTime' => '', 'howGetIPs' => '', 'actUpdateInterval' => '', 'alert_maxHourly' => 0,
65
"neverBlockBG" => "neverBlockVerified",
66
"loginSec_countFailMins" => "5",
67
"loginSec_lockoutMins" => "5",
@@ -136,7 +136,7 @@ class wfConfig {
136
),
137
"otherParams" => array(
138
'securityLevel' => '1',
139
- "alertEmails" => "", "liveTraf_ignoreUsers" => "", "liveTraf_ignoreIPs" => "", "liveTraf_ignoreUA" => "", "apiKey" => "", "maxMem" => '256', 'scan_exclude' => '', 'whitelisted' => '', 'maxExecutionTime' => '', 'howGetIPs' => '', 'actUpdateInterval' => '', 'alert_maxHourly' => 0,
140
"neverBlockBG" => "neverBlockVerified",
141
"loginSec_countFailMins" => "5",
142
"loginSec_lockoutMins" => "5",
@@ -211,7 +211,7 @@ class wfConfig {
211
),
212
"otherParams" => array(
213
'securityLevel' => '2',
214
- "alertEmails" => "", "liveTraf_ignoreUsers" => "", "liveTraf_ignoreIPs" => "", "liveTraf_ignoreUA" => "", "apiKey" => "", "maxMem" => '256', 'scan_exclude' => '', 'whitelisted' => '', 'maxExecutionTime' => '', 'howGetIPs' => '', 'actUpdateInterval' => '', 'alert_maxHourly' => 0,
215
"neverBlockBG" => "neverBlockVerified",
216
"loginSec_countFailMins" => "240",
217
"loginSec_lockoutMins" => "240",
@@ -286,7 +286,7 @@ class wfConfig {
286
),
287
"otherParams" => array(
288
'securityLevel' => '3',
289
- "alertEmails" => "", "liveTraf_ignoreUsers" => "", "liveTraf_ignoreIPs" => "", "liveTraf_ignoreUA" => "", "apiKey" => "", "maxMem" => '256', 'scan_exclude' => '', 'whitelisted' => '', 'maxExecutionTime' => '', 'howGetIPs' => '', 'actUpdateInterval' => '', 'alert_maxHourly' => 0,
290
"neverBlockBG" => "neverBlockVerified",
291
"loginSec_countFailMins" => "1440",
292
"loginSec_lockoutMins" => "1440",
@@ -361,7 +361,7 @@ class wfConfig {
361
),
362
"otherParams" => array(
363
'securityLevel' => '4',
364
- "alertEmails" => "", "liveTraf_ignoreUsers" => "", "liveTraf_ignoreIPs" => "", "liveTraf_ignoreUA" => "", "apiKey" => "", "maxMem" => '256', 'scan_exclude' => '', 'whitelisted' => '', 'maxExecutionTime' => '', 'howGetIPs' => '', 'actUpdateInterval' => '', 'alert_maxHourly' => 0,
365
"neverBlockBG" => "neverBlockVerified",
366
"loginSec_countFailMins" => "1440",
367
"loginSec_lockoutMins" => "1440",
@@ -483,10 +483,14 @@ class wfConfig {
483
if(is_file($cacheFile)){
484
//require($cacheFile); //will only require the file on first parse through this code. But we dynamically update the var and update the file with each get
485
try {
486
- wfConfig::$diskCache = @unserialize(@file_get_contents($cacheFile));
487
- if(isset(wfConfig::$diskCache) && is_array(wfConfig::$diskCache) && isset(wfConfig::$diskCache[$key])){
488
- return wfConfig::$diskCache[$key];
489
- }
490
} catch(Exception $err){ } //file_get or unserialize may fail, so just fail quietly.
491
}
492
}
@@ -494,7 +498,7 @@ class wfConfig {
494
if(self::$diskCacheDisabled){ return $val; }
495
wfConfig::$diskCache[$key] = isset($val) ? $val : '';
496
try {
497
- $bytesWritten = @file_put_contents($cacheFile, serialize(wfConfig::$diskCache), LOCK_EX);
498
} catch(Exception $err2){}
499
if(! $bytesWritten){
500
self::$diskCacheDisabled = true;
61
),
62
"otherParams" => array(
63
'securityLevel' => '0',
64
+ "alertEmails" => "", "liveTraf_ignoreUsers" => "", "liveTraf_ignoreIPs" => "", "liveTraf_ignoreUA" => "", "apiKey" => "", "maxMem" => '256', 'scan_exclude' => '', 'whitelisted' => '', 'maxExecutionTime' => '', 'howGetIPs' => '', 'actUpdateInterval' => '', 'alert_maxHourly' => 0, 'loginSec_userBlacklist' => '',
65
"neverBlockBG" => "neverBlockVerified",
66
"loginSec_countFailMins" => "5",
67
"loginSec_lockoutMins" => "5",
136
),
137
"otherParams" => array(
138
'securityLevel' => '1',
139
+ "alertEmails" => "", "liveTraf_ignoreUsers" => "", "liveTraf_ignoreIPs" => "", "liveTraf_ignoreUA" => "", "apiKey" => "", "maxMem" => '256', 'scan_exclude' => '', 'whitelisted' => '', 'maxExecutionTime' => '', 'howGetIPs' => '', 'actUpdateInterval' => '', 'alert_maxHourly' => 0, 'loginSec_userBlacklist' => '',
140
"neverBlockBG" => "neverBlockVerified",
141
"loginSec_countFailMins" => "5",
142
"loginSec_lockoutMins" => "5",
211
),
212
"otherParams" => array(
213
'securityLevel' => '2',
214
+ "alertEmails" => "", "liveTraf_ignoreUsers" => "", "liveTraf_ignoreIPs" => "", "liveTraf_ignoreUA" => "", "apiKey" => "", "maxMem" => '256', 'scan_exclude' => '', 'whitelisted' => '', 'maxExecutionTime' => '', 'howGetIPs' => '', 'actUpdateInterval' => '', 'alert_maxHourly' => 0, 'loginSec_userBlacklist' => '',
215
"neverBlockBG" => "neverBlockVerified",
216
"loginSec_countFailMins" => "240",
217
"loginSec_lockoutMins" => "240",
286
),
287
"otherParams" => array(
288
'securityLevel' => '3',
289
+ "alertEmails" => "", "liveTraf_ignoreUsers" => "", "liveTraf_ignoreIPs" => "", "liveTraf_ignoreUA" => "", "apiKey" => "", "maxMem" => '256', 'scan_exclude' => '', 'whitelisted' => '', 'maxExecutionTime' => '', 'howGetIPs' => '', 'actUpdateInterval' => '', 'alert_maxHourly' => 0, 'loginSec_userBlacklist' => '',
290
"neverBlockBG" => "neverBlockVerified",
291
"loginSec_countFailMins" => "1440",
292
"loginSec_lockoutMins" => "1440",
361
),
362
"otherParams" => array(
363
'securityLevel' => '4',
364
+ "alertEmails" => "", "liveTraf_ignoreUsers" => "", "liveTraf_ignoreIPs" => "", "liveTraf_ignoreUA" => "", "apiKey" => "", "maxMem" => '256', 'scan_exclude' => '', 'whitelisted' => '', 'maxExecutionTime' => '', 'howGetIPs' => '', 'actUpdateInterval' => '', 'alert_maxHourly' => 0, 'loginSec_userBlacklist' => '',
365
"neverBlockBG" => "neverBlockVerified",
366
"loginSec_countFailMins" => "1440",
367
"loginSec_lockoutMins" => "1440",
483
if(is_file($cacheFile)){
484
//require($cacheFile); //will only require the file on first parse through this code. But we dynamically update the var and update the file with each get
485
try {
486
+ $cont = @file_get_contents($cacheFile);
487
+ if(strpos($cont, '<?php') === 0){ //"<?php die() XX"
488
+ $cont = substr($cont, strlen(self::$tmpFileHeader));
489
+ wfConfig::$diskCache = @unserialize($cont);
490
+ if(isset(wfConfig::$diskCache) && is_array(wfConfig::$diskCache) && isset(wfConfig::$diskCache[$key])){
491
+ return wfConfig::$diskCache[$key];
492
+ }
493
+ } //Else don't return a cached value because this is an old file without the php header so we're going to rewrite it.
494
} catch(Exception $err){ } //file_get or unserialize may fail, so just fail quietly.
495
}
496
}
498
if(self::$diskCacheDisabled){ return $val; }
499
wfConfig::$diskCache[$key] = isset($val) ? $val : '';
500
try {
501
+ $bytesWritten = @file_put_contents($cacheFile, self::$tmpFileHeader . serialize(wfConfig::$diskCache), LOCK_EX);
502
} catch(Exception $err2){}
503
if(! $bytesWritten){
504
self::$diskCacheDisabled = true;
lib/wfLog.php CHANGED
@@ -45,10 +45,18 @@ class wfLog {
45
);
46
}
47
public function logLogin($action, $fail, $username){
48
$user = get_user_by('login', $username);
49
$userID = 0;
50
if($user){
51
$userID = $user->ID;
52
}
53
$this->getDB()->queryWrite("insert into " . $this->loginsTable . " (ctime, fail, action, username, userID, IP, UA) values (%f, %d, '%s', '%s', %s, %s, '%s')",
54
sprintf('%.6f', microtime(true)),
@@ -767,7 +775,7 @@ class wfLog {
767
return;
768
}
769
}
770
- private function do503($secsToGo, $reason){
771
wfUtils::doNotCache();
772
header('HTTP/1.1 503 Service Temporarily Unavailable');
773
header('Status: 503 Service Temporarily Unavailable');
45
);
46
}
47
public function logLogin($action, $fail, $username){
48
+ if(! $username){
49
+ return;
50
+ }
51
$user = get_user_by('login', $username);
52
$userID = 0;
53
if($user){
54
$userID = $user->ID;
55
+ if(! $userID){
56
+ return;
57
+ }
58
+ } else {
59
+ return;
60
}
61
$this->getDB()->queryWrite("insert into " . $this->loginsTable . " (ctime, fail, action, username, userID, IP, UA) values (%f, %d, '%s', '%s', %s, %s, '%s')",
62
sprintf('%.6f', microtime(true)),
775
return;
776
}
777
}
778
+ public function do503($secsToGo, $reason){
779
wfUtils::doNotCache();
780
header('HTTP/1.1 503 Service Temporarily Unavailable');
781
header('Status: 503 Service Temporarily Unavailable');
lib/wfScanEngine.php CHANGED
@@ -124,7 +124,7 @@ class wfScanEngine {
124
if($this->i->totalIssues > 0){
125
$this->status(10, 'info', "SUM_FINAL:Scan complete. You have " . $this->i->totalIssues . " new issues to fix. See below.");
126
} else {
127
- $this->status(10, 'info', "SUM_FINAL:Scan complete. Congratulations, there were no problems found.");
128
}
129
return;
130
}
@@ -187,6 +187,7 @@ class wfScanEngine {
187
}
188
$includeInKnownFilesScan = array();
189
foreach($baseContents as $file){ //Only include base files less than a meg that are files.
190
$fullFile = rtrim(ABSPATH, '/') . '/' . $file;
191
if($scanOutside){
192
$includeInKnownFilesScan[] = $file;
124
if($this->i->totalIssues > 0){
125
$this->status(10, 'info', "SUM_FINAL:Scan complete. You have " . $this->i->totalIssues . " new issues to fix. See below.");
126
} else {
127
+ $this->status(10, 'info', "SUM_FINAL:Scan complete. Congratulations, no problems found.");
128
}
129
return;
130
}
187
}
188
$includeInKnownFilesScan = array();
189
foreach($baseContents as $file){ //Only include base files less than a meg that are files.
190
+ if($file == '.' || $file == '..'){ continue; }
191
$fullFile = rtrim(ABSPATH, '/') . '/' . $file;
192
if($scanOutside){
193
$includeInKnownFilesScan[] = $file;
lib/wordfenceClass.php CHANGED
@@ -373,6 +373,7 @@ class wordfence {
373
add_action('profile_update', 'wordfence::profileUpdateAction', '99', 2);
374
add_action('validate_password_reset', 'wordfence::validatePassword', 10, 2 );
375
}
376
377
//For debugging
378
//add_filter( 'cron_schedules', 'wordfence::cronAddSchedules' );
@@ -416,7 +417,7 @@ class wordfence {
416
}
417
*/
418
public static function wpRedirectFilter($URL, $status){
419
- if(isset($_GET['author']) && preg_match('/^https?:\/\/[^\/]+\/author\/.+/i', $URL) && wfConfig::get('loginSec_disableAuthorScan') ){ //author query variable is present and we're about to redirect to a URL that starts with http://blah/author/...
420
return home_url(); //Send the user to the home URL (as opposed to site_url() which is not the home page on some sites)
421
}
422
return $URL;
@@ -452,13 +453,13 @@ class wordfence {
452
$UA = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : '';
453
$isCrawler = false;
454
if($UA){
455
- $b = $browscap->getBrowser($res['UA']);
456
if($b['Crawler']){
457
$isCrawler = true;
458
}
459
}
460
461
- ob_end_clean();
462
if(! headers_sent()){
463
header('Content-type: text/javascript');
464
header("Connection: close");
@@ -502,6 +503,11 @@ class wordfence {
502
die(json_encode($returnArr));
503
exit;
504
}
505
public static function validateProfileUpdate($errors, $update, $userData){
506
wordfence::validatePassword($errors, $userData);
507
}
@@ -779,9 +785,22 @@ class wordfence {
779
780
}
781
if($secEnabled){
782
- if(is_wp_error($authResult) && $authResult->get_error_code() == 'invalid_username' && wfConfig::get('loginSec_lockInvalidUsers')){
783
- self::lockOutIP($IP, "Used an invalid username '" . $_POST['log'] . "' to try to sign in.");
784
- require('wfLockedOut.php');
785
}
786
$tKey = 'wflginfl_' . wfUtils::inet_aton($IP);
787
if(is_wp_error($authResult) && ($authResult->get_error_code() == 'invalid_username' || $authResult->get_error_code() == 'incorrect_password') ){
@@ -1297,6 +1316,7 @@ class wordfence {
1297
}
1298
wfConfig::set('allowHTTPSCaching', $_POST['allowHTTPSCaching'] == '1' ? 1 : 0);
1299
wfConfig::set('addCacheComment', $_POST['addCacheComment'] == 1 ? '1' : 0);
1300
if($changed && wfConfig::get('cacheType', false) == 'falcon'){
1301
$err = wfCache::addHtaccessCode('add');
1302
if($err){
@@ -1472,6 +1492,11 @@ class wordfence {
1472
);
1473
wfConfig::set('cacheExclusions', serialize($ex));
1474
wfCache::scheduleCacheClear();
1475
return array('ok' => 1);
1476
}
1477
public static function ajax_removeCacheExclusion_callback(){
@@ -1481,13 +1506,20 @@ class wordfence {
1481
return array('ok' => 1);
1482
}
1483
$ex = unserialize($ex);
1484
for($i = 0; $i < sizeof($ex); $i++){
1485
if((string)$ex[$i]['id'] == (string)$id){
1486
array_splice($ex, $i, 1);
1487
//Dont break in case of dups
1488
}
1489
}
1490
wfConfig::set('cacheExclusions', serialize($ex));
1491
return array('ok' => 1);
1492
}
1493
public static function ajax_loadCacheExclusions_callback(){
@@ -1554,6 +1586,19 @@ class wordfence {
1554
}
1555
}
1556
}
1557
$opts['apiKey'] = trim($opts['apiKey']);
1558
if($opts['apiKey'] && (! preg_match('/^[a-fA-F0-9]+#x2F;', $opts['apiKey'])) ){ //User entered something but it's garbage.
1559
return array('errorMsg' => "You entered an API key but it is not in a valid format. It must consist only of characters A to F and 0 to 9.");
373
add_action('profile_update', 'wordfence::profileUpdateAction', '99', 2);
374
add_action('validate_password_reset', 'wordfence::validatePassword', 10, 2 );
375
}
376
+ add_action('publish_future_post', 'wordfence::publishFuturePost');
377
378
//For debugging
379
//add_filter( 'cron_schedules', 'wordfence::cronAddSchedules' );
417
}
418
*/
419
public static function wpRedirectFilter($URL, $status){
420
+ if(isset($_GET['author']) && preg_match('/\/author\/.+/i', $URL) && wfConfig::get('loginSec_disableAuthorScan') ){ //author query variable is present and we're about to redirect to a URL that starts with http://blah/author/...
421
return home_url(); //Send the user to the home URL (as opposed to site_url() which is not the home page on some sites)
422
}
423
return $URL;
453
$UA = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : '';
454
$isCrawler = false;
455
if($UA){
456
+ $b = $browscap->getBrowser($UA);
457
if($b['Crawler']){
458
$isCrawler = true;
459
}
460
}
461
462
+ @ob_end_clean();
463
if(! headers_sent()){
464
header('Content-type: text/javascript');
465
header("Connection: close");
503
die(json_encode($returnArr));
504
exit;
505
}
506
+ public static function publishFuturePost($id){
507
+ if(wfConfig::get('clearCacheSched')){
508
+ wfCache::scheduleCacheClear();
509
+ }
510
+ }
511
public static function validateProfileUpdate($errors, $update, $userData){
512
wordfence::validatePassword($errors, $userData);
513
}
785
786
}
787
if($secEnabled){
788
+ if(is_wp_error($authResult) && $authResult->get_error_code() == 'invalid_username'){
789
+ if($blacklist = wfConfig::get('loginSec_userBlacklist')){
790
+ $users = explode(',', $blacklist);
791
+ foreach($users as $user){
792
+ if(strtolower($_POST['log']) == strtolower($user)){
793
+ self::getLog()->blockIP($IP, "Blocked by login security setting.");
794
+ $secsToGo = wfConfig::get('blockedTime');
795
+ self::getLog()->do503($secsToGo, "Blocked by login security setting.");
796
+ break;
797
+ }
798
+ }
799
+ }
800
+ if(wfConfig::get('loginSec_lockInvalidUsers')){
801
+ self::lockOutIP($IP, "Used an invalid username '" . $_POST['log'] . "' to try to sign in.");
802
+ require('wfLockedOut.php');
803
+ }
804
}
805
$tKey = 'wflginfl_' . wfUtils::inet_aton($IP);
806
if(is_wp_error($authResult) && ($authResult->get_error_code() == 'invalid_username' || $authResult->get_error_code() == 'incorrect_password') ){
1316
}
1317
wfConfig::set('allowHTTPSCaching', $_POST['allowHTTPSCaching'] == '1' ? 1 : 0);
1318
wfConfig::set('addCacheComment', $_POST['addCacheComment'] == 1 ? '1' : 0);
1319
+ wfConfig::set('clearCacheSched', $_POST['clearCacheSched'] == 1 ? '1' : 0);
1320
if($changed && wfConfig::get('cacheType', false) == 'falcon'){
1321
$err = wfCache::addHtaccessCode('add');
1322
if($err){
1492
);
1493
wfConfig::set('cacheExclusions', serialize($ex));
1494
wfCache::scheduleCacheClear();
1495
+ if(wfConfig::get('cacheType', false) == 'falcon' && preg_match('/^(?:uac|uaeq|cc)#x2F;', $_POST['patternType'])){
1496
+ if(wfCache::addHtaccessCode('add')){ //rewrites htaccess rules
1497
+ return array('errorMsg' => "We added the rule you requested but could not modify your .htaccess file. Please delete this rule, check the permissions on your .htaccess file and then try again.");
1498
+ }
1499
+ }
1500
return array('ok' => 1);
1501
}
1502
public static function ajax_removeCacheExclusion_callback(){
1506
return array('ok' => 1);
1507
}
1508
$ex = unserialize($ex);
1509
+ $rewriteHtaccess = false;
1510
for($i = 0; $i < sizeof($ex); $i++){
1511
if((string)$ex[$i]['id'] == (string)$id){
1512
+ if(wfConfig::get('cacheType', false) == 'falcon' && preg_match('/^(?:uac|uaeq|cc)#x2F;', $ex[$i]['pt'])){
1513
+ $rewriteHtaccess = true;
1514
+ }
1515
array_splice($ex, $i, 1);
1516
//Dont break in case of dups
1517
}
1518
}
1519
wfConfig::set('cacheExclusions', serialize($ex));
1520
+ if($rewriteHtaccess && wfCache::addHtaccessCode('add')){ //rewrites htaccess rules
1521
+ return array('errorMsg', "We removed that rule but could not rewrite your .htaccess file. You're going to have to manually remove this rule from your .htaccess file. Please reload this page now.");
1522
+ }
1523
return array('ok' => 1);
1524
}
1525
public static function ajax_loadCacheExclusions_callback(){
1586
}
1587
}
1588
}
1589
+ $userBlacklist = array();
1590
+ foreach(explode(',', $opts['loginSec_userBlacklist']) as $user){
1591
+ $user = trim($user);
1592
+ if(strlen($user) > 0){
1593
+ $userBlacklist[] = $user;
1594
+ }
1595
+ }
1596
+ if(sizeof($userBlacklist) > 0){
1597
+ $opts['loginSec_userBlacklist'] = implode(',', $userBlacklist);
1598
+ } else {
1599
+ $opts['loginSec_userBlacklist'] = '';
1600
+ }
1601
+
1602
$opts['apiKey'] = trim($opts['apiKey']);
1603
if($opts['apiKey'] && (! preg_match('/^[a-fA-F0-9]+#x2F;', $opts['apiKey'])) ){ //User entered something but it's garbage.
1604
return array('errorMsg' => "You entered an API key but it is not in a valid format. It must consist only of characters A to F and 0 to 9.");
lib/wordfenceHash.php CHANGED
@@ -117,6 +117,7 @@ class wordfenceHash {
117
$this->engine = $engine;
118
$files = scandir($this->path);
119
foreach($files as $file){
120
if(sizeof($this->only) > 0 && (! in_array($file, $this->only))){
121
continue;
122
}
117
$this->engine = $engine;
118
$files = scandir($this->path);
119
foreach($files as $file){
120
+ if($file == '.' || $file == '..'){ continue; }
121
if(sizeof($this->only) > 0 && (! in_array($file, $this->only))){
122
continue;
123
}
readme.txt CHANGED
@@ -2,8 +2,8 @@
2
Contributors: mmaunder
3
Tags: wordpress, security, performance, speed, caching, cache, caching plugin, wordpress cache, wordpress caching, wordpress security, security plugin, secure, anti-virus, malware, firewall, antivirus, virus, google safe browsing, phishing, scrapers, hacking, wordfence, securty, secrity, secure, two factor, cellphone sign-in, cellphone signin, cellphone, twofactor, security, secure, htaccess, login, log, users, login alerts, lock, chmod, maintenance, plugin, private, privacy, protection, permissions, 503, base64, injection, code, encode, script, attack, hack, hackers, block, blocked, prevent, prevention, RFI, XSS, CRLF, CSRF, SQL Injection, vulnerability, website security, WordPress security, security log, logging, HTTP log, error log, login security, personal security, infrastructure security, firewall security, front-end security, web server security, proxy security, reverse proxy security, secure website, secure login, two factor security, maximum login security, heartbleed, heart bleed, heartbleed vulnerability, openssl vulnerability, nginx, litespeed, php5-fpm
4
Requires at least: 3.3.1
5
- Tested up to: 3.9
6
- Stable tag: 5.0.6
7
8
Wordfence Security is a free enterprise class security and performance plugin that makes your site up to 50 times faster and more secure.
9
@@ -162,6 +162,19 @@ cause a security hole on your site.
162
163
== Changelog ==
164
165
= 5.0.6 =
166
* Feature: Prevent discovery of usernames through '?/author=N' scans. New option under login security which you can enable.
167
* Fix: Introduced new global hash whitelist on our servers that drastically reduces false positives in all scans especially theme and plugin scans.
2
Contributors: mmaunder
3
Tags: wordpress, security, performance, speed, caching, cache, caching plugin, wordpress cache, wordpress caching, wordpress security, security plugin, secure, anti-virus, malware, firewall, antivirus, virus, google safe browsing, phishing, scrapers, hacking, wordfence, securty, secrity, secure, two factor, cellphone sign-in, cellphone signin, cellphone, twofactor, security, secure, htaccess, login, log, users, login alerts, lock, chmod, maintenance, plugin, private, privacy, protection, permissions, 503, base64, injection, code, encode, script, attack, hack, hackers, block, blocked, prevent, prevention, RFI, XSS, CRLF, CSRF, SQL Injection, vulnerability, website security, WordPress security, security log, logging, HTTP log, error log, login security, personal security, infrastructure security, firewall security, front-end security, web server security, proxy security, reverse proxy security, secure website, secure login, two factor security, maximum login security, heartbleed, heart bleed, heartbleed vulnerability, openssl vulnerability, nginx, litespeed, php5-fpm
4
Requires at least: 3.3.1
5
+ Tested up to: 3.9.1
6
+ Stable tag: 5.0.7
7
8
Wordfence Security is a free enterprise class security and performance plugin that makes your site up to 50 times faster and more secure.
9
162
163
== Changelog ==
164
165
+ = 5.0.7 =
166
+ * Feature: Immediately block IP if hacker tries any of the following usernames. (Comma separated list that you can specify on the Wordfence options page)
167
+ * Feature: Exclude exact URL's from caching. Specifically, this allows you to exclude the home page which was not possible before.
168
+ * Feature: Exclude browsers or partial browser matches and specific cookies from caching.
169
+ * Fix: Fixed issue where /.. dirs would be included in certain scandir operations.
170
+ * Fix: logHuman function was not analyzing user-agent strings correctly which would allow some crawlers that execute JS to be logged as humans.
171
+ * Fix: Removed ob_end_clean warnings about empty buffers when a human is being logged.
172
+ * Fix: Removed warning in lib/wfCache.php caused by unset $_SERVER['QUERY_STRING'] when we check it.
173
+ * Fix: Fixed "logged out as ''" blank username logout messages.
174
+ * Fix: Improved security of config cache by adding a PHP header to file that we strip. Already secure because we have a .htaccess denying access, but more is better.
175
+ * Fix: Falcon Engine option to clear Falcon cache when a post scheduled to be published in future is published.
176
+ * Fix: Fixed Heartbleed scans hanging.
177
+
178
= 5.0.6 =
179
* Feature: Prevent discovery of usernames through '?/author=N' scans. New option under login security which you can enable.
180
* Fix: Introduced new global hash whitelist on our servers that drastically reduces false positives in all scans especially theme and plugin scans.
wordfence.php CHANGED
@@ -2,15 +2,15 @@
2
/*
3
Plugin Name: Wordfence Security
4
Plugin URI: http://www.wordfence.com/
5
- Description: Wordfence Security - Anti-virus, Firewal and Site Speedup
6
Author: Wordfence
7
- Version: 5.0.6
8
Author URI: http://www.wordfence.com/
9
*/
10
if(defined('WP_INSTALLING') && WP_INSTALLING){
11
return;
12
}
13
- define('WORDFENCE_VERSION', '5.0.6');
14
if(get_option('wordfenceActivated') != 1){
15
add_action('activated_plugin','wordfence_save_activation_error'); function wordfence_save_activation_error(){ update_option('wf_plugin_act_error', ob_get_contents()); }
16
}
2
/*
3
Plugin Name: Wordfence Security
4
Plugin URI: http://www.wordfence.com/
5
+ Description: Wordfence Security - Anti-virus, Firewall and Site Speedup
6
Author: Wordfence
7
+ Version: 5.0.7
8
Author URI: http://www.wordfence.com/
9
*/
10
if(defined('WP_INSTALLING') && WP_INSTALLING){
11
return;
12
}
13
+ define('WORDFENCE_VERSION', '5.0.7');
14
if(get_option('wordfenceActivated') != 1){
15
add_action('activated_plugin','wordfence_save_activation_error'); function wordfence_save_activation_error(){ update_option('wf_plugin_act_error', ob_get_contents()); }
16
}