Version Description
- Feature: (Premium) Advanced Comment Spam Filter. Checks comment source IP, author URL and hosts and IP's in body against additional spam lists.
- Feature: (Premium) Check if your site is being Spamvertised i.e. your domain is being included in spam emails. Usually indicates you've been hacked.
- Feature: (Premium) Check if your website IP is generating spam. Checks against spam lists if your IP is a known source of spam.
- Improvement: Cache clearing errors are nown shown with clear explanations.
- Improvement: Added lightweight stats logging internally in preparation for displaying them on the admin UI in the next release.
- Fix: If a non-existent user tries to sign in it is not logged in the live logins tab. Fixed.
- Fix: Removed warning "Trying to get property of non-object" that would occur under certain conditions.
- Fix: Removed call to is_404() which was not having any effect and would issue a warning if debug mode is enabled.
- Fix: Check if CURL is installed as part of connectivity test.
Download this release
Release Info
Developer | mmaunder |
Plugin | Wordfence Security – Firewall & Malware Scan |
Version | 5.0.9 |
Comparing to | |
See all releases |
Code changes from version 5.0.8 to 5.0.9
- lib/conntest.php +4 -0
- lib/dashboard.php +49 -0
- lib/menu_options.php +6 -2
- lib/menu_scan.php +61 -0
- lib/wfCache.php +32 -10
- lib/wfConfig.php +27 -0
- lib/wfLog.php +6 -3
- lib/wfScanEngine.php +51 -0
- lib/wfUtils.php +32 -6
- lib/wordfenceClass.php +75 -2
- lib/wordfenceConstants.php +1 -1
- readme.txt +13 -2
- wordfence.php +2 -2
lib/conntest.php
CHANGED
@@ -40,6 +40,10 @@ function doWPostTest($protocol){
|
|
40 |
}
|
41 |
}
|
42 |
function doCurlTest($protocol){
|
|
|
|
|
|
|
|
|
43 |
echo "<br /><b>STARTING CURL $protocol CONNECTION TEST....</b><br />\n";
|
44 |
global $curlContent;
|
45 |
$curlContent = "";
|
40 |
}
|
41 |
}
|
42 |
function doCurlTest($protocol){
|
43 |
+
if(! function_exists('curl_init')){
|
44 |
+
echo "<br /><b style='color: #F00;'>CURL is not installed</b>. Asking your hosting provider to install and enable CURL may improve any connection problems.</b><br />\n";
|
45 |
+
return;
|
46 |
+
}
|
47 |
echo "<br /><b>STARTING CURL $protocol CONNECTION TEST....</b><br />\n";
|
48 |
global $curlContent;
|
49 |
$curlContent = "";
|
lib/dashboard.php
ADDED
@@ -0,0 +1,49 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
|
2 |
+
<table border="0">
|
3 |
+
<?php
|
4 |
+
$lastAdminLogin = wfConfig::get_ser('lastAdminLogin', false);
|
5 |
+
if($lastAdminLogin){
|
6 |
+
?>
|
7 |
+
<tr><td style="padding-right: 20px;">Last Admin Username Login:</td><td>
|
8 |
+
<?php
|
9 |
+
echo '<strong>' . $lastAdminLogin['username'] . '</strong> [' . $lastAdminLogin['firstName'] . ' ' . $lastAdminLogin['lastName'] . ']</td></tr><tr style="padding-right: 20px;"><td>Last Admin Login Time</td><td>' . $lastAdminLogin['time'] . '</td></tr><tr><td style="padding-right: 20px;">Last Admin Login IP:</td><td>' . $lastAdminLogin['IP'] . '</td></tr>';
|
10 |
+
?>
|
11 |
+
</td></tr>
|
12 |
+
<?php } ?>
|
13 |
+
<?php if(wfConfig::get('firewallEnabled')){ ?><tr><td style="padding-right: 20px;">Firewall Enabled:</td><td style="color: #0F0;">✔</td></tr> <?php } ?>
|
14 |
+
<?php if(wfConfig::get('loginSecurityEnabled')){ ?><tr><td style="padding-right: 20px;">Login Security Enabled:</td><td style="color: #0F0;">✔</td></tr> <?php } ?>
|
15 |
+
<?php if(wfConfig::get('other_scanComments')){ ?><tr><td style="padding-right: 20px;">Comment Filter Enabled:</td><td style="color: #0F0;">✔</td></tr> <?php } ?>
|
16 |
+
<?php if(wfConfig::get('other_hideWPVersion')){ ?><tr><td style="padding-right: 20px;">WordPress Version Hiding Enabled:</td><td style="color: #0F0;">✔</td></tr> <?php } ?>
|
17 |
+
<?php if(wfConfig::get('other_pwStrengthOnUpdate')){ ?><tr><td style="padding-right: 20px;">Password Strength Checking Enabled:</td><td style="color: #0F0;">✔</td></tr> <?php } ?>
|
18 |
+
<?php if(wfConfig::get('other_WFNet')){ ?><tr><td style="padding-right: 20px;">Security Network Active:</td><td style="color: #0F0;">✔</td></tr> <?php } ?>
|
19 |
+
<?php if(wfConfig::get('loginSec_maskLoginErrors')){ ?><tr><td style="padding-right: 20px;">Username Hiding in login form errors:</td><td style="color: #0F0;">✔</td></tr> <?php } ?>
|
20 |
+
<?php if(wfConfig::get('loginSec_disableAuthorScan')){ ?><tr><td style="padding-right: 20px;">Prevent username discovery by bots:</td><td style="color: #0F0;">✔</td></tr> <?php } ?>
|
21 |
+
<?php if(wfConfig::get('loginSec_blockAdminReg')){ ?><tr><td style="padding-right: 20px;">Protect 'admin' username from being registered:</td><td style="color: #0F0;">✔</td></tr> <?php } ?>
|
22 |
+
<?php if(wfConfig::get('loginSec_userBlacklist')){ ?><tr><td style="padding-right: 20px;">Instant blocking of specific username attempts:</td><td style="color: #0F0;">✔</td></tr> <?php } ?>
|
23 |
+
<?php if(wfConfig::get('other_noAnonMemberComments')){ ?><tr><td style="padding-right: 20px;">Hold anon comments by existing usernames:</td><td style="color: #0F0;">✔</td></tr> <?php } ?>
|
24 |
+
<?php if(wfConfig::get('loginSec_lockInvalidUsers')){ ?><tr><td style="padding-right: 20px;">Instant lockout of invalid usernames:</td><td style="color: #0F0;">✔</td></tr> <?php } ?>
|
25 |
+
<?php if(wfConfig::get('loginSec_strongPasswds') == 'all' || wfConfig::get('loginSec_strongPasswds') == 'pubs'){ ?><tr><td style="padding-right: 20px;">Enforce strong passwords:</td><td style="color: #0F0;">✔</td></tr> <?php } ?>
|
26 |
+
|
27 |
+
<?php if(wfConfig::get('scheduledScansEnabled')){ ?>
|
28 |
+
<?php if(wfConfig::get('scheduledScansEnabled')){ ?><tr><td style="padding-right: 20px;">Security Scans Enabled:</td><td style="color: #0F0;">✔</td></tr> <?php } ?>
|
29 |
+
<?php if(wfConfig::get('scansEnabled_public')){ ?><tr><td style="padding-right: 20px;">Scan public facing site:</td><td style="color: #0F0;">✔</td></tr> <?php } ?>
|
30 |
+
<?php if(wfConfig::get('scansEnabled_heartbleed')){ ?><tr><td style="padding-right: 20px;">Scan for HeartBleed Vulnerability:</td><td style="color: #0F0;">✔</td></tr> <?php } ?>
|
31 |
+
<?php if(wfConfig::get('scansEnabled_core')){ ?><tr><td style="padding-right: 20px;">Scan Core Files:</td><td style="color: #0F0;">✔</td></tr> <?php } ?>
|
32 |
+
<?php if(wfConfig::get('scansEnabled_themes')){ ?><tr><td style="padding-right: 20px;">Scan Themes:</td><td style="color: #0F0;">✔</td></tr> <?php } ?>
|
33 |
+
<?php if(wfConfig::get('scansEnabled_plugins')){ ?><tr><td style="padding-right: 20px;">Scan Plugins:</td><td style="color: #0F0;">✔</td></tr> <?php } ?>
|
34 |
+
<?php if(wfConfig::get('scansEnabled_fileContents')){ ?><tr><td style="padding-right: 20px;">Scan Other Files:</td><td style="color: #0F0;">✔</td></tr> <?php } ?>
|
35 |
+
<?php if(wfConfig::get('scansEnabled_posts')){ ?><tr><td style="padding-right: 20px;">Scan Posts:</td><td style="color: #0F0;">✔</td></tr> <?php } ?>
|
36 |
+
<?php if(wfConfig::get('scansEnabled_comments')){ ?><tr><td style="padding-right: 20px;">Scan Comments:</td><td style="color: #0F0;">✔</td></tr> <?php } ?>
|
37 |
+
<?php if(wfConfig::get('scansEnabled_oldVersions')){ ?><tr><td style="padding-right: 20px;">Scan for Old Software:</td><td style="color: #0F0;">✔</td></tr> <?php } ?>
|
38 |
+
<?php if(wfConfig::get('scansEnabled_options')){ ?><tr><td style="padding-right: 20px;">Scan Options Table:</td><td style="color: #0F0;">✔</td></tr> <?php } ?>
|
39 |
+
<?php if(wfConfig::get('scansEnabled_highSense')){ ?><tr><td style="padding-right: 20px;">High sensitivity scans enabled:</td><td style="color: #0F0;">✔</td></tr> <?php } ?>
|
40 |
+
<?php if(wfConfig::get('scansEnabled_scanImages')){ ?><tr><td style="padding-right: 20px;">Scan image files for executable code:</td><td style="color: #0F0;">✔</td></tr> <?php } ?>
|
41 |
+
<?php if(wfConfig::get('other_scanOutside')){ ?><tr><td style="padding-right: 20px;">Scan files outside WordPress install:</td><td style="color: #0F0;">✔</td></tr> <?php } ?>
|
42 |
+
<?php if(wfConfig::get('scansEnabled_dns')){ ?><tr><td style="padding-right: 20px;">Scan for DNS changes:</td><td style="color: #0F0;">✔</td></tr> <?php } ?>
|
43 |
+
<?php if(wfConfig::get('scansEnabled_diskSpace')){ ?><tr><td style="padding-right: 20px;">Monitor disk space:</td><td style="color: #0F0;">✔</td></tr> <?php } ?>
|
44 |
+
<?php } ?>
|
45 |
+
<?php if(wfConfig::get('debugOn')){ ?><tr><td style="padding-right: 20px;">Wordfence DEBUG mode enabled:</td><td style="color: #F00;">DEBUG ENABLED</td></tr> <?php } ?>
|
46 |
+
|
47 |
+
|
48 |
+
</table>
|
49 |
+
|
lib/menu_options.php
CHANGED
@@ -23,7 +23,7 @@ var WFSLevels = <?php echo json_encode(wfConfig::$securityLevels); ?>;
|
|
23 |
<?php if(wfConfig::get('isPaid')){ ?>
|
24 |
The currently active API Key is a Premium Key. <span style="font-weight: bold; color: #0A0;">Premium scanning enabled!</span>
|
25 |
<?php } else {?>
|
26 |
-
The currently active API Key is a <span style="color: #F00; font-weight: bold;">Free Key</a>. <a href="https://www.wordfence.com/wordfence-signup/" target="_blank">Upgrade to Premium
|
27 |
<?php } ?>
|
28 |
</td></tr>
|
29 |
<tr><td colspan="2">
|
@@ -39,6 +39,10 @@ var WFSLevels = <?php echo json_encode(wfConfig::$securityLevels); ?>;
|
|
39 |
<tr><td colspan="2"> </td></tr>
|
40 |
<tr><th class="wfConfigEnable">Enable Live Traffic View</th><td><input type="checkbox" id="liveTrafficEnabled" class="wfConfigElem" name="liveTrafficEnabled" value="1" <?php $w->cb('liveTrafficEnabled'); ?> onclick="WFAD.reloadConfigPage = true; return true;" /> This option enables live traffic logging.</td></tr>
|
41 |
<tr><td colspan="2"> </td></tr>
|
|
|
|
|
|
|
|
|
42 |
<?php /* <tr><th class="wfConfigEnable">Enable Performance Monitoring</th><td><input type="checkbox" id="perfLoggingEnabled" class="wfConfigElem" name="perfLoggingEnabled" value="1" <?php $w->cb('perfLoggingEnabled'); ?> onclick="WFAD.reloadConfigPage = true; return true;" /> This option enables performance monitoring.</td></tr> */ ?>
|
43 |
<tr><td colspan="2"> </td></tr>
|
44 |
<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'); ?> /> Regular scans ensure your site stays secure.</td></tr>
|
@@ -253,7 +257,7 @@ var WFSLevels = <?php echo json_encode(wfConfig::$securityLevels); ?>;
|
|
253 |
<tr><th colspan="2" style="color: #999;">Whitelisted IP's must be separated by commas. You can specify ranges using the following format: 123.23.34.[1-50]<br />Wordfence automatically whitelists <a href="http://en.wikipedia.org/wiki/Private_network" target="_blank">private networks</a> because these are not routable on the public Internet.<br /><br /></th></tr>
|
254 |
<tr><th>Hide WordPress version</th><td><input type="checkbox" id="other_hideWPVersion" class="wfConfigElem" name="other_hideWPVersion" value="1" <?php $w->cb('other_hideWPVersion'); ?> /></td></tr>
|
255 |
<tr><th>Hold anonymous comments using member emails for moderation</th><td><input type="checkbox" id="other_noAnonMemberComments" class="wfConfigElem" name="other_noAnonMemberComments" value="1" <?php $w->cb('other_noAnonMemberComments'); ?> /></td></tr>
|
256 |
-
<tr><th>
|
257 |
<tr><th>Check password strength on profile update</th><td><input type="checkbox" id="other_pwStrengthOnUpdate" class="wfConfigElem" name="other_pwStrengthOnUpdate" value="1" <?php $w->cb('other_pwStrengthOnUpdate'); ?> /></td></tr>
|
258 |
<tr><th>Participate in the Real-Time WordPress Security Network</th><td><input type="checkbox" id="other_WFNet" class="wfConfigElem" name="other_WFNet" value="1" <?php $w->cb('other_WFNet'); ?> /></td></tr>
|
259 |
<tr><th>Maximum memory Wordfence can use</th><td><input type="text" id="maxMem" name="maxMem" value="<?php $w->f('maxMem'); ?>" size="4" />Megabytes</td></tr>
|
23 |
<?php if(wfConfig::get('isPaid')){ ?>
|
24 |
The currently active API Key is a Premium Key. <span style="font-weight: bold; color: #0A0;">Premium scanning enabled!</span>
|
25 |
<?php } else {?>
|
26 |
+
The currently active API Key is a <span style="color: #F00; font-weight: bold;">Free Key</a>. <a href="https://www.wordfence.com/wordfence-signup/" target="_blank">Click Here to Upgrade to Wordfence Premium now.</a>
|
27 |
<?php } ?>
|
28 |
</td></tr>
|
29 |
<tr><td colspan="2">
|
39 |
<tr><td colspan="2"> </td></tr>
|
40 |
<tr><th class="wfConfigEnable">Enable Live Traffic View</th><td><input type="checkbox" id="liveTrafficEnabled" class="wfConfigElem" name="liveTrafficEnabled" value="1" <?php $w->cb('liveTrafficEnabled'); ?> onclick="WFAD.reloadConfigPage = true; return true;" /> This option enables live traffic logging.</td></tr>
|
41 |
<tr><td colspan="2"> </td></tr>
|
42 |
+
<tr><th class="wfConfigEnable">Advanced Comment Spam Filter</th><td><input type="checkbox" id="advancedCommentScanning" class="wfConfigElem" name="advancedCommentScanning" value="1" <?php $w->cbp('advancedCommentScanning'); if(! wfConfig::get('isPaid')){ ?>onclick="alert('This is a paid feature because it places significant additional load on our servers.'); jQuery('#advancedCommentScanning').attr('checked', false); return false;" <?php } ?> /> <span style="color: #F00;">Premium Feature</span> In addition to free comment filtering (see below) this option filters comments against several additional real-time lists of known spammers and infected hosts.</td></tr>
|
43 |
+
<tr><th class="wfConfigEnable">Check if this website is being "Spamvertised"</th><td><input type="checkbox" id="spamvertizeCheck" class="wfConfigElem" name="spamvertizeCheck" value="1" <?php $w->cbp('spamvertizeCheck'); if(! wfConfig::get('isPaid')){ ?>onclick="alert('This is a paid feature because it places significant additional load on our servers.'); jQuery('#spamvertizeCheck').attr('checked', false); return false;" <?php } ?> /> <span style="color: #F00;">Premium Feature</span> When doing a scan, Wordfence will check with spam services if your site domain name is appearing as a link in spam emails.</td></tr>
|
44 |
+
<tr><th class="wfConfigEnable">Check if this website IP is generating spam</th><td><input type="checkbox" id="checkSpamIP" class="wfConfigElem" name="checkSpamIP" value="1" <?php $w->cbp('checkSpamIP'); if(! wfConfig::get('isPaid')){ ?>onclick="alert('This is a paid feature because it places significant additional load on our servers.'); jQuery('#checkSpamIP').attr('checked', false); return false;" <?php } ?> /> <span style="color: #F00;">Premium Feature</span> When doing a scan, Wordfence will check with spam services if your website IP address is listed as a known source of spam email.</td></tr>
|
45 |
+
<tr><td colspan="2"> </td></tr>
|
46 |
<?php /* <tr><th class="wfConfigEnable">Enable Performance Monitoring</th><td><input type="checkbox" id="perfLoggingEnabled" class="wfConfigElem" name="perfLoggingEnabled" value="1" <?php $w->cb('perfLoggingEnabled'); ?> onclick="WFAD.reloadConfigPage = true; return true;" /> This option enables performance monitoring.</td></tr> */ ?>
|
47 |
<tr><td colspan="2"> </td></tr>
|
48 |
<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'); ?> /> Regular scans ensure your site stays secure.</td></tr>
|
257 |
<tr><th colspan="2" style="color: #999;">Whitelisted IP's must be separated by commas. You can specify ranges using the following format: 123.23.34.[1-50]<br />Wordfence automatically whitelists <a href="http://en.wikipedia.org/wiki/Private_network" target="_blank">private networks</a> because these are not routable on the public Internet.<br /><br /></th></tr>
|
258 |
<tr><th>Hide WordPress version</th><td><input type="checkbox" id="other_hideWPVersion" class="wfConfigElem" name="other_hideWPVersion" value="1" <?php $w->cb('other_hideWPVersion'); ?> /></td></tr>
|
259 |
<tr><th>Hold anonymous comments using member emails for moderation</th><td><input type="checkbox" id="other_noAnonMemberComments" class="wfConfigElem" name="other_noAnonMemberComments" value="1" <?php $w->cb('other_noAnonMemberComments'); ?> /></td></tr>
|
260 |
+
<tr><th>Filter comments for malware and phishing URL's</th><td><input type="checkbox" id="other_scanComments" class="wfConfigElem" name="other_scanComments" value="1" <?php $w->cb('other_scanComments'); ?> /></td></tr>
|
261 |
<tr><th>Check password strength on profile update</th><td><input type="checkbox" id="other_pwStrengthOnUpdate" class="wfConfigElem" name="other_pwStrengthOnUpdate" value="1" <?php $w->cb('other_pwStrengthOnUpdate'); ?> /></td></tr>
|
262 |
<tr><th>Participate in the Real-Time WordPress Security Network</th><td><input type="checkbox" id="other_WFNet" class="wfConfigElem" name="other_WFNet" value="1" <?php $w->cb('other_WFNet'); ?> /></td></tr>
|
263 |
<tr><th>Maximum memory Wordfence can use</th><td><input type="text" id="maxMem" name="maxMem" value="<?php $w->f('maxMem'); ?>" size="4" />Megabytes</td></tr>
|
lib/menu_scan.php
CHANGED
@@ -651,6 +651,67 @@
|
|
651 |
</div>
|
652 |
</div>
|
653 |
</script>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
654 |
|
655 |
|
656 |
|
651 |
</div>
|
652 |
</div>
|
653 |
</script>
|
654 |
+
<script type="text/x-jquery-template" id="issueTmpl_checkSpamIP">
|
655 |
+
<div>
|
656 |
+
<div class="wfIssue">
|
657 |
+
<h2>${shortMsg}</h2>
|
658 |
+
<p>
|
659 |
+
<table border="0" class="wfIssue" cellspacing="0" cellpadding="0">
|
660 |
+
<tr><th>Severity:</th><td>{{if severity == '1'}}Critical{{else}}Warning{{/if}}</td></tr>
|
661 |
+
<tr><th>Status</th><td>
|
662 |
+
{{if status == 'new' }}New{{/if}}
|
663 |
+
{{if status == 'ignoreC' }}This redirect will be ignored until it changes.{{/if}}
|
664 |
+
{{if status == 'ignoreP' }}This redirect is permanently ignored.{{/if}}
|
665 |
+
</td></tr>
|
666 |
+
</table>
|
667 |
+
</p>
|
668 |
+
<p>
|
669 |
+
{{html longMsg}}
|
670 |
+
</p>
|
671 |
+
<div class="wfIssueOptions">
|
672 |
+
{{if status == 'new'}}
|
673 |
+
<strong>Resolve:</strong>
|
674 |
+
<a href="#" onclick="WFAD.updateIssueStatus('${id}', 'delete'); return false;">I have fixed this issue</a>
|
675 |
+
<a href="#" onclick="WFAD.updateIssueStatus('${id}', 'ignoreP'); return false;">Ignore this problem</a>
|
676 |
+
{{/if}}
|
677 |
+
{{if status == 'ignoreP' || status == 'ignoreC'}}
|
678 |
+
<a href="#" onclick="WFAD.updateIssueStatus('${id}', 'delete'); return false;">Stop ignoring this issue</a>
|
679 |
+
{{/if}}
|
680 |
+
</div>
|
681 |
+
</div>
|
682 |
+
</div>
|
683 |
+
</script>
|
684 |
+
|
685 |
+
<script type="text/x-jquery-template" id="issueTmpl_spamvertizeCheck">
|
686 |
+
<div>
|
687 |
+
<div class="wfIssue">
|
688 |
+
<h2>${shortMsg}</h2>
|
689 |
+
<p>
|
690 |
+
<table border="0" class="wfIssue" cellspacing="0" cellpadding="0">
|
691 |
+
<tr><th>Severity:</th><td>{{if severity == '1'}}Critical{{else}}Warning{{/if}}</td></tr>
|
692 |
+
<tr><th>Status</th><td>
|
693 |
+
{{if status == 'new' }}New{{/if}}
|
694 |
+
{{if status == 'ignoreC' }}This redirect will be ignored until it changes.{{/if}}
|
695 |
+
{{if status == 'ignoreP' }}This redirect is permanently ignored.{{/if}}
|
696 |
+
</td></tr>
|
697 |
+
</table>
|
698 |
+
</p>
|
699 |
+
<p>
|
700 |
+
{{html longMsg}}
|
701 |
+
</p>
|
702 |
+
<div class="wfIssueOptions">
|
703 |
+
{{if status == 'new'}}
|
704 |
+
<strong>Resolve:</strong>
|
705 |
+
<a href="#" onclick="WFAD.updateIssueStatus('${id}', 'delete'); return false;">I have fixed this issue</a>
|
706 |
+
<a href="#" onclick="WFAD.updateIssueStatus('${id}', 'ignoreP'); return false;">Ignore this problem</a>
|
707 |
+
{{/if}}
|
708 |
+
{{if status == 'ignoreP' || status == 'ignoreC'}}
|
709 |
+
<a href="#" onclick="WFAD.updateIssueStatus('${id}', 'delete'); return false;">Stop ignoring this issue</a>
|
710 |
+
{{/if}}
|
711 |
+
</div>
|
712 |
+
</div>
|
713 |
+
</div>
|
714 |
+
</script>
|
715 |
|
716 |
|
717 |
|
lib/wfCache.php
CHANGED
@@ -5,6 +5,7 @@ class wfCache {
|
|
5 |
private static $cacheStats = array();
|
6 |
private static $cacheClearedThisRequest = false;
|
7 |
private static $clearScheduledThisRequest = false;
|
|
|
8 |
public static function setupCaching(){
|
9 |
self::$cacheType = wfConfig::get('cacheType');
|
10 |
if(self::$cacheType != 'php' && self::$cacheType != 'falcon'){
|
@@ -67,9 +68,6 @@ class wfCache {
|
|
67 |
return $status;
|
68 |
}
|
69 |
public static function isCachable(){
|
70 |
-
if(function_exists('is_404') && is_404()){
|
71 |
-
return false;
|
72 |
-
}
|
73 |
if(defined('WFDONOTCACHE') || defined('DONOTCACHEPAGE') || defined('DONOTCACHEDB') || defined('DONOTCACHEOBJECT')){ //If you want to tell Wordfence not to cache something in another plugin, simply define one of these.
|
74 |
return false;
|
75 |
}
|
@@ -320,18 +318,32 @@ class wfCache {
|
|
320 |
'dirsDeleted' => 0,
|
321 |
'filesDeleted' => 0,
|
322 |
'totalData' => 0,
|
323 |
-
'totalErrors' => 0
|
|
|
324 |
);
|
325 |
$cacheClearLock = WP_CONTENT_DIR . '/wfcache/clear.lock';
|
326 |
if(! is_file($cacheClearLock)){
|
327 |
-
touch($cacheClearLock)
|
|
|
|
|
|
|
|
|
328 |
}
|
329 |
$fp = fopen($cacheClearLock, 'w');
|
330 |
-
if(! $fp){
|
|
|
|
|
|
|
|
|
331 |
if(flock($fp, LOCK_EX | LOCK_NB)){ //non blocking exclusive flock attempt. If we get a lock then it continues and returns true. If we don't lock, then return false, don't block and don't clear the cache.
|
332 |
// This logic means that if a cache clear is currently in progress we don't try to clear the cache.
|
333 |
// This prevents web server children from being queued up waiting to be able to also clear the cache.
|
|
|
334 |
self::recursiveDelete(WP_CONTENT_DIR . '/wfcache/');
|
|
|
|
|
|
|
|
|
335 |
flock($fp, LOCK_UN);
|
336 |
}
|
337 |
fclose($fp);
|
@@ -342,7 +354,9 @@ class wfCache {
|
|
342 |
$files = array_diff(scandir($dir), array('.','..'));
|
343 |
foreach ($files as $file) {
|
344 |
if(is_dir($dir . '/' . $file)){
|
345 |
-
self::recursiveDelete($dir . '/' . $file)
|
|
|
|
|
346 |
} else {
|
347 |
if($file == 'clear.lock'){ continue; } //Don't delete our lock file
|
348 |
$size = filesize($dir . '/' . $file);
|
@@ -350,29 +364,37 @@ class wfCache {
|
|
350 |
self::$cacheStats['totalData'] += round($size / 1024);
|
351 |
}
|
352 |
if(strpos($dir, 'wfcache/') === false){
|
353 |
-
|
354 |
-
|
|
|
355 |
}
|
356 |
if(@unlink($dir . '/' . $file)){
|
357 |
self::$cacheStats['filesDeleted']++;
|
358 |
} else {
|
|
|
359 |
self::$cacheStats['totalErrors']++;
|
|
|
360 |
}
|
361 |
}
|
362 |
}
|
363 |
if($dir != WP_CONTENT_DIR . '/wfcache/'){
|
364 |
if(strpos($dir, 'wfcache/') === false){
|
365 |
-
|
|
|
366 |
return; //Safety check that we're in a subdir of the cache
|
367 |
}
|
368 |
if(@rmdir($dir)){
|
369 |
self::$cacheStats['dirsDeleted']++;
|
370 |
} else {
|
|
|
371 |
self::$cacheStats['totalErrors']++;
|
|
|
372 |
}
|
|
|
373 |
} else {
|
374 |
return true;
|
375 |
}
|
|
|
376 |
}
|
377 |
public static function addHtaccessCode($action){
|
378 |
if($action != 'add' && $action != 'remove'){
|
5 |
private static $cacheStats = array();
|
6 |
private static $cacheClearedThisRequest = false;
|
7 |
private static $clearScheduledThisRequest = false;
|
8 |
+
private static $lastRecursiveDeleteError = false;
|
9 |
public static function setupCaching(){
|
10 |
self::$cacheType = wfConfig::get('cacheType');
|
11 |
if(self::$cacheType != 'php' && self::$cacheType != 'falcon'){
|
68 |
return $status;
|
69 |
}
|
70 |
public static function isCachable(){
|
|
|
|
|
|
|
71 |
if(defined('WFDONOTCACHE') || defined('DONOTCACHEPAGE') || defined('DONOTCACHEDB') || defined('DONOTCACHEOBJECT')){ //If you want to tell Wordfence not to cache something in another plugin, simply define one of these.
|
72 |
return false;
|
73 |
}
|
318 |
'dirsDeleted' => 0,
|
319 |
'filesDeleted' => 0,
|
320 |
'totalData' => 0,
|
321 |
+
'totalErrors' => 0,
|
322 |
+
'error' => '',
|
323 |
);
|
324 |
$cacheClearLock = WP_CONTENT_DIR . '/wfcache/clear.lock';
|
325 |
if(! is_file($cacheClearLock)){
|
326 |
+
if(! touch($cacheClearLock)){
|
327 |
+
self::$cacheStats['error'] = "Could not create a lock file $cacheClearLock to clear the cache.";
|
328 |
+
self::$cacheStats['totalErrors']++;
|
329 |
+
return self::$cacheStats;
|
330 |
+
}
|
331 |
}
|
332 |
$fp = fopen($cacheClearLock, 'w');
|
333 |
+
if(! $fp){
|
334 |
+
self::$cacheStats['error'] = "Could not open the lock file $cacheClearLock to clear the cache. Please make sure the directory is writable by your web server.";
|
335 |
+
self::$cacheStats['totalErrors']++;
|
336 |
+
return self::$cacheStats;
|
337 |
+
}
|
338 |
if(flock($fp, LOCK_EX | LOCK_NB)){ //non blocking exclusive flock attempt. If we get a lock then it continues and returns true. If we don't lock, then return false, don't block and don't clear the cache.
|
339 |
// This logic means that if a cache clear is currently in progress we don't try to clear the cache.
|
340 |
// This prevents web server children from being queued up waiting to be able to also clear the cache.
|
341 |
+
self::$lastRecursiveDeleteError = false;
|
342 |
self::recursiveDelete(WP_CONTENT_DIR . '/wfcache/');
|
343 |
+
if(self::$lastRecursiveDeleteError){
|
344 |
+
self::$cacheStats['error'] = self::$lastRecursiveDeleteError;
|
345 |
+
self::$cacheStats['totalErrors']++;
|
346 |
+
}
|
347 |
flock($fp, LOCK_UN);
|
348 |
}
|
349 |
fclose($fp);
|
354 |
$files = array_diff(scandir($dir), array('.','..'));
|
355 |
foreach ($files as $file) {
|
356 |
if(is_dir($dir . '/' . $file)){
|
357 |
+
if(! self::recursiveDelete($dir . '/' . $file)){
|
358 |
+
return false;
|
359 |
+
}
|
360 |
} else {
|
361 |
if($file == 'clear.lock'){ continue; } //Don't delete our lock file
|
362 |
$size = filesize($dir . '/' . $file);
|
364 |
self::$cacheStats['totalData'] += round($size / 1024);
|
365 |
}
|
366 |
if(strpos($dir, 'wfcache/') === false){
|
367 |
+
self::$lastRecursiveDeleteError = "Not deleting file in directory $dir because it appears to be in the wrong path.";
|
368 |
+
self::$cacheStats['totalErrors']++;
|
369 |
+
return false; //Safety check that we're in a subdir of the cache
|
370 |
}
|
371 |
if(@unlink($dir . '/' . $file)){
|
372 |
self::$cacheStats['filesDeleted']++;
|
373 |
} else {
|
374 |
+
self::$lastRecursiveDeleteError = "Could not delete file " . $dir . "/" . $file . " : " . wfUtils::getLastError();
|
375 |
self::$cacheStats['totalErrors']++;
|
376 |
+
return false;
|
377 |
}
|
378 |
}
|
379 |
}
|
380 |
if($dir != WP_CONTENT_DIR . '/wfcache/'){
|
381 |
if(strpos($dir, 'wfcache/') === false){
|
382 |
+
self::$lastRecursiveDeleteError = "Not deleting directory $dir because it appears to be in the wrong path.";
|
383 |
+
self::$cacheStats['totalErrors']++;
|
384 |
return; //Safety check that we're in a subdir of the cache
|
385 |
}
|
386 |
if(@rmdir($dir)){
|
387 |
self::$cacheStats['dirsDeleted']++;
|
388 |
} else {
|
389 |
+
self::$lastRecursiveDeleteError = "Could not delete directory $dir : " . wfUtils::getLastError();
|
390 |
self::$cacheStats['totalErrors']++;
|
391 |
+
return false;
|
392 |
}
|
393 |
+
return true;
|
394 |
} else {
|
395 |
return true;
|
396 |
}
|
397 |
+
return true;
|
398 |
}
|
399 |
public static function addHtaccessCode($action){
|
400 |
if($action != 'add' && $action != 'remove'){
|
lib/wfConfig.php
CHANGED
@@ -19,6 +19,9 @@ class wfConfig {
|
|
19 |
"alertOn_adminLogin" => false,
|
20 |
"alertOn_nonAdminLogin" => false,
|
21 |
"liveTrafficEnabled" => true,
|
|
|
|
|
|
|
22 |
"liveTraf_ignorePublishers" => true,
|
23 |
//"perfLoggingEnabled" => false,
|
24 |
"scheduledScansEnabled" => false,
|
@@ -94,6 +97,9 @@ class wfConfig {
|
|
94 |
"alertOn_adminLogin" => true,
|
95 |
"alertOn_nonAdminLogin" => false,
|
96 |
"liveTrafficEnabled" => true,
|
|
|
|
|
|
|
97 |
"liveTraf_ignorePublishers" => true,
|
98 |
//"perfLoggingEnabled" => false,
|
99 |
"scheduledScansEnabled" => true,
|
@@ -169,6 +175,9 @@ class wfConfig {
|
|
169 |
"alertOn_adminLogin" => true,
|
170 |
"alertOn_nonAdminLogin" => false,
|
171 |
"liveTrafficEnabled" => true,
|
|
|
|
|
|
|
172 |
"liveTraf_ignorePublishers" => true,
|
173 |
//"perfLoggingEnabled" => false,
|
174 |
"scheduledScansEnabled" => true,
|
@@ -244,6 +253,9 @@ class wfConfig {
|
|
244 |
"alertOn_adminLogin" => true,
|
245 |
"alertOn_nonAdminLogin" => false,
|
246 |
"liveTrafficEnabled" => true,
|
|
|
|
|
|
|
247 |
"liveTraf_ignorePublishers" => true,
|
248 |
//"perfLoggingEnabled" => false,
|
249 |
"scheduledScansEnabled" => true,
|
@@ -319,6 +331,9 @@ class wfConfig {
|
|
319 |
"alertOn_adminLogin" => true,
|
320 |
"alertOn_nonAdminLogin" => false,
|
321 |
"liveTrafficEnabled" => true,
|
|
|
|
|
|
|
322 |
"liveTraf_ignorePublishers" => true,
|
323 |
//"perfLoggingEnabled" => false,
|
324 |
"scheduledScansEnabled" => true,
|
@@ -435,6 +450,13 @@ class wfConfig {
|
|
435 |
public static function getHTML($key){
|
436 |
return htmlspecialchars(self::get($key));
|
437 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
438 |
public static function set($key, $val){
|
439 |
if(is_array($val)){
|
440 |
$msg = "wfConfig::set() got an array as second param with key: $key and value: " . var_export($val, true);
|
@@ -621,6 +643,11 @@ class wfConfig {
|
|
621 |
public static function f($key){
|
622 |
echo esc_attr(self::get($key));
|
623 |
}
|
|
|
|
|
|
|
|
|
|
|
624 |
public static function cb($key){
|
625 |
if(self::get($key)){
|
626 |
echo ' checked ';
|
19 |
"alertOn_adminLogin" => false,
|
20 |
"alertOn_nonAdminLogin" => false,
|
21 |
"liveTrafficEnabled" => true,
|
22 |
+
"advancedCommentScanning" => false,
|
23 |
+
"checkSpamIP" => false,
|
24 |
+
"spamvertizeCheck" => false,
|
25 |
"liveTraf_ignorePublishers" => true,
|
26 |
//"perfLoggingEnabled" => false,
|
27 |
"scheduledScansEnabled" => false,
|
97 |
"alertOn_adminLogin" => true,
|
98 |
"alertOn_nonAdminLogin" => false,
|
99 |
"liveTrafficEnabled" => true,
|
100 |
+
"advancedCommentScanning" => false,
|
101 |
+
"checkSpamIP" => false,
|
102 |
+
"spamvertizeCheck" => false,
|
103 |
"liveTraf_ignorePublishers" => true,
|
104 |
//"perfLoggingEnabled" => false,
|
105 |
"scheduledScansEnabled" => true,
|
175 |
"alertOn_adminLogin" => true,
|
176 |
"alertOn_nonAdminLogin" => false,
|
177 |
"liveTrafficEnabled" => true,
|
178 |
+
"advancedCommentScanning" => false,
|
179 |
+
"checkSpamIP" => false,
|
180 |
+
"spamvertizeCheck" => false,
|
181 |
"liveTraf_ignorePublishers" => true,
|
182 |
//"perfLoggingEnabled" => false,
|
183 |
"scheduledScansEnabled" => true,
|
253 |
"alertOn_adminLogin" => true,
|
254 |
"alertOn_nonAdminLogin" => false,
|
255 |
"liveTrafficEnabled" => true,
|
256 |
+
"advancedCommentScanning" => false,
|
257 |
+
"checkSpamIP" => false,
|
258 |
+
"spamvertizeCheck" => false,
|
259 |
"liveTraf_ignorePublishers" => true,
|
260 |
//"perfLoggingEnabled" => false,
|
261 |
"scheduledScansEnabled" => true,
|
331 |
"alertOn_adminLogin" => true,
|
332 |
"alertOn_nonAdminLogin" => false,
|
333 |
"liveTrafficEnabled" => true,
|
334 |
+
"advancedCommentScanning" => false,
|
335 |
+
"checkSpamIP" => false,
|
336 |
+
"spamvertizeCheck" => false,
|
337 |
"liveTraf_ignorePublishers" => true,
|
338 |
//"perfLoggingEnabled" => false,
|
339 |
"scheduledScansEnabled" => true,
|
450 |
public static function getHTML($key){
|
451 |
return htmlspecialchars(self::get($key));
|
452 |
}
|
453 |
+
public static function inc($key){
|
454 |
+
$val = self::get($key, false);
|
455 |
+
if(! $val){
|
456 |
+
$val = 0;
|
457 |
+
}
|
458 |
+
self::set($key, $val + 1);
|
459 |
+
}
|
460 |
public static function set($key, $val){
|
461 |
if(is_array($val)){
|
462 |
$msg = "wfConfig::set() got an array as second param with key: $key and value: " . var_export($val, true);
|
643 |
public static function f($key){
|
644 |
echo esc_attr(self::get($key));
|
645 |
}
|
646 |
+
public static function cbp($key){
|
647 |
+
if(self::get('isPaid') && self::get($key)){
|
648 |
+
echo ' checked ';
|
649 |
+
}
|
650 |
+
}
|
651 |
public static function cb($key){
|
652 |
if(self::get($key)){
|
653 |
echo ' checked ';
|
lib/wfLog.php
CHANGED
@@ -55,9 +55,7 @@ class wfLog {
|
|
55 |
if(! $userID){
|
56 |
return;
|
57 |
}
|
58 |
-
}
|
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)),
|
63 |
$fail,
|
@@ -281,6 +279,7 @@ class wfLog {
|
|
281 |
);
|
282 |
}
|
283 |
wfCache::updateBlockedIPs('add');
|
|
|
284 |
return true;
|
285 |
}
|
286 |
public function lockOutIP($IP, $reason){
|
@@ -290,6 +289,7 @@ class wfLog {
|
|
290 |
$reason,
|
291 |
$reason
|
292 |
);
|
|
|
293 |
return true;
|
294 |
}
|
295 |
public function unlockOutIP($IP){
|
@@ -713,6 +713,7 @@ class wfLog {
|
|
713 |
}
|
714 |
} else {
|
715 |
$this->do503(3600, "Access from your area has been temporarily limited for security reasons");
|
|
|
716 |
}
|
717 |
}
|
718 |
}
|
@@ -768,6 +769,7 @@ class wfLog {
|
|
768 |
$IP = wfUtils::getIP();
|
769 |
$this->getDB()->queryWrite("insert into " . $this->throttleTable . " (IP, startTime, endTime, timesThrottled, lastReason) values (%s, unix_timestamp(), unix_timestamp(), 1, '%s') ON DUPLICATE KEY UPDATE endTime=unix_timestamp(), timesThrottled = timesThrottled + 1, lastReason='%s'", wfUtils::inet_aton($IP), $reason, $reason);
|
770 |
wordfence::status(2, 'info', "Throttling IP $IP. $reason");
|
|
|
771 |
$secsToGo = 60;
|
772 |
}
|
773 |
$this->do503($secsToGo, $reason);
|
@@ -776,6 +778,7 @@ class wfLog {
|
|
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');
|
55 |
if(! $userID){
|
56 |
return;
|
57 |
}
|
58 |
+
} //Else userID stays 0 but we do log this even though the user doesn't exist.
|
|
|
|
|
59 |
$this->getDB()->queryWrite("insert into " . $this->loginsTable . " (ctime, fail, action, username, userID, IP, UA) values (%f, %d, '%s', '%s', %s, %s, '%s')",
|
60 |
sprintf('%.6f', microtime(true)),
|
61 |
$fail,
|
279 |
);
|
280 |
}
|
281 |
wfCache::updateBlockedIPs('add');
|
282 |
+
wfConfig::inc('totalIPsBlocked');
|
283 |
return true;
|
284 |
}
|
285 |
public function lockOutIP($IP, $reason){
|
289 |
$reason,
|
290 |
$reason
|
291 |
);
|
292 |
+
wfConfig::inc('totalIPsLocked');
|
293 |
return true;
|
294 |
}
|
295 |
public function unlockOutIP($IP){
|
713 |
}
|
714 |
} else {
|
715 |
$this->do503(3600, "Access from your area has been temporarily limited for security reasons");
|
716 |
+
wfConfig::inc('totalCountryBlocked');
|
717 |
}
|
718 |
}
|
719 |
}
|
769 |
$IP = wfUtils::getIP();
|
770 |
$this->getDB()->queryWrite("insert into " . $this->throttleTable . " (IP, startTime, endTime, timesThrottled, lastReason) values (%s, unix_timestamp(), unix_timestamp(), 1, '%s') ON DUPLICATE KEY UPDATE endTime=unix_timestamp(), timesThrottled = timesThrottled + 1, lastReason='%s'", wfUtils::inet_aton($IP), $reason, $reason);
|
771 |
wordfence::status(2, 'info', "Throttling IP $IP. $reason");
|
772 |
+
wfConfig::inc('totalIPsThrottled');
|
773 |
$secsToGo = 60;
|
774 |
}
|
775 |
$this->do503($secsToGo, $reason);
|
778 |
}
|
779 |
}
|
780 |
public function do503($secsToGo, $reason){
|
781 |
+
wfConfig::inc('total503s');
|
782 |
wfUtils::doNotCache();
|
783 |
header('HTTP/1.1 503 Service Temporarily Unavailable');
|
784 |
header('Status: 503 Service Temporarily Unavailable');
|
lib/wfScanEngine.php
CHANGED
@@ -49,6 +49,8 @@ class wfScanEngine {
|
|
49 |
include('wfDict.php'); //$dictWords
|
50 |
$this->dictWords = $dictWords;
|
51 |
$this->jobList[] = 'publicSite';
|
|
|
|
|
52 |
$this->jobList[] = 'heartbleed';
|
53 |
$this->jobList[] = 'knownFiles_init';
|
54 |
$this->jobList[] = 'knownFiles_main';
|
@@ -173,6 +175,54 @@ class wfScanEngine {
|
|
173 |
sleep(2); //enough time to read the message before it scrolls off.
|
174 |
}
|
175 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
176 |
private function scan_knownFiles_init(){
|
177 |
$this->status(1, 'info', "Contacting Wordfence to initiate scan");
|
178 |
$this->api->call('log_scan', array(), array());
|
@@ -887,6 +937,7 @@ class wfScanEngine {
|
|
887 |
}
|
888 |
public static function startScan($isFork = false){
|
889 |
if(! $isFork){ //beginning of scan
|
|
|
890 |
wfConfig::set('wfKillRequested', 0);
|
891 |
wordfence::status(4, 'info', "Entering start scan routine");
|
892 |
if(wfUtils::isScanRunning()){
|
49 |
include('wfDict.php'); //$dictWords
|
50 |
$this->dictWords = $dictWords;
|
51 |
$this->jobList[] = 'publicSite';
|
52 |
+
$this->jobList[] = 'checkSpamvertized';
|
53 |
+
$this->jobList[] = 'checkSpamIP';
|
54 |
$this->jobList[] = 'heartbleed';
|
55 |
$this->jobList[] = 'knownFiles_init';
|
56 |
$this->jobList[] = 'knownFiles_main';
|
175 |
sleep(2); //enough time to read the message before it scrolls off.
|
176 |
}
|
177 |
}
|
178 |
+
private function scan_checkSpamIP(){
|
179 |
+
if(wfConfig::get('isPaid')){
|
180 |
+
if(wfConfig::get('checkSpamIP')){
|
181 |
+
$this->statusIDX['checkSpamIP'] = wordfence::statusStart("Checking if your site IP is generating spam");
|
182 |
+
$result = $this->api->call('check_spam_ip', array(), array(
|
183 |
+
'siteURL' => site_url()
|
184 |
+
));
|
185 |
+
$haveIssues = false;
|
186 |
+
if($result['haveIssues'] && is_array($result['issues']) ){
|
187 |
+
foreach($result['issues'] as $issue){
|
188 |
+
$this->addIssue($issue['type'], $issue['level'], $issue['ignoreP'], $issue['ignoreC'], $issue['shortMsg'], $issue['longMsg'], $issue['data']);
|
189 |
+
$haveIssues = true;
|
190 |
+
}
|
191 |
+
}
|
192 |
+
wordfence::statusEnd($this->statusIDX['checkSpamIP'], $haveIssues);
|
193 |
+
} else {
|
194 |
+
wordfence::statusDisabled("Skipping check if your IP is generating spam");
|
195 |
+
}
|
196 |
+
|
197 |
+
} else {
|
198 |
+
wordfence::statusPaidOnly("Checking if your IP is generating spam is for paid members only");
|
199 |
+
sleep(2);
|
200 |
+
}
|
201 |
+
}
|
202 |
+
private function scan_checkSpamvertized(){
|
203 |
+
if(wfConfig::get('isPaid')){
|
204 |
+
if(wfConfig::get('spamvertizeCheck')){
|
205 |
+
$this->statusIDX['spamvertizeCheck'] = wordfence::statusStart("Checking if your site is being Spamvertised");
|
206 |
+
$result = $this->api->call('spamvertize_check', array(), array(
|
207 |
+
'siteURL' => site_url()
|
208 |
+
));
|
209 |
+
$haveIssues = false;
|
210 |
+
if($result['haveIssues'] && is_array($result['issues']) ){
|
211 |
+
foreach($result['issues'] as $issue){
|
212 |
+
$this->addIssue($issue['type'], $issue['level'], $issue['ignoreP'], $issue['ignoreC'], $issue['shortMsg'], $issue['longMsg'], $issue['data']);
|
213 |
+
$haveIssues = true;
|
214 |
+
}
|
215 |
+
}
|
216 |
+
wordfence::statusEnd($this->statusIDX['spamvertizeCheck'], $haveIssues);
|
217 |
+
} else {
|
218 |
+
wordfence::statusDisabled("Skipping check if your site is being spamvertized");
|
219 |
+
}
|
220 |
+
|
221 |
+
} else {
|
222 |
+
wordfence::statusPaidOnly("Check if your site is being Spamvertized is for paid members only");
|
223 |
+
sleep(2);
|
224 |
+
}
|
225 |
+
}
|
226 |
private function scan_knownFiles_init(){
|
227 |
$this->status(1, 'info', "Contacting Wordfence to initiate scan");
|
228 |
$this->api->call('log_scan', array(), array());
|
937 |
}
|
938 |
public static function startScan($isFork = false){
|
939 |
if(! $isFork){ //beginning of scan
|
940 |
+
wfConfig::inc('totalScansRun');
|
941 |
wfConfig::set('wfKillRequested', 0);
|
942 |
wordfence::status(4, 'info', "Entering start scan routine");
|
943 |
if(wfUtils::isScanRunning()){
|
lib/wfUtils.php
CHANGED
@@ -321,14 +321,26 @@ class wfUtils {
|
|
321 |
self::iniSet('memory_limit', $maxMem . 'M');
|
322 |
}
|
323 |
}
|
324 |
-
public static function isAdmin(){
|
325 |
-
if(
|
326 |
-
if(
|
327 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
328 |
}
|
329 |
} else {
|
330 |
-
if(
|
331 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
332 |
}
|
333 |
}
|
334 |
return false;
|
@@ -415,6 +427,10 @@ class wfUtils {
|
|
415 |
$db->queryWrite("insert IGNORE into " . $locsTable . " (IP, ctime, failed) values (%s, unix_timestamp(), 1)", ($isInt ? $IP : self::inet_aton($IP)) );
|
416 |
$IPLocs[$IP] = false;
|
417 |
} else {
|
|
|
|
|
|
|
|
|
418 |
$db->queryWrite("insert IGNORE into " . $locsTable . " (IP, ctime, failed, city, region, countryName, countryCode, lat, lon) values (%s, unix_timestamp(), 0, '%s', '%s', '%s', '%s', %s, %s)",
|
419 |
($isInt ? $IP : self::inet_aton($IP)),
|
420 |
$value[3], //city
|
@@ -544,6 +560,9 @@ class wfUtils {
|
|
544 |
public static function localHumanDate(){
|
545 |
return date('l jS \of F Y \a\t h:i:s A', time() + (3600 * get_option('gmt_offset')));
|
546 |
}
|
|
|
|
|
|
|
547 |
public static function funcEnabled($func){
|
548 |
if(! function_exists($func)){ return false; }
|
549 |
$disabled = explode(',', ini_get('disable_functions'));
|
@@ -600,6 +619,13 @@ class wfUtils {
|
|
600 |
return true;
|
601 |
}
|
602 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
603 |
}
|
604 |
|
605 |
|
321 |
self::iniSet('memory_limit', $maxMem . 'M');
|
322 |
}
|
323 |
}
|
324 |
+
public static function isAdmin($user = false){
|
325 |
+
if($user){
|
326 |
+
if(is_multisite()){
|
327 |
+
if(user_can($user, 'manage_network')){
|
328 |
+
return true;
|
329 |
+
}
|
330 |
+
} else {
|
331 |
+
if(user_can($user, 'manage_options')){
|
332 |
+
return true;
|
333 |
+
}
|
334 |
}
|
335 |
} else {
|
336 |
+
if(is_multisite()){
|
337 |
+
if(current_user_can('manage_network')){
|
338 |
+
return true;
|
339 |
+
}
|
340 |
+
} else {
|
341 |
+
if(current_user_can('manage_options')){
|
342 |
+
return true;
|
343 |
+
}
|
344 |
}
|
345 |
}
|
346 |
return false;
|
427 |
$db->queryWrite("insert IGNORE into " . $locsTable . " (IP, ctime, failed) values (%s, unix_timestamp(), 1)", ($isInt ? $IP : self::inet_aton($IP)) );
|
428 |
$IPLocs[$IP] = false;
|
429 |
} else {
|
430 |
+
for($i = 0; $i <= 5; $i++){
|
431 |
+
//Prevent warnings in debug mode about uninitialized values
|
432 |
+
if(! isset($value[$i])){ $value[$i] = ''; }
|
433 |
+
}
|
434 |
$db->queryWrite("insert IGNORE into " . $locsTable . " (IP, ctime, failed, city, region, countryName, countryCode, lat, lon) values (%s, unix_timestamp(), 0, '%s', '%s', '%s', '%s', %s, %s)",
|
435 |
($isInt ? $IP : self::inet_aton($IP)),
|
436 |
$value[3], //city
|
560 |
public static function localHumanDate(){
|
561 |
return date('l jS \of F Y \a\t h:i:s A', time() + (3600 * get_option('gmt_offset')));
|
562 |
}
|
563 |
+
public static function localHumanDateShort(){
|
564 |
+
return date('D jS F \@ h:i:sA', time() + (3600 * get_option('gmt_offset')));
|
565 |
+
}
|
566 |
public static function funcEnabled($func){
|
567 |
if(! function_exists($func)){ return false; }
|
568 |
$disabled = explode(',', ini_get('disable_functions'));
|
619 |
return true;
|
620 |
}
|
621 |
}
|
622 |
+
public static function getLastError(){
|
623 |
+
$err = error_get_last();
|
624 |
+
if(is_array($err)){
|
625 |
+
return $err['message'];
|
626 |
+
}
|
627 |
+
return '';
|
628 |
+
}
|
629 |
}
|
630 |
|
631 |
|
lib/wordfenceClass.php
CHANGED
@@ -28,6 +28,7 @@ class wordfence {
|
|
28 |
private static $statusStartMsgs = array();
|
29 |
private static $debugOn = null;
|
30 |
private static $runInstallCalled = false;
|
|
|
31 |
public static function installPlugin(){
|
32 |
self::runInstall();
|
33 |
//Used by MU code below
|
@@ -125,7 +126,7 @@ class wordfence {
|
|
125 |
}
|
126 |
}
|
127 |
}
|
128 |
-
private function keyAlert($msg){
|
129 |
self::alert($msg, $msg . " To ensure uninterrupted Premium Wordfence protection on your site,\nplease renew your API key by visiting http://www.wordfence.com/ Sign in, go to your dashboard,\nselect the key about to expire and click the button to renew that API key.", false);
|
130 |
}
|
131 |
public static function dailyCron(){
|
@@ -349,6 +350,10 @@ class wordfence {
|
|
349 |
add_action('wp_ajax_wordfence_logHuman', 'wordfence::ajax_logHuman_callback');
|
350 |
add_action('wp_ajax_wordfence_doScan', 'wordfence::ajax_doScan_callback');
|
351 |
add_action('wp_ajax_wordfence_testAjax', 'wordfence::ajax_testAjax_callback');
|
|
|
|
|
|
|
|
|
352 |
}
|
353 |
|
354 |
|
@@ -417,6 +422,14 @@ class wordfence {
|
|
417 |
return $schedules;
|
418 |
}
|
419 |
*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
420 |
public static function jetpackMobileSetup(){
|
421 |
define('WFDONOTCACHE', true); //Don't cache jetpack mobile theme pages.
|
422 |
}
|
@@ -704,9 +717,21 @@ class wordfence {
|
|
704 |
public static function loginAction($username){
|
705 |
if(sizeof($_POST) < 1){ return; } //only execute if login form is posted
|
706 |
if(! $username){ return; }
|
|
|
707 |
$user = get_user_by('login', $username);
|
708 |
$userID = $user ? $user->ID : 0;
|
709 |
self::getLog()->logLogin('loginOK', 0, $username);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
710 |
if(user_can($userID, 'update_core')){
|
711 |
if(wfConfig::get('alertOn_adminLogin')){
|
712 |
wordfence::alert("Admin Login", "A user with username \"$username\" who has administrator access signed in to your WordPress site.", wfUtils::getIP());
|
@@ -724,6 +749,7 @@ class wordfence {
|
|
724 |
return $errors;
|
725 |
}
|
726 |
public static function authenticateFilter($authResult){
|
|
|
727 |
$IP = wfUtils::getIP();
|
728 |
$secEnabled = wfConfig::get('loginSecurityEnabled');
|
729 |
if($secEnabled && (! self::getLog()->isWhitelisted($IP)) && wfConfig::get('isPaid') ){
|
@@ -865,7 +891,9 @@ class wordfence {
|
|
865 |
public static function logoutAction(){
|
866 |
$userID = get_current_user_id();
|
867 |
$userDat = get_user_by('id', $userID);
|
868 |
-
|
|
|
|
|
869 |
}
|
870 |
public static function loginInitAction(){
|
871 |
if(self::isLockedOut(wfUtils::getIP())){
|
@@ -1443,6 +1471,10 @@ class wordfence {
|
|
1443 |
}
|
1444 |
public static function ajax_clearPageCache_callback(){
|
1445 |
$stats = wfCache::clearPageCache();
|
|
|
|
|
|
|
|
|
1446 |
$body = "A total of " . $stats['filesDeleted'] . ' files were deleted and ' . $stats['dirsDeleted'] . ' directories were removed. We cleared a total of ' . $stats['totalData'] . 'KB of data in the cache.';
|
1447 |
if($stats['totalErrors'] > 0){
|
1448 |
$body .= ' A total of ' . $stats['totalErrors'] . ' errors were encountered. This probably means that we could not remove some of the files or directories in the cache. Please use your CPanel or file manager to remove the rest of the files in the directory: ' . WP_CONTENT_DIR . '/wfcache/';
|
@@ -2513,10 +2545,19 @@ EOL;
|
|
2513 |
return $gen;
|
2514 |
}
|
2515 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2516 |
public static function preCommentApprovedFilter($approved, $cData){
|
2517 |
if( $approved == 1 && (! is_user_logged_in()) && wfConfig::get('other_noAnonMemberComments') ){
|
2518 |
$user = get_user_by('email', trim($cData['comment_author_email']));
|
2519 |
if($user){
|
|
|
2520 |
return 0; //hold for moderation if the user is not signed in but used a members email
|
2521 |
}
|
2522 |
}
|
@@ -2525,12 +2566,43 @@ EOL;
|
|
2525 |
$wf = new wfScanEngine();
|
2526 |
try {
|
2527 |
if($wf->isBadComment($cData['comment_author'], $cData['comment_author_email'], $cData['comment_author_url'], $cData['comment_author_IP'], $cData['comment_content'])){
|
|
|
2528 |
return 'spam';
|
2529 |
}
|
2530 |
} catch(Exception $e){
|
2531 |
//This will most likely be an API exception because we can't contact the API, so we ignore it and let the normal comment mechanisms run.
|
2532 |
}
|
2533 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2534 |
return $approved;
|
2535 |
}
|
2536 |
public static function getMyHomeURL(){
|
@@ -2541,6 +2613,7 @@ EOL;
|
|
2541 |
}
|
2542 |
|
2543 |
public static function alert($subject, $alertMsg, $IP){
|
|
|
2544 |
$emails = wfConfig::getAlertEmails();
|
2545 |
if(sizeof($emails) < 1){ return; }
|
2546 |
|
28 |
private static $statusStartMsgs = array();
|
29 |
private static $debugOn = null;
|
30 |
private static $runInstallCalled = false;
|
31 |
+
public static $commentSpamItems = array();
|
32 |
public static function installPlugin(){
|
33 |
self::runInstall();
|
34 |
//Used by MU code below
|
126 |
}
|
127 |
}
|
128 |
}
|
129 |
+
private static function keyAlert($msg){
|
130 |
self::alert($msg, $msg . " To ensure uninterrupted Premium Wordfence protection on your site,\nplease renew your API key by visiting http://www.wordfence.com/ Sign in, go to your dashboard,\nselect the key about to expire and click the button to renew that API key.", false);
|
131 |
}
|
132 |
public static function dailyCron(){
|
350 |
add_action('wp_ajax_wordfence_logHuman', 'wordfence::ajax_logHuman_callback');
|
351 |
add_action('wp_ajax_wordfence_doScan', 'wordfence::ajax_doScan_callback');
|
352 |
add_action('wp_ajax_wordfence_testAjax', 'wordfence::ajax_testAjax_callback');
|
353 |
+
/*
|
354 |
+
add_action('wp_dashboard_setup', 'wordfence::addDashboardWidget');
|
355 |
+
*/
|
356 |
+
|
357 |
}
|
358 |
|
359 |
|
422 |
return $schedules;
|
423 |
}
|
424 |
*/
|
425 |
+
/*
|
426 |
+
public static function addDashboardWidget(){
|
427 |
+
wp_add_dashboard_widget('wordfenceDashboardWidget', 'Wordfence Security Status', 'wordfence::displayDashboardWidget');
|
428 |
+
}
|
429 |
+
public static function displayDashboardWidget(){
|
430 |
+
require('dashboard.php');
|
431 |
+
}
|
432 |
+
*/
|
433 |
public static function jetpackMobileSetup(){
|
434 |
define('WFDONOTCACHE', true); //Don't cache jetpack mobile theme pages.
|
435 |
}
|
717 |
public static function loginAction($username){
|
718 |
if(sizeof($_POST) < 1){ return; } //only execute if login form is posted
|
719 |
if(! $username){ return; }
|
720 |
+
wfConfig::inc('totalLogins');
|
721 |
$user = get_user_by('login', $username);
|
722 |
$userID = $user ? $user->ID : 0;
|
723 |
self::getLog()->logLogin('loginOK', 0, $username);
|
724 |
+
if(wfUtils::isAdmin($user)){
|
725 |
+
wfConfig::set_ser('lastAdminLogin', array(
|
726 |
+
'userID' => $userID,
|
727 |
+
'username' => $username,
|
728 |
+
'firstName' => $user->first_name,
|
729 |
+
'lastName' => $user->last_name,
|
730 |
+
'time' => wfUtils::localHumanDateShort(),
|
731 |
+
'IP' => wfUtils::getIP()
|
732 |
+
));
|
733 |
+
}
|
734 |
+
|
735 |
if(user_can($userID, 'update_core')){
|
736 |
if(wfConfig::get('alertOn_adminLogin')){
|
737 |
wordfence::alert("Admin Login", "A user with username \"$username\" who has administrator access signed in to your WordPress site.", wfUtils::getIP());
|
749 |
return $errors;
|
750 |
}
|
751 |
public static function authenticateFilter($authResult){
|
752 |
+
wfConfig::inc('totalLoginHits'); //The total hits to wp-login.php including logins, logouts and just hits.
|
753 |
$IP = wfUtils::getIP();
|
754 |
$secEnabled = wfConfig::get('loginSecurityEnabled');
|
755 |
if($secEnabled && (! self::getLog()->isWhitelisted($IP)) && wfConfig::get('isPaid') ){
|
891 |
public static function logoutAction(){
|
892 |
$userID = get_current_user_id();
|
893 |
$userDat = get_user_by('id', $userID);
|
894 |
+
if(is_object($userDat)){
|
895 |
+
self::getLog()->logLogin('logout', 0, $userDat->user_login);
|
896 |
+
}
|
897 |
}
|
898 |
public static function loginInitAction(){
|
899 |
if(self::isLockedOut(wfUtils::getIP())){
|
1471 |
}
|
1472 |
public static function ajax_clearPageCache_callback(){
|
1473 |
$stats = wfCache::clearPageCache();
|
1474 |
+
if($stats['error']){
|
1475 |
+
$body = "A total of " . $stats['totalErrors'] . " errors occurred while trying to clear your cache. The last error was: " . $stats['error'];
|
1476 |
+
return array('ok' => 1, 'heading' => 'Error occurred while clearing cache', 'body' => $body );
|
1477 |
+
}
|
1478 |
$body = "A total of " . $stats['filesDeleted'] . ' files were deleted and ' . $stats['dirsDeleted'] . ' directories were removed. We cleared a total of ' . $stats['totalData'] . 'KB of data in the cache.';
|
1479 |
if($stats['totalErrors'] > 0){
|
1480 |
$body .= ' A total of ' . $stats['totalErrors'] . ' errors were encountered. This probably means that we could not remove some of the files or directories in the cache. Please use your CPanel or file manager to remove the rest of the files in the directory: ' . WP_CONTENT_DIR . '/wfcache/';
|
2545 |
return $gen;
|
2546 |
}
|
2547 |
}
|
2548 |
+
public static function pushCommentSpamIP($m){
|
2549 |
+
if(wfUtils::isValidIP($m[1]) && strpos($m[1], '127.0.0') !== 0 ){
|
2550 |
+
self::$commentSpamItems[] = trim($m[1]);
|
2551 |
+
}
|
2552 |
+
}
|
2553 |
+
public static function pushCommentSpamHost($m){
|
2554 |
+
self::$commentSpamItems[] = trim($m[1]);
|
2555 |
+
}
|
2556 |
public static function preCommentApprovedFilter($approved, $cData){
|
2557 |
if( $approved == 1 && (! is_user_logged_in()) && wfConfig::get('other_noAnonMemberComments') ){
|
2558 |
$user = get_user_by('email', trim($cData['comment_author_email']));
|
2559 |
if($user){
|
2560 |
+
wfConfig::inc('totalSpamStopped');
|
2561 |
return 0; //hold for moderation if the user is not signed in but used a members email
|
2562 |
}
|
2563 |
}
|
2566 |
$wf = new wfScanEngine();
|
2567 |
try {
|
2568 |
if($wf->isBadComment($cData['comment_author'], $cData['comment_author_email'], $cData['comment_author_url'], $cData['comment_author_IP'], $cData['comment_content'])){
|
2569 |
+
wfConfig::inc('totalSpamStopped');
|
2570 |
return 'spam';
|
2571 |
}
|
2572 |
} catch(Exception $e){
|
2573 |
//This will most likely be an API exception because we can't contact the API, so we ignore it and let the normal comment mechanisms run.
|
2574 |
}
|
2575 |
}
|
2576 |
+
if(wfConfig::get('isPaid') && ($approved == 1 || $approved == 0) && wfConfig::get('advancedCommentScanning')){
|
2577 |
+
$IPs = array();
|
2578 |
+
$hosts = array();
|
2579 |
+
self::$commentSpamItems = array();
|
2580 |
+
preg_replace_callback('/(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/', 'wordfence::pushCommentSpamIP', $cData['comment_content']);
|
2581 |
+
$IPs = self::$commentSpamItems;
|
2582 |
+
self::$commentSpamItems = array();
|
2583 |
+
preg_replace_callback('/https?:\/\/([a-zA-Z0-9\-]+\.[a-zA-Z0-9\-\.]+[a-zA-Z0-9])/i', 'wordfence::pushCommentSpamHost', $cData['comment_content']);
|
2584 |
+
$hosts = self::$commentSpamItems;
|
2585 |
+
self::$commentSpamItems = array();
|
2586 |
+
try {
|
2587 |
+
$api = new wfAPI(wfConfig::get('apiKey'), wfUtils::getWPVersion());
|
2588 |
+
$res = $api->call('advanced_comment_scan', array(), array(
|
2589 |
+
'author' => $cData['comment_author'],
|
2590 |
+
'email' => $cData['comment_author_email'],
|
2591 |
+
'URL' => $cData['comment_author_url'],
|
2592 |
+
'commentIP' => $cData['comment_author_IP'],
|
2593 |
+
'wfIP' => wfUtils::getIP(),
|
2594 |
+
'hosts' => (sizeof($hosts) > 0 ? implode(',', $hosts) : ''),
|
2595 |
+
'IPs' => (sizeof($IPs) > 0 ? implode(',', $IPs) : '')
|
2596 |
+
));
|
2597 |
+
if(is_array($res) && isset($res['spam']) && $res['spam'] == 1){
|
2598 |
+
wfConfig::inc('totalSpamStopped');
|
2599 |
+
return 'spam';
|
2600 |
+
}
|
2601 |
+
} catch(Exception $e){
|
2602 |
+
//API server is probably down
|
2603 |
+
}
|
2604 |
+
}
|
2605 |
+
wfConfig::inc('totalCommentsFiltered');
|
2606 |
return $approved;
|
2607 |
}
|
2608 |
public static function getMyHomeURL(){
|
2613 |
}
|
2614 |
|
2615 |
public static function alert($subject, $alertMsg, $IP){
|
2616 |
+
wfConfig::inc('totalAlertsSent');
|
2617 |
$emails = wfConfig::getAlertEmails();
|
2618 |
if(sizeof($emails) < 1){ return; }
|
2619 |
|
lib/wordfenceConstants.php
CHANGED
@@ -1,5 +1,5 @@
|
|
1 |
<?php
|
2 |
-
define('WORDFENCE_API_VERSION', '2.
|
3 |
define('WORDFENCE_API_URL_SEC', 'https://noc1.wordfence.com/');
|
4 |
define('WORDFENCE_API_URL_NONSEC', 'http://noc1.wordfence.com/');
|
5 |
define('WORDFENCE_MAX_SCAN_TIME', 86400); //Increased this from 10 mins to 1 day because very big scans run for a long time. Users can use kill.
|
1 |
<?php
|
2 |
+
define('WORDFENCE_API_VERSION', '2.11');
|
3 |
define('WORDFENCE_API_URL_SEC', 'https://noc1.wordfence.com/');
|
4 |
define('WORDFENCE_API_URL_NONSEC', 'http://noc1.wordfence.com/');
|
5 |
define('WORDFENCE_MAX_SCAN_TIME', 86400); //Increased this from 10 mins to 1 day because very big scans run for a long time. Users can use kill.
|
readme.txt
CHANGED
@@ -3,7 +3,7 @@ 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 |
|
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,9 +162,20 @@ cause a security hole on your site.
|
|
162 |
|
163 |
== Changelog ==
|
164 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
165 |
= 5.0.8 =
|
166 |
* Feature: Support for Jetpack Mobile Theme in Falcon Caching engine. Regular pages are cached, mobile pages are served direct to browser.
|
167 |
-
* Improvement: Pages that are less than 1000 bytes will not be cached. The avg web page size in 2014 is 1246,000 bytes. Anything less than 1000 bytes is
|
168 |
* Improvement: Wordfence will now request 128M on hosts instead of 64M where memory in php.ini is set too low.
|
169 |
* Fix: Wordfence was caching 404's under certain conditions. Fixed.
|
170 |
* Fix: Nginx/FastCGI users would sometimes receive an error about not being able to edit .htaccess. Fixed.
|
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.9
|
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.9 =
|
166 |
+
* Feature: (Premium) Advanced Comment Spam Filter. Checks comment source IP, author URL and hosts and IP's in body against additional spam lists.
|
167 |
+
* Feature: (Premium) Check if your site is being Spamvertised i.e. your domain is being included in spam emails. Usually indicates you've been hacked.
|
168 |
+
* Feature: (Premium) Check if your website IP is generating spam. Checks against spam lists if your IP is a known source of spam.
|
169 |
+
* Improvement: Cache clearing errors are nown shown with clear explanations.
|
170 |
+
* Improvement: Added lightweight stats logging internally in preparation for displaying them on the admin UI in the next release.
|
171 |
+
* Fix: If a non-existent user tries to sign in it is not logged in the live logins tab. Fixed.
|
172 |
+
* Fix: Removed warning "Trying to get property of non-object" that would occur under certain conditions.
|
173 |
+
* Fix: Removed call to is_404() which was not having any effect and would issue a warning if debug mode is enabled.
|
174 |
+
* Fix: Check if CURL is installed as part of connectivity test.
|
175 |
+
|
176 |
= 5.0.8 =
|
177 |
* Feature: Support for Jetpack Mobile Theme in Falcon Caching engine. Regular pages are cached, mobile pages are served direct to browser.
|
178 |
+
* Improvement: Pages that are less than 1000 bytes will not be cached. The avg web page size in 2014 is 1246,000 bytes. Anything less than 1000 bytes is usually an error.
|
179 |
* Improvement: Wordfence will now request 128M on hosts instead of 64M where memory in php.ini is set too low.
|
180 |
* Fix: Wordfence was caching 404's under certain conditions. Fixed.
|
181 |
* Fix: Nginx/FastCGI users would sometimes receive an error about not being able to edit .htaccess. Fixed.
|
wordfence.php
CHANGED
@@ -4,13 +4,13 @@ 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.
|
8 |
Author URI: http://www.wordfence.com/
|
9 |
*/
|
10 |
if(defined('WP_INSTALLING') && WP_INSTALLING){
|
11 |
return;
|
12 |
}
|
13 |
-
define('WORDFENCE_VERSION', '5.0.
|
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 |
}
|
4 |
Plugin URI: http://www.wordfence.com/
|
5 |
Description: Wordfence Security - Anti-virus, Firewall and Site Speedup
|
6 |
Author: Wordfence
|
7 |
+
Version: 5.0.9
|
8 |
Author URI: http://www.wordfence.com/
|
9 |
*/
|
10 |
if(defined('WP_INSTALLING') && WP_INSTALLING){
|
11 |
return;
|
12 |
}
|
13 |
+
define('WORDFENCE_VERSION', '5.0.9');
|
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 |
}
|