Wordfence Security – Firewall & Malware Scan - Version 1.5.5

Version Description

  • Added ability for admin's to unlock login and unblock their IP addresses if they're accidentally locked out by the firewall or login security. Uses two security tokens to prevent abuse.
  • Admins can now also disable firewall and login security from the unlock-me email, just in case of emergency.
  • Made advanced options visible so you know they exist.
  • Fixed dns_get_record() function not existing bug on Windows sytems pre PHP 5.3.0. Was causing scans to hang.
  • Increased login lockout defaults to be much higher which still protects against brute force hacks.
  • Removed CURLOPT_MAXREDIRS in curl to avoid safe mode warnings.
  • Fixed ability to view and diff files on blogs installed in subdirectories.
  • Fixed ability to see individual IP hits on subdir sites.
  • Plugin and theme update messages now include links to the upgrade page.
  • Removed the link on the login form that mentions the site is protected by Wordfence.
  • Changed lockout defaults to be much higher.
  • Added options for higher number of failures before lockout in options page.
  • Now including plugin version in the activity log when the admin chooses to email it to us for debugging.
Download this release

Release Info

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

Code changes from version 1.5.4 to 1.5.5

css/main.css CHANGED
@@ -206,3 +206,15 @@ table th.wfSubheading { font-weight: bold; padding-top: 10px; }
206
  background-image: url(../images/icons/arrow_refresh.png);
207
  }
208
  #wfActivity { position: relative; }
 
 
 
 
 
 
 
 
 
 
 
 
206
  background-image: url(../images/icons/arrow_refresh.png);
207
  }
208
  #wfActivity { position: relative; }
209
+ h3.wfConfigHeading {
210
+ font-size: 22px;
211
+ color: #777;
212
+ font-family: Georgia;
213
+ font-style: italic;
214
+ font-weight: normal
215
+ }
216
+ .wfTipText {
217
+ color: #777;
218
+ font-family: Georgia;
219
+ font-style: italic;
220
+ }
js/admin.js CHANGED
@@ -549,16 +549,19 @@ window['wordfenceAdmin'] = {
549
  return str.charAt(0).toUpperCase() + str.slice(1);
550
  },
551
  makeIPTrafLink: function(IP){
552
- return '/?_wfsf=IPTraf&nonce=' + this.nonce + '&IP=' + encodeURIComponent(IP);
553
  },
554
  makeDiffLink: function(dat){
555
- return '/?_wfsf=diff&nonce=' + this.nonce +
556
  '&file=' + encodeURIComponent(this.es(dat['file'])) +
557
  '&cType=' + encodeURIComponent(this.es(dat['cType'])) +
558
  '&cKey=' + encodeURIComponent(this.es(dat['cKey'])) +
559
  '&cName=' + encodeURIComponent(this.es(dat['cName'])) +
560
  '&cVersion=' + encodeURIComponent(this.es(dat['cVersion']));
561
  },
 
 
 
562
  makeTimeAgo: function(t){
563
  var months = Math.floor(t / (86400 * 30));
564
  var days = Math.floor(t / 86400);
549
  return str.charAt(0).toUpperCase() + str.slice(1);
550
  },
551
  makeIPTrafLink: function(IP){
552
+ return WordfenceAdminVars.siteBaseURL + '?_wfsf=IPTraf&nonce=' + this.nonce + '&IP=' + encodeURIComponent(IP);
553
  },
554
  makeDiffLink: function(dat){
555
+ return WordfenceAdminVars.siteBaseURL + '?_wfsf=diff&nonce=' + this.nonce +
556
  '&file=' + encodeURIComponent(this.es(dat['file'])) +
557
  '&cType=' + encodeURIComponent(this.es(dat['cType'])) +
558
  '&cKey=' + encodeURIComponent(this.es(dat['cKey'])) +
559
  '&cName=' + encodeURIComponent(this.es(dat['cName'])) +
560
  '&cVersion=' + encodeURIComponent(this.es(dat['cVersion']));
561
  },
562
+ makeViewFileLink: function(file){
563
+ return WordfenceAdminVars.siteBaseURL + '?_wfsf=view&nonce=' + this.nonce + '&file=' + encodeURIComponent(file);
564
+ },
565
  makeTimeAgo: function(t){
566
  var months = Math.floor(t / (86400 * 30));
567
  var days = Math.floor(t / 86400);
lib/email_unlockRequest.php ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Either you or someone else at IP address <b><?php echo $IP; ?></b> requesed instructions to<br />
2
+ regain access to the website <a href="<?php echo wfUtils::getSiteBaseURL(); ?>"><b><?php echo $siteName; ?></b></a>.<br />
3
+ <br />
4
+ If you did not request these instructions then you can safely ignore them.<br />
5
+ These instructions <b>will be valid for 30 minutes</b>
6
+ from the time they were sent.
7
+ <ul>
8
+ <li>
9
+ <a href="<?php echo $unlockHref; ?>&func=unlockMyIP">Click here to unlock your ability to sign-in and to access to the site.</a> Do this if you simply need to regain access because you were accidentally locked out.
10
+ </li>
11
+ <li>
12
+ <a href="<?php echo $unlockHref; ?>&func=unlockAllIPs">Click here to unblock all IP addresses.</a> Do this if you still can't regain access using the link above. It causes everyone who is blocked or locked out to be able to access your site again.
13
+ </li>
14
+ <li>
15
+ <a href="<?php echo $unlockHref; ?>&func=disableRules">Click here to unlock all IP addresses and disable the Wordfence Firewall and Wordefence login security for all users.</a> Do this if you keep getting locked out or blocked and can't access your site. You can re-enable login security and the firewall once you sign-in to the site by visiting the Wordfence options menu and checking the boxes under advanced options to enable the firewall and login security.
16
+ </li>
17
+ </ul>
18
+ <br />
19
+ <br />
20
+ If you have any further questions, please <a href="https://www.wordfence.com/forums/">visit our support forum at www.wordfence.com</a>.
21
+ <br />
22
+ <br />
23
+ <br />
lib/menu_options.php CHANGED
@@ -15,10 +15,9 @@ var WFSLevels = <?php echo json_encode(wfConfig::$securityLevels); ?>;
15
 
16
  <form id="wfConfigForm">
17
  <table class="wfConfigForm">
18
- <tr><td colspan="2"><h2>Alerts</h2></td></tr>
19
- <tr><th>List of emails to alert, separated by commas</th><td><input type="text" id="alertEmails" name="alertEmails" value="<?php $w->f('alertEmails'); ?>" size="50" /></td></tr>
20
- <tr><td colspan="2"><h2>Security Level</h2></td></tr>
21
- <tr><td colspan="2">
22
  <select id="securityLevel" name="securityLevel" onchange="WFAD.changeSecurityLevel(); return true;">
23
  <option value="0"<?php $w->sel('securityLevel', '0'); ?>>Level 0: Disable all Wordfence security measures</option>
24
  <option value="1"<?php $w->sel('securityLevel', '1'); ?>>Level 1: Light protection. Just the basics</option>
@@ -31,13 +30,16 @@ var WFSLevels = <?php echo json_encode(wfConfig::$securityLevels); ?>;
31
 
32
  </table>
33
  <p><table border="0" cellpadding="0" cellspacing="0"><tr><td><input type="button" id="button1" name="button1" class="button-primary" value="Save Changes" onclick="WFAD.saveConfig();" /></td><td style="height: 24px;"><div class="wfAjax24"></div><span class="wfSavedMsg">&nbsp;Your changes have been saved!</span></td></tr></table></p>
34
- <div>
35
- <p style="width: 600px;">Wordfence works great out of the box for most websites. Simply install Wordfence and your site and content is protected. For finer granularity of control, we have provided advanced options.</p>
36
- <a href="#" onclick="jQuery('#wfConfigAdvanced').fadeToggle();">Show or hide advanced options that let you create a custom security profile</a>
 
 
 
37
  </div>
38
- <div id="wfConfigAdvanced" style="display: none;">
39
  <table class="wfConfigForm">
40
- <tr><td colspan="2"><h2>Alerts</h2></td></tr>
41
  <tr><th>Alert on critical problems</th><td><input type="checkbox" id="alertOn_critical" class="wfConfigElem" name="alertOn_critical" value="1" <?php $w->cb('alertOn_critical'); ?>/></td></tr>
42
  <tr><th>Alert on warnings</th><td><input type="checkbox" id="alertOn_warnings" class="wfConfigElem" name="alertOn_warnings" value="1" <?php $w->cb('alertOn_warnings'); ?>/></td></tr>
43
  <tr><th>Alert when an IP address is blocked</th><td><input type="checkbox" id="alertOn_block" class="wfConfigElem" name="alertOn_block" value="1" <?php $w->cb('alertOn_block'); ?>/></td></tr>
@@ -45,14 +47,14 @@ var WFSLevels = <?php echo json_encode(wfConfig::$securityLevels); ?>;
45
  <tr><th>Alert when the "lost password" form is used for a valid user</th><td><input type="checkbox" id="alertOn_lostPasswdForm" class="wfConfigElem" name="alertOn_lostPasswdForm" value="1" <?php $w->cb('alertOn_lostPasswdForm'); ?>/></td></tr>
46
  <tr><th>Alert me when someone with administrator access signs in</th><td><input type="checkbox" id="alertOn_adminLogin" class="wfConfigElem" name="alertOn_adminLogin" value="1" <?php $w->cb('alertOn_adminLogin'); ?>/></td></tr>
47
  <tr><th>Alert me when a non-admin user signs in</th><td><input type="checkbox" id="alertOn_nonAdminLogin" class="wfConfigElem" name="alertOn_nonAdminLogin" value="1" <?php $w->cb('alertOn_nonAdminLogin'); ?>/></td></tr>
48
- <tr><td colspan="2"><h2>Live Traffic View</h2></td></tr>
49
  <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;" /></td></tr>
50
  <tr><th>Don't log signed-in users with publishing access:</th><td><input type="checkbox" id="liveTraf_ignorePublishers" name="liveTraf_ignorePublishers" value="1" <?php $w->cb('liveTraf_ignorePublishers'); ?> /></td></tr>
51
  <tr><th>List of comma separated usernames to ignore:</th><td><input type="text" name="liveTraf_ignoreUsers" id="liveTraf_ignoreUsers" value="<?php echo $w->getHTML('liveTraf_ignoreUsers'); ?>" /></td></tr>
52
  <tr><th>List of comma separated IP addresses to ignore:</th><td><input type="text" name="liveTraf_ignoreIPs" id="liveTraf_ignoreIPs" value="<?php echo $w->getHTML('liveTraf_ignoreIPs'); ?>" /></td></tr>
53
  <tr><th>Browser user-agent to ignore:</th><td><input type="text" name="liveTraf_ignoreUA" id="liveTraf_ignoreUA" value="<?php echo $w->getHTML('liveTraf_ignoreUA'); ?>" /></td></tr>
54
  <tr><th>Limit size of hits table to</th><td><input type="text" name="liveTraf_hitsMaxSize" class="wfConfigElem" name="liveTraf_hitsMaxSize" value="<?php $w->f('liveTraf_hitsMaxSize'); ?>" size="6" />Megabytes</td></tr>
55
- <tr><td colspan="2"><h2>Scans to include</h2></td></tr>
56
  <tr><th class="wfConfigEnable">Enable automatic scheduled scans</th><td><input type="checkbox" id="scheduledScansEnabled" class="wfConfigElem" name="scheduledScansEnabled" value="1" <?php $w->cb('scheduledScansEnabled'); ?> /></td></tr>
57
  <tr><th>Scan core files against repository versions for changes</th><td><input type="checkbox" id="scansEnabled_core" class="wfConfigElem" name="scansEnabled_core" value="1" <?php $w->cb('scansEnabled_core'); ?>/></td></tr>
58
 
@@ -60,7 +62,7 @@ var WFSLevels = <?php echo json_encode(wfConfig::$securityLevels); ?>;
60
  <tr><th>Scan theme files against repository versions for changes</th><td><input type="checkbox" id="scansEnabled_themes" class="wfConfigElem" name="scansEnabled_themes" value="1" <?php $w->cb('scansEnabled_themes'); ?>/></td></tr>
61
  <tr><th>Scan plugin files against repository versions for changes</th><td><input type="checkbox" id="scansEnabled_plugins" class="wfConfigElem" name="scansEnabled_plugins" value="1" <?php $w->cb('scansEnabled_plugins'); ?>/></td></tr>
62
  <?php } else { ?>
63
- <tr><th style="color: #F00; padding-top: 10px;">Only available to Premium Members:</th><td></td></tr>
64
  <tr><th style="color: #999;">Scan theme files against repository versions for changes</th><td><input type="checkbox" id="scansEnabled_themes" class="wfConfigElem" name="scansEnabled_themes" value="1" DISABLED /></td></tr>
65
  <tr><th style="color: #999;">Scan plugin files against repository versions for changes</th><td><input type="checkbox" id="scansEnabled_plugins" class="wfConfigElem" name="scansEnabled_plugins" value="1" DISABLED /></td></tr>
66
  <tr><td colspan="2">&nbsp;</td></tr>
@@ -74,7 +76,7 @@ var WFSLevels = <?php echo json_encode(wfConfig::$securityLevels); ?>;
74
  <tr><th>Monitor disk space</th><td><input type="checkbox" id="scansEnabled_diskSpace" class="wfConfigElem" name="scansEnabled_diskSpace" value="1" <?php $w->cb('scansEnabled_diskSpace'); ?>/></td></tr>
75
  <tr><th>Scan for unauthorized DNS changes</th><td><input type="checkbox" id="scansEnabled_dns" class="wfConfigElem" name="scansEnabled_dns" value="1" <?php $w->cb('scansEnabled_dns'); ?>/></td></tr>
76
  <tr><td colspan="2">
77
- <h2>Firewall Rules</h2>
78
  </td></tr>
79
 
80
  <tr><th class="wfConfigEnable">Enable firewall rules</th><td><input type="checkbox" id="firewallEnabled" class="wfConfigElem" name="firewallEnabled" value="1" <?php $w->cb('firewallEnabled'); ?> /></td></tr>
@@ -107,7 +109,7 @@ var WFSLevels = <?php echo json_encode(wfConfig::$securityLevels); ?>;
107
  <option value="2592000"<?php $w->sel('blockedTime', '2592000'); ?>>1 month</option>
108
  </select></td></tr>
109
 
110
- <tr><td colspan="2"><h2>Login Security Options</h2></td></tr>
111
  <tr><th class="wfConfigEnable">Enable login security</th><td><input type="checkbox" id="loginSecurityEnabled" class="wfConfigElem" name="loginSecurityEnabled" value="1" <?php $w->cb('loginSecurityEnabled'); ?> /></td></tr>
112
  <tr><th>Lock out after how many login failures</th><td>
113
  <select id="loginSec_maxFailures" class="wfConfigElem" name="loginSec_maxFailures">
@@ -121,6 +123,13 @@ var WFSLevels = <?php echo json_encode(wfConfig::$securityLevels); ?>;
121
  <option value="8"<?php $w->sel('loginSec_maxFailures', '8'); ?>>8</option>
122
  <option value="9"<?php $w->sel('loginSec_maxFailures', '9'); ?>>9</option>
123
  <option value="10"<?php $w->sel('loginSec_maxFailures', '10'); ?>>10</option>
 
 
 
 
 
 
 
124
  </select>
125
  </td></tr>
126
  <tr><th>Lock out after how many forgot password attempts</th><td>
@@ -135,6 +144,13 @@ var WFSLevels = <?php echo json_encode(wfConfig::$securityLevels); ?>;
135
  <option value="8"<?php $w->sel('loginSec_maxForgotPasswd', '8'); ?>>8</option>
136
  <option value="9"<?php $w->sel('loginSec_maxForgotPasswd', '9'); ?>>9</option>
137
  <option value="10"<?php $w->sel('loginSec_maxForgotPasswd', '10'); ?>>10</option>
 
 
 
 
 
 
 
138
  </select>
139
  </td></tr>
140
  <tr><th>Count failures over what time period</th><td>
@@ -163,7 +179,7 @@ var WFSLevels = <?php echo json_encode(wfConfig::$securityLevels); ?>;
163
  </td></tr>
164
  <tr><th>Immediately lock out invalid usernames</th><td><input type="checkbox" id="loginSec_lockInvalidUsers" class="wfConfigElem" name="loginSec_lockInvalidUsers" <?php $w->cb('loginSec_lockInvalidUsers'); ?> /></td></tr>
165
  <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>
166
- <tr><td colspan="2"><h2>Other Options</h2></td></tr>
167
  <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>
168
  <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>
169
  <tr><th>Scan 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>
15
 
16
  <form id="wfConfigForm">
17
  <table class="wfConfigForm">
18
+ <tr><td colspan="2"><h2>Basic Options</h2></td></tr>
19
+ <tr><th>Where to email alerts:</th><td><input type="text" id="alertEmails" name="alertEmails" value="<?php $w->f('alertEmails'); ?>" size="50" />&nbsp;<span class="wfTipText">Separate multiple emails with commas</span></td></tr>
20
+ <tr><th>Security Level:</th><td>
 
21
  <select id="securityLevel" name="securityLevel" onchange="WFAD.changeSecurityLevel(); return true;">
22
  <option value="0"<?php $w->sel('securityLevel', '0'); ?>>Level 0: Disable all Wordfence security measures</option>
23
  <option value="1"<?php $w->sel('securityLevel', '1'); ?>>Level 1: Light protection. Just the basics</option>
30
 
31
  </table>
32
  <p><table border="0" cellpadding="0" cellspacing="0"><tr><td><input type="button" id="button1" name="button1" class="button-primary" value="Save Changes" onclick="WFAD.saveConfig();" /></td><td style="height: 24px;"><div class="wfAjax24"></div><span class="wfSavedMsg">&nbsp;Your changes have been saved!</span></td></tr></table></p>
33
+ <div style="margin-top: 25px;">
34
+ <h2>Advanced Options:</h2>
35
+ <p style="width: 600px;">
36
+ Wordfence works great out of the box for most websites. Simply install Wordfence and your site and content is protected. For finer granularity of control, we have provided advanced options.
37
+ If you need help with advanced options, <a href="http://www.wordfence.com/forums/forum/wordfence-support-questions/" target="_blank">please ask in the Wordfence support forum</a>.
38
+ </p>
39
  </div>
40
+ <div id="wfConfigAdvanced">
41
  <table class="wfConfigForm">
42
+ <tr><td colspan="2"><h3 class="wfConfigHeading">Alerts</h3></td></tr>
43
  <tr><th>Alert on critical problems</th><td><input type="checkbox" id="alertOn_critical" class="wfConfigElem" name="alertOn_critical" value="1" <?php $w->cb('alertOn_critical'); ?>/></td></tr>
44
  <tr><th>Alert on warnings</th><td><input type="checkbox" id="alertOn_warnings" class="wfConfigElem" name="alertOn_warnings" value="1" <?php $w->cb('alertOn_warnings'); ?>/></td></tr>
45
  <tr><th>Alert when an IP address is blocked</th><td><input type="checkbox" id="alertOn_block" class="wfConfigElem" name="alertOn_block" value="1" <?php $w->cb('alertOn_block'); ?>/></td></tr>
47
  <tr><th>Alert when the "lost password" form is used for a valid user</th><td><input type="checkbox" id="alertOn_lostPasswdForm" class="wfConfigElem" name="alertOn_lostPasswdForm" value="1" <?php $w->cb('alertOn_lostPasswdForm'); ?>/></td></tr>
48
  <tr><th>Alert me when someone with administrator access signs in</th><td><input type="checkbox" id="alertOn_adminLogin" class="wfConfigElem" name="alertOn_adminLogin" value="1" <?php $w->cb('alertOn_adminLogin'); ?>/></td></tr>
49
  <tr><th>Alert me when a non-admin user signs in</th><td><input type="checkbox" id="alertOn_nonAdminLogin" class="wfConfigElem" name="alertOn_nonAdminLogin" value="1" <?php $w->cb('alertOn_nonAdminLogin'); ?>/></td></tr>
50
+ <tr><td colspan="2"><h3 class="wfConfigHeading">Live Traffic View</h3></td></tr>
51
  <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;" /></td></tr>
52
  <tr><th>Don't log signed-in users with publishing access:</th><td><input type="checkbox" id="liveTraf_ignorePublishers" name="liveTraf_ignorePublishers" value="1" <?php $w->cb('liveTraf_ignorePublishers'); ?> /></td></tr>
53
  <tr><th>List of comma separated usernames to ignore:</th><td><input type="text" name="liveTraf_ignoreUsers" id="liveTraf_ignoreUsers" value="<?php echo $w->getHTML('liveTraf_ignoreUsers'); ?>" /></td></tr>
54
  <tr><th>List of comma separated IP addresses to ignore:</th><td><input type="text" name="liveTraf_ignoreIPs" id="liveTraf_ignoreIPs" value="<?php echo $w->getHTML('liveTraf_ignoreIPs'); ?>" /></td></tr>
55
  <tr><th>Browser user-agent to ignore:</th><td><input type="text" name="liveTraf_ignoreUA" id="liveTraf_ignoreUA" value="<?php echo $w->getHTML('liveTraf_ignoreUA'); ?>" /></td></tr>
56
  <tr><th>Limit size of hits table to</th><td><input type="text" name="liveTraf_hitsMaxSize" class="wfConfigElem" name="liveTraf_hitsMaxSize" value="<?php $w->f('liveTraf_hitsMaxSize'); ?>" size="6" />Megabytes</td></tr>
57
+ <tr><td colspan="2"><h3 class="wfConfigHeading">Scans to include</h3></td></tr>
58
  <tr><th class="wfConfigEnable">Enable automatic scheduled scans</th><td><input type="checkbox" id="scheduledScansEnabled" class="wfConfigElem" name="scheduledScansEnabled" value="1" <?php $w->cb('scheduledScansEnabled'); ?> /></td></tr>
59
  <tr><th>Scan core files against repository versions for changes</th><td><input type="checkbox" id="scansEnabled_core" class="wfConfigElem" name="scansEnabled_core" value="1" <?php $w->cb('scansEnabled_core'); ?>/></td></tr>
60
 
62
  <tr><th>Scan theme files against repository versions for changes</th><td><input type="checkbox" id="scansEnabled_themes" class="wfConfigElem" name="scansEnabled_themes" value="1" <?php $w->cb('scansEnabled_themes'); ?>/></td></tr>
63
  <tr><th>Scan plugin files against repository versions for changes</th><td><input type="checkbox" id="scansEnabled_plugins" class="wfConfigElem" name="scansEnabled_plugins" value="1" <?php $w->cb('scansEnabled_plugins'); ?>/></td></tr>
64
  <?php } else { ?>
65
+ <tr><th style="color: #F00; padding-top: 10px;" colspan="2">Only available to Premium Members: <a href="https://www.wordfence.com/choose-a-wordfence-membership-type/" target="_blank">[click to upgrade]</a></th><td></td></tr>
66
  <tr><th style="color: #999;">Scan theme files against repository versions for changes</th><td><input type="checkbox" id="scansEnabled_themes" class="wfConfigElem" name="scansEnabled_themes" value="1" DISABLED /></td></tr>
67
  <tr><th style="color: #999;">Scan plugin files against repository versions for changes</th><td><input type="checkbox" id="scansEnabled_plugins" class="wfConfigElem" name="scansEnabled_plugins" value="1" DISABLED /></td></tr>
68
  <tr><td colspan="2">&nbsp;</td></tr>
76
  <tr><th>Monitor disk space</th><td><input type="checkbox" id="scansEnabled_diskSpace" class="wfConfigElem" name="scansEnabled_diskSpace" value="1" <?php $w->cb('scansEnabled_diskSpace'); ?>/></td></tr>
77
  <tr><th>Scan for unauthorized DNS changes</th><td><input type="checkbox" id="scansEnabled_dns" class="wfConfigElem" name="scansEnabled_dns" value="1" <?php $w->cb('scansEnabled_dns'); ?>/></td></tr>
78
  <tr><td colspan="2">
79
+ <h3 class="wfConfigHeading">Firewall Rules</h3>
80
  </td></tr>
81
 
82
  <tr><th class="wfConfigEnable">Enable firewall rules</th><td><input type="checkbox" id="firewallEnabled" class="wfConfigElem" name="firewallEnabled" value="1" <?php $w->cb('firewallEnabled'); ?> /></td></tr>
109
  <option value="2592000"<?php $w->sel('blockedTime', '2592000'); ?>>1 month</option>
110
  </select></td></tr>
111
 
112
+ <tr><td colspan="2"><h3 class="wfConfigHeading">Login Security Options</h3></td></tr>
113
  <tr><th class="wfConfigEnable">Enable login security</th><td><input type="checkbox" id="loginSecurityEnabled" class="wfConfigElem" name="loginSecurityEnabled" value="1" <?php $w->cb('loginSecurityEnabled'); ?> /></td></tr>
114
  <tr><th>Lock out after how many login failures</th><td>
115
  <select id="loginSec_maxFailures" class="wfConfigElem" name="loginSec_maxFailures">
123
  <option value="8"<?php $w->sel('loginSec_maxFailures', '8'); ?>>8</option>
124
  <option value="9"<?php $w->sel('loginSec_maxFailures', '9'); ?>>9</option>
125
  <option value="10"<?php $w->sel('loginSec_maxFailures', '10'); ?>>10</option>
126
+ <option value="20"<?php $w->sel('loginSec_maxFailures', '20'); ?>>20</option>
127
+ <option value="30"<?php $w->sel('loginSec_maxFailures', '30'); ?>>30</option>
128
+ <option value="40"<?php $w->sel('loginSec_maxFailures', '40'); ?>>40</option>
129
+ <option value="50"<?php $w->sel('loginSec_maxFailures', '50'); ?>>50</option>
130
+ <option value="100"<?php $w->sel('loginSec_maxFailures', '100'); ?>>100</option>
131
+ <option value="200"<?php $w->sel('loginSec_maxFailures', '200'); ?>>200</option>
132
+ <option value="500"<?php $w->sel('loginSec_maxFailures', '500'); ?>>500</option>
133
  </select>
134
  </td></tr>
135
  <tr><th>Lock out after how many forgot password attempts</th><td>
144
  <option value="8"<?php $w->sel('loginSec_maxForgotPasswd', '8'); ?>>8</option>
145
  <option value="9"<?php $w->sel('loginSec_maxForgotPasswd', '9'); ?>>9</option>
146
  <option value="10"<?php $w->sel('loginSec_maxForgotPasswd', '10'); ?>>10</option>
147
+ <option value="20"<?php $w->sel('loginSec_maxForgotPasswd', '20'); ?>>20</option>
148
+ <option value="30"<?php $w->sel('loginSec_maxForgotPasswd', '30'); ?>>30</option>
149
+ <option value="40"<?php $w->sel('loginSec_maxForgotPasswd', '40'); ?>>40</option>
150
+ <option value="50"<?php $w->sel('loginSec_maxForgotPasswd', '50'); ?>>50</option>
151
+ <option value="100"<?php $w->sel('loginSec_maxForgotPasswd', '100'); ?>>100</option>
152
+ <option value="200"<?php $w->sel('loginSec_maxForgotPasswd', '200'); ?>>200</option>
153
+ <option value="500"<?php $w->sel('loginSec_maxForgotPasswd', '500'); ?>>500</option>
154
  </select>
155
  </td></tr>
156
  <tr><th>Count failures over what time period</th><td>
179
  </td></tr>
180
  <tr><th>Immediately lock out invalid usernames</th><td><input type="checkbox" id="loginSec_lockInvalidUsers" class="wfConfigElem" name="loginSec_lockInvalidUsers" <?php $w->cb('loginSec_lockInvalidUsers'); ?> /></td></tr>
181
  <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>
182
+ <tr><td colspan="2"><h3 class="wfConfigHeading">Other Options</h3></td></tr>
183
  <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>
184
  <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>
185
  <tr><th>Scan 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>
lib/menu_scan.php CHANGED
@@ -70,6 +70,7 @@
70
  </p>
71
  <p>
72
  {{html longMsg}}
 
73
  </p>
74
  <div class="wfIssueOptions">
75
  {{if (status == 'new')}}
@@ -104,6 +105,7 @@
104
  </p>
105
  <p>
106
  {{html longMsg}}
 
107
  </p>
108
  <div class="wfIssueOptions">
109
  {{if status == 'new'}}
@@ -136,6 +138,7 @@
136
  </p>
137
  <p>
138
  {{html longMsg}}
 
139
  </p>
140
  <div class="wfIssueOptions">
141
  {{if (status == 'new')}}
@@ -348,7 +351,7 @@
348
  <div class="wfIssueOptions">
349
  <strong>Tools:</strong>
350
  {{if data.fileExists}}
351
- <a target="_blank" href="/?_wfsf=view&nonce=${WFAD.nonce}&file=${encodeURIComponent(data.file)}">View the file.</a>
352
  {{/if}}
353
  {{if data.canFix}}
354
  <a href="#" onclick="WFAD.restoreFile('${id}'); return false;">Restore the original version of this file.</a>
70
  </p>
71
  <p>
72
  {{html longMsg}}
73
+ <a href="<?php echo get_admin_url() . 'update-core.php'; ?>">Click here to update now</a>.
74
  </p>
75
  <div class="wfIssueOptions">
76
  {{if (status == 'new')}}
105
  </p>
106
  <p>
107
  {{html longMsg}}
108
+ <a href="<?php echo get_admin_url() . 'update-core.php'; ?>">Click here to update now</a>.
109
  </p>
110
  <div class="wfIssueOptions">
111
  {{if status == 'new'}}
138
  </p>
139
  <p>
140
  {{html longMsg}}
141
+ <a href="<?php echo get_admin_url() . 'update-core.php'; ?>">Click here to update now</a>.
142
  </p>
143
  <div class="wfIssueOptions">
144
  {{if (status == 'new')}}
351
  <div class="wfIssueOptions">
352
  <strong>Tools:</strong>
353
  {{if data.fileExists}}
354
+ <a target="_blank" href="${WFAD.makeViewFileLink(data.file)}">View the file.</a>
355
  {{/if}}
356
  {{if data.canFix}}
357
  <a href="#" onclick="WFAD.restoreFile('${id}'); return false;">Restore the original version of this file.</a>
lib/wf503.php CHANGED
@@ -5,5 +5,7 @@
5
  <h1>Service Unavailable</h1>
6
  <p>Your access to this service has been temporarily limited. Please try again in a few minutes. (HTTP response code 503)</p>
7
  <hr>
 
 
8
  <address>This response was generated by Wordfence.</address>
9
  </body></html>
5
  <h1>Service Unavailable</h1>
6
  <p>Your access to this service has been temporarily limited. Please try again in a few minutes. (HTTP response code 503)</p>
7
  <hr>
8
+ <br /><br />
9
+ <?php require('wfUnlockMsg.php'); ?>
10
  <address>This response was generated by Wordfence.</address>
11
  </body></html>
lib/wfAPI.php CHANGED
@@ -67,8 +67,6 @@ class wfAPI {
67
  curl_setopt ($curl, CURLOPT_SSL_VERIFYPEER, false);
68
  curl_setopt ($curl, CURLOPT_SSL_VERIFYHOST, false);
69
  curl_setopt ($curl, CURLOPT_WRITEFUNCTION, array($this, 'curlWrite'));
70
- @curl_setopt ($curl, CURLOPT_FOLLOWLOCATION, true);
71
- @curl_setopt ($curl, CURLOPT_MAXREDIRS, 10);
72
  curl_setopt($curl, CURLOPT_POST, true);
73
  curl_setopt($curl, CURLOPT_POSTFIELDS, $postParams);
74
 
@@ -106,9 +104,6 @@ class wfAPI {
106
  curl_setopt ($curl, CURLOPT_RETURNTRANSFER, TRUE);
107
  curl_setopt ($curl, CURLOPT_SSL_VERIFYPEER, false);
108
  curl_setopt ($curl, CURLOPT_SSL_VERIFYHOST, false);
109
-
110
- @curl_setopt ($curl, CURLOPT_FOLLOWLOCATION, true);
111
- @curl_setopt ($curl, CURLOPT_MAXREDIRS, 10);
112
  curl_setopt($curl, CURLOPT_POST, true);
113
  if($postData){
114
  curl_setopt($curl, CURLOPT_POSTFIELDS, $postData);
67
  curl_setopt ($curl, CURLOPT_SSL_VERIFYPEER, false);
68
  curl_setopt ($curl, CURLOPT_SSL_VERIFYHOST, false);
69
  curl_setopt ($curl, CURLOPT_WRITEFUNCTION, array($this, 'curlWrite'));
 
 
70
  curl_setopt($curl, CURLOPT_POST, true);
71
  curl_setopt($curl, CURLOPT_POSTFIELDS, $postParams);
72
 
104
  curl_setopt ($curl, CURLOPT_RETURNTRANSFER, TRUE);
105
  curl_setopt ($curl, CURLOPT_SSL_VERIFYPEER, false);
106
  curl_setopt ($curl, CURLOPT_SSL_VERIFYHOST, false);
 
 
 
107
  curl_setopt($curl, CURLOPT_POST, true);
108
  if($postData){
109
  curl_setopt($curl, CURLOPT_POSTFIELDS, $postData);
lib/wfConfig.php CHANGED
@@ -48,8 +48,8 @@ class wfConfig {
48
  "neverBlockBG" => "neverBlockVerified",
49
  "loginSec_countFailMins" => "5",
50
  "loginSec_lockoutMins" => "5",
51
- 'loginSec_maxFailures' => "5",
52
- 'loginSec_maxForgotPasswd' => "5",
53
  'maxGlobalRequests' => "DISABLED",
54
  'maxGlobalRequests_action' => "throttle",
55
  'maxRequestsCrawlers' => "DISABLED",
@@ -109,8 +109,8 @@ class wfConfig {
109
  "neverBlockBG" => "neverBlockVerified",
110
  "loginSec_countFailMins" => "5",
111
  "loginSec_lockoutMins" => "5",
112
- 'loginSec_maxFailures' => "10",
113
- 'loginSec_maxForgotPasswd' => "10",
114
  'maxGlobalRequests' => "960",
115
  'maxGlobalRequests_action' => "throttle",
116
  'maxRequestsCrawlers' => "960",
@@ -170,8 +170,8 @@ class wfConfig {
170
  "neverBlockBG" => "neverBlockVerified",
171
  "loginSec_countFailMins" => "240",
172
  "loginSec_lockoutMins" => "240",
173
- 'loginSec_maxFailures' => "3",
174
- 'loginSec_maxForgotPasswd' => "5",
175
  'maxGlobalRequests' => "960",
176
  'maxGlobalRequests_action' => "throttle",
177
  'maxRequestsCrawlers' => "960",
@@ -231,8 +231,8 @@ class wfConfig {
231
  "neverBlockBG" => "neverBlockVerified",
232
  "loginSec_countFailMins" => "1440",
233
  "loginSec_lockoutMins" => "1440",
234
- 'loginSec_maxFailures' => "3",
235
- 'loginSec_maxForgotPasswd' => "3",
236
  'maxGlobalRequests' => "960",
237
  'maxGlobalRequests_action' => "throttle",
238
  'maxRequestsCrawlers' => "960",
@@ -292,8 +292,8 @@ class wfConfig {
292
  "neverBlockBG" => "neverBlockVerified",
293
  "loginSec_countFailMins" => "1440",
294
  "loginSec_lockoutMins" => "1440",
295
- 'loginSec_maxFailures' => "3",
296
- 'loginSec_maxForgotPasswd' => "3",
297
  'maxGlobalRequests' => "960",
298
  'maxGlobalRequests_action' => "throttle",
299
  'maxRequestsCrawlers' => "960",
@@ -435,7 +435,7 @@ class wfConfig {
435
  $emails = array();
436
  foreach($dat as $email){
437
  if(preg_match('/\@/', $email)){
438
- $emails[] = $email;
439
  }
440
  }
441
  return $emails;
48
  "neverBlockBG" => "neverBlockVerified",
49
  "loginSec_countFailMins" => "5",
50
  "loginSec_lockoutMins" => "5",
51
+ 'loginSec_maxFailures' => "500",
52
+ 'loginSec_maxForgotPasswd' => "500",
53
  'maxGlobalRequests' => "DISABLED",
54
  'maxGlobalRequests_action' => "throttle",
55
  'maxRequestsCrawlers' => "DISABLED",
109
  "neverBlockBG" => "neverBlockVerified",
110
  "loginSec_countFailMins" => "5",
111
  "loginSec_lockoutMins" => "5",
112
+ 'loginSec_maxFailures' => "50",
113
+ 'loginSec_maxForgotPasswd' => "50",
114
  'maxGlobalRequests' => "960",
115
  'maxGlobalRequests_action' => "throttle",
116
  'maxRequestsCrawlers' => "960",
170
  "neverBlockBG" => "neverBlockVerified",
171
  "loginSec_countFailMins" => "240",
172
  "loginSec_lockoutMins" => "240",
173
+ 'loginSec_maxFailures' => "20",
174
+ 'loginSec_maxForgotPasswd' => "20",
175
  'maxGlobalRequests' => "960",
176
  'maxGlobalRequests_action' => "throttle",
177
  'maxRequestsCrawlers' => "960",
231
  "neverBlockBG" => "neverBlockVerified",
232
  "loginSec_countFailMins" => "1440",
233
  "loginSec_lockoutMins" => "1440",
234
+ 'loginSec_maxFailures' => "10",
235
+ 'loginSec_maxForgotPasswd' => "10",
236
  'maxGlobalRequests' => "960",
237
  'maxGlobalRequests_action' => "throttle",
238
  'maxRequestsCrawlers' => "960",
292
  "neverBlockBG" => "neverBlockVerified",
293
  "loginSec_countFailMins" => "1440",
294
  "loginSec_lockoutMins" => "1440",
295
+ 'loginSec_maxFailures' => "5",
296
+ 'loginSec_maxForgotPasswd' => "5",
297
  'maxGlobalRequests' => "960",
298
  'maxGlobalRequests_action' => "throttle",
299
  'maxRequestsCrawlers' => "960",
435
  $emails = array();
436
  foreach($dat as $email){
437
  if(preg_match('/\@/', $email)){
438
+ $emails[] = trim($email);
439
  }
440
  }
441
  return $emails;
lib/wfLockedOut.php CHANGED
@@ -14,6 +14,8 @@
14
  <li><a href="<?php echo site_url(); ?>">Return to the site home page</a></li>
15
  <li><a href="<?php echo admin_url(); ?>">Attempt to return to the admin login page (you may still be locked out)</a></li>
16
  </ul>
 
 
17
  </p>
18
  <p style="font-style: italic;">Generated by Wordfence.</p>
19
  </body>
14
  <li><a href="<?php echo site_url(); ?>">Return to the site home page</a></li>
15
  <li><a href="<?php echo admin_url(); ?>">Attempt to return to the admin login page (you may still be locked out)</a></li>
16
  </ul>
17
+ <br /><br />
18
+ <?php require('wfUnlockMsg.php'); ?>
19
  </p>
20
  <p style="font-style: italic;">Generated by Wordfence.</p>
21
  </body>
lib/wfScanEngine.php CHANGED
@@ -415,13 +415,13 @@ class wfScanEngine {
415
  for($i = 0; $i < sizeof($words); $i++){
416
  if($hasher->CheckPassword($words[$i], $userDat->user_pass)){
417
  $this->status(2, 'info', "Adding issue " . $shortMsg);
418
- $this->addIssue('easyPassword', $level, $user->ID, $user->ID . '-' . $userDat->user_pass, $shortMsg, $longMsg, array(
419
- 'ID' => $user->ID,
420
  'user_login' => $userDat->user_login,
421
  'user_email' => $userDat->user_email,
422
  'first_name' => $userDat->first_name,
423
  'last_name' => $userDat->last_name,
424
- 'editUserLink' => wfUtils::editUserLink($user->ID)
425
  ));
426
  break;
427
  }
@@ -453,6 +453,10 @@ class wfScanEngine {
453
 
454
  }
455
  private function scanDNSChanges(){
 
 
 
 
456
  $this->status(2, 'info', "Starting DNS checks");
457
  $home = get_home_url();
458
  if(preg_match('/https?:\/\/([^\/]+)/i', $home, $matches)){
415
  for($i = 0; $i < sizeof($words); $i++){
416
  if($hasher->CheckPassword($words[$i], $userDat->user_pass)){
417
  $this->status(2, 'info', "Adding issue " . $shortMsg);
418
+ $this->addIssue('easyPassword', $level, $userDat->ID, $userDat->ID . '-' . $userDat->user_pass, $shortMsg, $longMsg, array(
419
+ 'ID' => $userDat->ID,
420
  'user_login' => $userDat->user_login,
421
  'user_email' => $userDat->user_email,
422
  'first_name' => $userDat->first_name,
423
  'last_name' => $userDat->last_name,
424
+ 'editUserLink' => wfUtils::editUserLink($userDat->ID)
425
  ));
426
  break;
427
  }
453
 
454
  }
455
  private function scanDNSChanges(){
456
+ if(! function_exists('dns_get_record')){
457
+ $this->status(1, 'info', "Skipping DNS scan because this system does not support dns_get_record()");
458
+ return;
459
+ }
460
  $this->status(2, 'info', "Starting DNS checks");
461
  $home = get_home_url();
462
  if(preg_match('/https?:\/\/([^\/]+)/i', $home, $matches)){
lib/wfUnlockMsg.php ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
1
+ If you are a site administrator and have been accidentally locked out, please enter your email in the box below and click "Send". If the email address you enter belongs to a known site administrator or someone set to receive Wordfence alerts, we will send you an email to help you regain access.
2
+ <br /><br />
3
+ <form method="POST" action="<?php echo wfUtils::getSiteBaseURL(); ?>?_wfsf=unlockEmail&nonce=<?php echo wp_create_nonce('wp-ajax'); ?>">
4
+ <input type="text" size="50" name="email" value="" maxlength="255" />&nbsp;<input type="submit" name="s" value="Send me an unlock email" />
5
+ </form>
6
+ <br /><br />
lib/wfUtils.php CHANGED
@@ -149,6 +149,22 @@ class wfUtils {
149
  }
150
  return false;
151
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
152
  }
153
 
154
 
149
  }
150
  return false;
151
  }
152
+ public static function getSiteBaseURL(){
153
+ return rtrim(site_url(), '/') . '/';
154
+ }
155
+ public static function myVersion(){
156
+ if(! function_exists( 'get_plugin_data')){
157
+ require_once ABSPATH . '/wp-admin/includes/plugin.php';
158
+ }
159
+ $file = dirname(__FILE__) . '/../wordfence.php';
160
+ if(is_file($file)){
161
+ $dat = get_plugin_data($file);
162
+ if(is_array($dat)){
163
+ return $dat['Version'];
164
+ }
165
+ }
166
+ return 'unknown';
167
+ }
168
  }
169
 
170
 
lib/wordfenceClass.php CHANGED
@@ -159,7 +159,6 @@ class wordfence {
159
  add_action('wp_logout','wordfence::logoutAction');
160
  add_action('profile_update', 'wordfence::profileUpdateAction', '99', 2);
161
  add_action('lostpassword_post', 'wordfence::lostPasswordPost', '1');
162
- add_action('login_form', 'wordfence::loginForm', '1');
163
  add_filter('pre_comment_approved', 'wordfence::preCommentApprovedFilter', '99', 2);
164
  add_filter('authenticate', 'wordfence::authenticateFilter', 99, 3);
165
  //html|xhtml|atom|rss2|rdf|comment|export
@@ -244,6 +243,86 @@ class wordfence {
244
  return self::getLog()->isIPLockedOut($IP);
245
  }
246
  public static function veryFirstAction(){
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
247
  $wfLog = self::getLog();
248
  $wfLog->firewallBadIPs();
249
  }
@@ -355,7 +434,7 @@ class wordfence {
355
  }
356
  }
357
  public static function ajax_sendActivityLog_callback(){
358
- $content = "SITE: " . site_url() . "\nWP VERSION: " . wfUtils::getWPVersion() . "\nAPI KEY: " . wfConfig::get('apiKey') . "\nADMIN EMAIL: " . get_option('admin_email') . "\nLOG:\n\n";
359
  $wfdb = new wfDB();
360
  global $wpdb;
361
  $p = $wpdb->base_prefix;
@@ -801,6 +880,7 @@ class wordfence {
801
  return false;
802
  }
803
  public static function templateRedir(){
 
804
  $wfLog = self::getLog();
805
  if($wfLog->logHitOK()){
806
  if(is_404() ){
@@ -814,7 +894,6 @@ class wordfence {
814
  }
815
  }
816
 
817
- $wfFunc = get_query_var('_wfsf');
818
  if(! ($wfFunc == 'diff' || $wfFunc == 'view' || $wfFunc == 'sysinfo' || $wfFunc == 'IPTraf')){
819
  return;
820
  }
@@ -991,7 +1070,8 @@ class wordfence {
991
  wp_enqueue_script('wordfenceAdminjs', wfUtils::getBaseURL() . 'js/admin.js', array('jquery'));
992
  wp_localize_script('wordfenceAdminjs', 'WordfenceAdminVars', array(
993
  'ajaxURL' => admin_url('admin-ajax.php'),
994
- 'firstNonce' => wp_create_nonce('wp-ajax')
 
995
  ));
996
 
997
  }
@@ -1128,8 +1208,5 @@ class wordfence {
1128
  }
1129
  return self::$wfLog;
1130
  }
1131
- public static function loginForm(){
1132
- echo "<p><a href='http://www.wordfence.com/' target='_blank'>WordPress Security powered by Wordfence</a><br /><br /><br /></p>";
1133
- }
1134
  }
1135
  ?>
159
  add_action('wp_logout','wordfence::logoutAction');
160
  add_action('profile_update', 'wordfence::profileUpdateAction', '99', 2);
161
  add_action('lostpassword_post', 'wordfence::lostPasswordPost', '1');
 
162
  add_filter('pre_comment_approved', 'wordfence::preCommentApprovedFilter', '99', 2);
163
  add_filter('authenticate', 'wordfence::authenticateFilter', 99, 3);
164
  //html|xhtml|atom|rss2|rdf|comment|export
243
  return self::getLog()->isIPLockedOut($IP);
244
  }
245
  public static function veryFirstAction(){
246
+ $wfFunc = $_GET['_wfsf'];
247
+ if($wfFunc == 'unlockEmail'){
248
+ if(! wp_verify_nonce($_GET['nonce'], 'wp-ajax')){
249
+ echo "Security token verification failed.";
250
+ exit();
251
+ }
252
+ $email = trim($_POST['email']);
253
+ global $wpdb;
254
+ $ws = $wpdb->get_results("SELECT ID, user_login FROM $wpdb->users");
255
+ $users = array();
256
+ foreach($ws as $user){
257
+ if($user->user_level > 7){
258
+ if($email == $user->user_email){
259
+ $found = true;
260
+ break;
261
+ }
262
+ }
263
+ }
264
+ if(! $found){
265
+ foreach(wfConfig::getAlertEmails() as $alertEmail){
266
+ if($alertEmail == $email){
267
+ $found = true;
268
+ break;
269
+ }
270
+ }
271
+ }
272
+ if($found){
273
+ $key = wfUtils::bigRandomHex();
274
+ $IP = wfUtils::getIP();
275
+ set_transient('wfunlock_' . $key, $IP, 1800);
276
+ $content = wfUtils::tmpl('email_unlockRequest.php', array(
277
+ 'siteName' => get_bloginfo('name', 'raw'),
278
+ 'siteURL' => wfUtils::getSiteBaseURL(),
279
+ 'unlockHref' => wfUtils::getSiteBaseURL() . '?_wfsf=unlockAccess&nonce=' . wp_create_nonce('wp-unlock') . '&key=' . $key,
280
+ 'key' => $key,
281
+ 'IP' => $IP
282
+ ));
283
+ wp_mail($email, "Unlock email requested", $content, "Content-Type: text/html");
284
+ }
285
+ echo "<html><body><h1>Your request was received</h1><p>We received a request to email \"$email\" instructions to unlock their access. If that is the email address of a site administrator or someone on the Wordfence alert list, then they have been emailed instructions on how to regain access to this sytem. The instructions we sent will expire 30 minutes from now.</body></html>";
286
+ exit();
287
+ } else if($wfFunc == 'unlockAccess'){
288
+ if(! wp_verify_nonce($_GET['nonce'], 'wp-unlock')){
289
+ echo "Security token verification failed.";
290
+ exit();
291
+ }
292
+ if(! preg_match('/^\d+\.\d+\.\d+\.\d+$/', get_transient('wfunlock_' . $_GET['key']))){
293
+ echo "Invalid key provided for authentication.";
294
+ exit();
295
+ }
296
+ /* You can enable this for paranoid security leve.
297
+ if(get_transient('wfunlock_' . $_GET['key']) != wfUtils::getIP()){
298
+ echo "You can only use this link from the IP address you used to generate the unlock email.";
299
+ exit();
300
+ }
301
+ */
302
+ $wfLog = new wfLog(wfConfig::get('apiKey'), wfUtils::getWPVersion());
303
+ if($_GET['func'] == 'unlockMyIP'){
304
+ $wfLog->unblockIP(wfUtils::getIP());
305
+ $wfLog->unlockOutIP(wfUtils::getIP());
306
+ header('Location: ' . wp_login_url());
307
+ exit();
308
+ } else if($_GET['func'] == 'unlockAllIPs'){
309
+ $wfLog->unblockAllIPs();
310
+ $wfLog->unlockAllIPs();
311
+ header('Location: ' . wp_login_url());
312
+ exit();
313
+ } else if($_GET['func'] == 'disableRules'){
314
+ wfConfig::set('firewallEnabled', 0);
315
+ wfConfig::set('loginSecurityEnabled', 0);
316
+ $wfLog->unblockAllIPs();
317
+ $wfLog->unlockAllIPs();
318
+ header('Location: ' . wp_login_url());
319
+ exit();
320
+ } else {
321
+ echo "Invalid function specified. Please check the link we emailed you and make sure it was not cut-off by your email reader.";
322
+ exit();
323
+ }
324
+ }
325
+
326
  $wfLog = self::getLog();
327
  $wfLog->firewallBadIPs();
328
  }
434
  }
435
  }
436
  public static function ajax_sendActivityLog_callback(){
437
+ $content = "SITE: " . site_url() . "\nPLUGIN VERSION: " . wfUtils::myVersion() . "\nWP VERSION: " . wfUtils::getWPVersion() . "\nAPI KEY: " . wfConfig::get('apiKey') . "\nADMIN EMAIL: " . get_option('admin_email') . "\nLOG:\n\n";
438
  $wfdb = new wfDB();
439
  global $wpdb;
440
  $p = $wpdb->base_prefix;
880
  return false;
881
  }
882
  public static function templateRedir(){
883
+ $wfFunc = get_query_var('_wfsf');
884
  $wfLog = self::getLog();
885
  if($wfLog->logHitOK()){
886
  if(is_404() ){
894
  }
895
  }
896
 
 
897
  if(! ($wfFunc == 'diff' || $wfFunc == 'view' || $wfFunc == 'sysinfo' || $wfFunc == 'IPTraf')){
898
  return;
899
  }
1070
  wp_enqueue_script('wordfenceAdminjs', wfUtils::getBaseURL() . 'js/admin.js', array('jquery'));
1071
  wp_localize_script('wordfenceAdminjs', 'WordfenceAdminVars', array(
1072
  'ajaxURL' => admin_url('admin-ajax.php'),
1073
+ 'firstNonce' => wp_create_nonce('wp-ajax'),
1074
+ 'siteBaseURL' => wfUtils::getSiteBaseURL()
1075
  ));
1076
 
1077
  }
1208
  }
1209
  return self::$wfLog;
1210
  }
 
 
 
1211
  }
1212
  ?>
readme.txt CHANGED
@@ -3,7 +3,7 @@ Contributors: mmaunder
3
  Tags: wordpress, security, wordpress security, security plugin, secure, anti-virus, malware, firewall, antivirus, virus, google safe browsing, phishing, scrapers, hacking, wordfence, securty, secrity, secure
4
  Requires at least: 3.3.1
5
  Tested up to: 3.3.2
6
- Stable tag: 1.5.4
7
 
8
  Wordfence Security is a free enterprise class security plugin that includes a firewall, virus scanning, real-time traffic with geolocation and more.
9
 
@@ -152,6 +152,21 @@ or a theme, because often these have been updated to fix a security hole.
152
  5. If you're technically minded, this is the under-the-hood view of Wordfence options where you can fine-tune your security settings.
153
 
154
  == Changelog ==
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
155
  = 1.5.4 =
156
  * Admin can now select to scan outside the WordPress base dir and standard WordPress directories.
157
  * Max memory size for scans is now configurable for larger installations. 256M is the default.
3
  Tags: wordpress, security, wordpress security, security plugin, secure, anti-virus, malware, firewall, antivirus, virus, google safe browsing, phishing, scrapers, hacking, wordfence, securty, secrity, secure
4
  Requires at least: 3.3.1
5
  Tested up to: 3.3.2
6
+ Stable tag: 1.5.5
7
 
8
  Wordfence Security is a free enterprise class security plugin that includes a firewall, virus scanning, real-time traffic with geolocation and more.
9
 
152
  5. If you're technically minded, this is the under-the-hood view of Wordfence options where you can fine-tune your security settings.
153
 
154
  == Changelog ==
155
+ = 1.5.5 =
156
+ * Added ability for admin's to unlock login and unblock their IP addresses if they're accidentally locked out by the firewall or login security. Uses two security tokens to prevent abuse.
157
+ * Admins can now also disable firewall and login security from the unlock-me email, just in case of emergency.
158
+ * Made advanced options visible so you know they exist.
159
+ * Fixed dns_get_record() function not existing bug on Windows sytems pre PHP 5.3.0. Was causing scans to hang.
160
+ * Increased login lockout defaults to be much higher which still protects against brute force hacks.
161
+ * Removed CURLOPT_MAXREDIRS in curl to avoid safe mode warnings.
162
+ * Fixed ability to view and diff files on blogs installed in subdirectories.
163
+ * Fixed ability to see individual IP hits on subdir sites.
164
+ * Plugin and theme update messages now include links to the upgrade page.
165
+ * Removed the link on the login form that mentions the site is protected by Wordfence.
166
+ * Changed lockout defaults to be much higher.
167
+ * Added options for higher number of failures before lockout in options page.
168
+ * Now including plugin version in the activity log when the admin chooses to email it to us for debugging.
169
+
170
  = 1.5.4 =
171
  * Admin can now select to scan outside the WordPress base dir and standard WordPress directories.
172
  * Max memory size for scans is now configurable for larger installations. 256M is the default.
wordfence.php CHANGED
@@ -2,9 +2,9 @@
2
  /*
3
  Plugin Name: Wordfence Security
4
  Plugin URI: http://wordfence.com/
5
- Description: WordPress Security - Anti-virus and Firewall security plugin for WordPress
6
  Author: Mark Maunder
7
- Version: 1.5.4
8
  Author URI: http://wordfence.com/
9
  */
10
  require_once('lib/wordfenceConstants.php');
2
  /*
3
  Plugin Name: Wordfence Security
4
  Plugin URI: http://wordfence.com/
5
+ Description: Wordfence Security - Anti-virus and Firewall security plugin for WordPress
6
  Author: Mark Maunder
7
+ Version: 1.5.5
8
  Author URI: http://wordfence.com/
9
  */
10
  require_once('lib/wordfenceConstants.php');