Wordfence Security – Firewall & Malware Scan - Version 5.3.2

Version Description

  • Feature: Advanced blocking now includes referer blocking. i.e. you can block visitors arriving from certain websites or pretending to. See updated http://docs.wordfence.com/en/Advanced_Blocking
  • Feature: Developers, you can now ask Wordfence to whitelist your server IP by calling wordfence::whitelistIP(). See http://docs.wordfence.com/en/WhitelistIP
Download this release

Release Info

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

Code changes from version 5.3.1 to 5.3.2

js/admin.js CHANGED
@@ -1119,7 +1119,7 @@ window['wordfenceAdmin'] = {
1119
  jQuery('#wfrawhtml').html('<span style="color: #F00;">Sorry, but no data for that IP or domain was found.</span>');
1120
  }
1121
  },
1122
- blockIPUARange: function(ipRange, uaRange, reason){
1123
  if(! /\w+/.test(reason)){
1124
  this.colorbox('300px', "Please specify a reason", "You forgot to include a reason you're blocking this IP range. We ask you to include this for your own record keeping.");
1125
  return;
@@ -1131,7 +1131,7 @@ window['wordfenceAdmin'] = {
1131
  return;
1132
  }
1133
  }
1134
- if( ! (/\w+/.test(ipRange) || /\w+/.test(uaRange))){
1135
  this.colorbox('300px', 'Specify an IP range or Browser pattern', "Please specify either an IP address range or a web browser pattern to match.");
1136
  return;
1137
  }
@@ -1139,6 +1139,7 @@ window['wordfenceAdmin'] = {
1139
  this.ajax('wordfence_blockIPUARange', {
1140
  ipRange: ipRange,
1141
  uaRange: uaRange,
 
1142
  reason: reason
1143
  }, function(res){
1144
  if(res.ok){
1119
  jQuery('#wfrawhtml').html('<span style="color: #F00;">Sorry, but no data for that IP or domain was found.</span>');
1120
  }
1121
  },
1122
+ blockIPUARange: function(ipRange, uaRange, referer, reason){
1123
  if(! /\w+/.test(reason)){
1124
  this.colorbox('300px', "Please specify a reason", "You forgot to include a reason you're blocking this IP range. We ask you to include this for your own record keeping.");
1125
  return;
1131
  return;
1132
  }
1133
  }
1134
+ if( ! (/\w+/.test(ipRange) || /\w+/.test(uaRange) || /\w+/.test(referer)) ){
1135
  this.colorbox('300px', 'Specify an IP range or Browser pattern', "Please specify either an IP address range or a web browser pattern to match.");
1136
  return;
1137
  }
1139
  this.ajax('wordfence_blockIPUARange', {
1140
  ipRange: ipRange,
1141
  uaRange: uaRange,
1142
+ referer: referer,
1143
  reason: reason
1144
  }, function(res){
1145
  if(res.ok){
lib/menu_rangeBlocking.php CHANGED
@@ -6,14 +6,16 @@
6
  <p>
7
  <?php if(! wfConfig::get('firewallEnabled')){ ?><div style="color: #F00; font-weight: bold;">Firewall is disabled. You can enable it on the <a href="admin.php?page=WordfenceSecOpt">Wordfence Options page</a> at the top.</div><br /><?php } ?>
8
  <table class="wfConfigForm">
9
- <tr><th>Block anyone that has an IP address in this range:</th><td><input id="ipRange" type="text" size="30" maxlength="255" value="<?php if( isset( $_GET['wfBlockRange'] ) && $_GET['wfBlockRange']){ echo wp_kses($_GET['wfBlockRange'], array()); } ?>" onkeyup="WFAD.calcRangeTotal();">&nbsp;<span id="wfShowRangeTotal"></span></td></tr>
10
  <tr><td></td><td style="padding-bottom: 15px;"><strong>Examples:</strong> 192.168.200.200 - 192.168.200.220</td></tr>
11
- <tr><th>...you can also enter a User-Agent (browser) that matches:</th><td><input id="uaRange" type="text" size="30" maxlength="255" >&nbsp;(Case insensitive)</td></tr>
12
- <tr><td></td><td style="padding-bottom: 15px;"><strong>Examples:</strong> *badRobot*, AnotherBadRobot*, *someKindOfSuffix</td></tr>
 
 
13
  <tr><th>Enter a reason you're blocking this visitor pattern:</th><td><input id="wfReason" type="text" size="30" maxlength="255"></td></tr>
14
  <tr><td></td><td style="padding-bottom: 15px;"><strong>Why a reason:</strong> The reason you specify above is for your own record keeping.</td></tr>
15
  <tr><td colspan="2" style="padding-top: 15px;">
16
- <input type="button" name="but3" class="button-primary" value="Block Visitors Matching this Pattern" onclick="WFAD.blockIPUARange(jQuery('#ipRange').val(), jQuery('#uaRange').val(), jQuery('#wfReason').val()); return false;" />
17
  </td></tr>
18
  </table>
19
  </p>
@@ -31,7 +33,7 @@
31
  <tr><td>
32
  {{if patternDisabled}}
33
  <div style="width: 500px; margin-top: 20px;">
34
- <span style="color: #F00;">Pattern Below has been DISABLED:</span> Falcon engine does not support advanced blocks that include BOTH an IP address range AND a browser pattern.
35
  </div>
36
  <div style="color: #AAA;">
37
  {{/if}}
@@ -41,6 +43,9 @@
41
  <div>
42
  <strong>Browser Pattern:</strong>&nbsp;${browserPattern}
43
  </div>
 
 
 
44
  <div>
45
  <strong>Reason:</strong>&nbsp;${reason}
46
  </div>
@@ -53,7 +58,7 @@
53
  <ul>
54
  <li>${totalBlocked} blocked hits</li>
55
  {{if lastBlockedAgo}}
56
- <li>Last blocked: ${lastBlockedAgo} ago</li>
57
  {{/if}}
58
  </ul>
59
  </td></tr>
6
  <p>
7
  <?php if(! wfConfig::get('firewallEnabled')){ ?><div style="color: #F00; font-weight: bold;">Firewall is disabled. You can enable it on the <a href="admin.php?page=WordfenceSecOpt">Wordfence Options page</a> at the top.</div><br /><?php } ?>
8
  <table class="wfConfigForm">
9
+ <tr><th>IP address range:</th><td><input id="ipRange" type="text" size="30" maxlength="255" value="<?php if( isset( $_GET['wfBlockRange'] ) && $_GET['wfBlockRange']){ echo wp_kses($_GET['wfBlockRange'], array()); } ?>" onkeyup="WFAD.calcRangeTotal();">&nbsp;<span id="wfShowRangeTotal"></span></td></tr>
10
  <tr><td></td><td style="padding-bottom: 15px;"><strong>Examples:</strong> 192.168.200.200 - 192.168.200.220</td></tr>
11
+ <tr><th>User-Agent (browser) that matches:</th><td><input id="uaRange" type="text" size="30" maxlength="255" >&nbsp;(Case insensitive)</td></tr>
12
+ <tr><td></td><td style="padding-bottom: 15px;"><strong>Examples:</strong> *badRobot*, AnotherBadRobot*, *someBrowserSuffix</td></tr>
13
+ <tr><th>Referer (website visitor arrived from) that matches:</th><td><input id="wfreferer" type="text" size="30" maxlength="255" >&nbsp;(Case insensitive)</td></tr>
14
+ <tr><td></td><td style="padding-bottom: 15px;"><strong>Examples:</strong> *badWebsite*, AnotherBadWebsite*, *someWebsiteSuffix</td></tr>
15
  <tr><th>Enter a reason you're blocking this visitor pattern:</th><td><input id="wfReason" type="text" size="30" maxlength="255"></td></tr>
16
  <tr><td></td><td style="padding-bottom: 15px;"><strong>Why a reason:</strong> The reason you specify above is for your own record keeping.</td></tr>
17
  <tr><td colspan="2" style="padding-top: 15px;">
18
+ <input type="button" name="but3" class="button-primary" value="Block Visitors Matching this Pattern" onclick="WFAD.blockIPUARange(jQuery('#ipRange').val(), jQuery('#uaRange').val(), jQuery('#wfreferer').val(), jQuery('#wfReason').val()); return false;" />
19
  </td></tr>
20
  </table>
21
  </p>
33
  <tr><td>
34
  {{if patternDisabled}}
35
  <div style="width: 500px; margin-top: 20px;">
36
+ <span style="color: #F00;">Pattern Below has been DISABLED:</span> Falcon engine does not support advanced blocks that include combinations of IP range, browser pattern and referring website. You can only specify one of the three in patterns when using Falcon.
37
  </div>
38
  <div style="color: #AAA;">
39
  {{/if}}
43
  <div>
44
  <strong>Browser Pattern:</strong>&nbsp;${browserPattern}
45
  </div>
46
+ <div>
47
+ <strong>Source website:</strong>&nbsp;${refererPattern}
48
+ </div>
49
  <div>
50
  <strong>Reason:</strong>&nbsp;${reason}
51
  </div>
58
  <ul>
59
  <li>${totalBlocked} blocked hits</li>
60
  {{if lastBlockedAgo}}
61
+ <li>Last blocked: ${lastBlockedAgo}</li>
62
  {{/if}}
63
  </ul>
64
  </td></tr>
lib/wfCache.php CHANGED
@@ -601,10 +601,10 @@ EOT;
601
  $arr = explode('|', $r);
602
  $range = isset($arr[0]) ? $arr[0] : false;
603
  $browser = isset($arr[1]) ? $arr[1] : false;
 
604
 
605
- if($range && $browser){
606
- continue; //Don't process browser and range combos
607
- } else if($range){
608
  $ips = explode('-', $range);
609
  $cidrs = wfUtils::rangeToCIDRs($ips[0], $ips[1]);
610
  $hIPs = wfUtils::inet_ntoa($ips[0]) . ' - ' . wfUtils::inet_ntoa($ips[1]);
@@ -616,11 +616,19 @@ EOT;
616
  $lines[] = '#End of blocking code for IP range: ' . $hIPs . "\n";
617
  }
618
  } else if($browser){
 
619
  $browserLines[] = "\t#Blocking code for browser pattern: $browser\n";
620
  $browser = preg_replace('/([\-\_\.\+\!\@\#\$\%\^\&\(\)\[\]\{\}\/])/', "\\\\$1", $browser);
621
  $browser = preg_replace('/\*/', '.*', $browser);
622
  $browserLines[] = "\tSetEnvIf User-Agent " . $browser . " WordfenceBadBrowser=1\n";
623
  $browserAdded = true;
 
 
 
 
 
 
 
624
  }
625
  }
626
  }
601
  $arr = explode('|', $r);
602
  $range = isset($arr[0]) ? $arr[0] : false;
603
  $browser = isset($arr[1]) ? $arr[1] : false;
604
+ $referer = isset($arr[2]) ? $arr[2] : false;
605
 
606
+ if($range){
607
+ if($browser || $referer){ continue; } //We don't allow combos in falcon
 
608
  $ips = explode('-', $range);
609
  $cidrs = wfUtils::rangeToCIDRs($ips[0], $ips[1]);
610
  $hIPs = wfUtils::inet_ntoa($ips[0]) . ' - ' . wfUtils::inet_ntoa($ips[1]);
616
  $lines[] = '#End of blocking code for IP range: ' . $hIPs . "\n";
617
  }
618
  } else if($browser){
619
+ if($range || $referer){ continue; }
620
  $browserLines[] = "\t#Blocking code for browser pattern: $browser\n";
621
  $browser = preg_replace('/([\-\_\.\+\!\@\#\$\%\^\&\(\)\[\]\{\}\/])/', "\\\\$1", $browser);
622
  $browser = preg_replace('/\*/', '.*', $browser);
623
  $browserLines[] = "\tSetEnvIf User-Agent " . $browser . " WordfenceBadBrowser=1\n";
624
  $browserAdded = true;
625
+ } else if($referer){
626
+ if($browser || $range){ continue; }
627
+ $browserLines[] = "\t#Blocking code for referer pattern: $referer\n";
628
+ $referer = preg_replace('/([\-\_\.\+\!\@\#\$\%\^\&\(\)\[\]\{\}\/])/', "\\\\$1", $referer);
629
+ $referer = preg_replace('/\*/', '.*', $referer);
630
+ $browserLines[] = "\tSetEnvIf Referer " . $referer . " WordfenceBadBrowser=1\n";
631
+ $browserAdded = true;
632
  }
633
  }
634
  }
lib/wfLog.php CHANGED
@@ -234,7 +234,7 @@ class wfLog {
234
  if($elem['blockType'] != 'IU'){ continue; } //We only use IU type for now, but have this for future different block types.
235
  $elem['ctimeAgo'] = wfUtils::makeTimeAgo($elem['ctimeAgo']);
236
  if($elem['lastBlocked'] > 0){
237
- $elem['lastBlockedAgo'] = wfUtils::makeTimeAgo($elem['lastBlockedAgo']);
238
  } else {
239
  $elem['lastBlockedAgo'] = 'Never';
240
  }
@@ -242,8 +242,11 @@ class wfLog {
242
  $elem['ipPattern'] = "";
243
  $haveIPBlock = false;
244
  $haveBrowserBlock = false;
 
 
245
  if($blockDat[0]){
246
  $haveIPBlock = true;
 
247
  $ipDat = explode('-', $blockDat[0]);
248
  $elem['ipPattern'] = "Block visitors with IP addresses in the range: " . wfUtils::inet_ntoa($ipDat[0]) . ' - ' . wfUtils::inet_ntoa($ipDat[1]);
249
  } else {
@@ -251,11 +254,19 @@ class wfLog {
251
  }
252
  if($blockDat[1]){
253
  $haveBrowserBlock = true;
 
254
  $elem['browserPattern'] = "Block visitors whos browsers match the pattern: " . $blockDat[1];
255
  } else {
256
  $elem['browserPattern'] = 'Allow all browsers';
257
  }
258
- $elem['patternDisabled'] = (wfConfig::get('cacheType') == 'falcon' && $haveIPBlock && $haveBrowserBlock) ? true : false;
 
 
 
 
 
 
 
259
  }
260
  return $results;
261
  }
@@ -652,10 +663,12 @@ class wfLog {
652
  if($blockRec['blockType'] == 'IU'){
653
  $ipRangeBlocked = false;
654
  $uaPatternBlocked = false;
 
655
 
656
  $bDat = explode('|', $blockRec['blockString']);
657
  $ipRange = $bDat[0];
658
  $uaPattern = $bDat[1];
 
659
  if($ipRange){
660
  $ips = explode('-', $ipRange);
661
  if($IPnum >= $ips[0] && $IPnum <= $ips[1]){
@@ -667,23 +680,47 @@ class wfLog {
667
  $uaPatternBlocked = true;
668
  }
669
  }
670
- $rangeBlockReason = false;
 
 
 
 
 
 
 
 
 
 
671
  if($uaPattern && $ipRange){
672
  if($uaPatternBlocked && $ipRangeBlocked){
673
- $rangeBlockReason = "Advanced pattern blocking in effect.";
 
 
 
 
 
 
 
 
 
 
674
  }
675
  } else if($uaPattern){
676
  if($uaPatternBlocked){
677
- $rangeBlockReason = "Advanced pattern blocking in effect.";
678
  }
679
  } else if($ipRange){
680
  if($ipRangeBlocked){
681
- $rangeBlockReason = "Advanced pattern blocking in effect.";
 
 
 
 
682
  }
683
  }
684
- if($rangeBlockReason){
685
  $this->getDB()->queryWrite("update " . $this->ipRangesTable . " set totalBlocked = totalBlocked + 1, lastBlocked = unix_timestamp() where id=%d", $blockRec['id']);
686
- $this->do503(3600, $rangeBlockReason);
687
  }
688
  }
689
  }
234
  if($elem['blockType'] != 'IU'){ continue; } //We only use IU type for now, but have this for future different block types.
235
  $elem['ctimeAgo'] = wfUtils::makeTimeAgo($elem['ctimeAgo']);
236
  if($elem['lastBlocked'] > 0){
237
+ $elem['lastBlockedAgo'] = wfUtils::makeTimeAgo($elem['lastBlockedAgo']) . ' ago';
238
  } else {
239
  $elem['lastBlockedAgo'] = 'Never';
240
  }
242
  $elem['ipPattern'] = "";
243
  $haveIPBlock = false;
244
  $haveBrowserBlock = false;
245
+ $haveRefererBlock = false;
246
+ $numBlockElements = 0;
247
  if($blockDat[0]){
248
  $haveIPBlock = true;
249
+ $numBlockElements++;
250
  $ipDat = explode('-', $blockDat[0]);
251
  $elem['ipPattern'] = "Block visitors with IP addresses in the range: " . wfUtils::inet_ntoa($ipDat[0]) . ' - ' . wfUtils::inet_ntoa($ipDat[1]);
252
  } else {
254
  }
255
  if($blockDat[1]){
256
  $haveBrowserBlock = true;
257
+ $numBlockElements++;
258
  $elem['browserPattern'] = "Block visitors whos browsers match the pattern: " . $blockDat[1];
259
  } else {
260
  $elem['browserPattern'] = 'Allow all browsers';
261
  }
262
+ if($blockDat[2]){
263
+ $haveRefererBlock = true;
264
+ $numBlockElements++;
265
+ $elem['refererPattern'] = "Block visitors from websites that match the pattern: " . $blockDat[2];
266
+ } else {
267
+ $elem['refererPattern'] = "Allow visitors arriving from all websites";
268
+ }
269
+ $elem['patternDisabled'] = (wfConfig::get('cacheType') == 'falcon' && $numBlockElements > 1) ? true : false;
270
  }
271
  return $results;
272
  }
663
  if($blockRec['blockType'] == 'IU'){
664
  $ipRangeBlocked = false;
665
  $uaPatternBlocked = false;
666
+ $refBlocked = false;
667
 
668
  $bDat = explode('|', $blockRec['blockString']);
669
  $ipRange = $bDat[0];
670
  $uaPattern = $bDat[1];
671
+ $refPattern = $bDat[2];
672
  if($ipRange){
673
  $ips = explode('-', $ipRange);
674
  if($IPnum >= $ips[0] && $IPnum <= $ips[1]){
680
  $uaPatternBlocked = true;
681
  }
682
  }
683
+ if($refPattern){
684
+ if(wfUtils::isRefererBlocked($refPattern)){
685
+ $refBlocked = true;
686
+ }
687
+ }
688
+ $doBlock = false;
689
+ if($uaPattern && $ipRange && $refPattern){
690
+ if($uaPatternBlocked && $ipRangeBlocked && $refBlocked){
691
+ $doBlock = true;
692
+ }
693
+ }
694
  if($uaPattern && $ipRange){
695
  if($uaPatternBlocked && $ipRangeBlocked){
696
+ $doBlock = true;
697
+ }
698
+ }
699
+ if($uaPattern && $refPattern){
700
+ if($uaPatternBlocked && $refBlocked){
701
+ $doBlock = true;
702
+ }
703
+ }
704
+ if($ipRange && $refPattern){
705
+ if($ipRangeBlocked && $refBlocked){
706
+ $doBlock = true;
707
  }
708
  } else if($uaPattern){
709
  if($uaPatternBlocked){
710
+ $doBlock = true;
711
  }
712
  } else if($ipRange){
713
  if($ipRangeBlocked){
714
+ $doBlock = true;
715
+ }
716
+ } else if($refPattern){
717
+ if($refBlocked){
718
+ $doBlock = true;
719
  }
720
  }
721
+ if($doBlock){
722
  $this->getDB()->queryWrite("update " . $this->ipRangesTable . " set totalBlocked = totalBlocked + 1, lastBlocked = unix_timestamp() where id=%d", $blockRec['id']);
723
+ $this->do503(3600, "Advanced blocking in effect.");
724
  }
725
  }
726
  }
lib/wfUtils.php CHANGED
@@ -584,6 +584,9 @@ class wfUtils {
584
  public static function isUABlocked($uaPattern){ // takes a pattern using asterisks as wildcards, turns it into regex and checks it against the visitor UA returning true if blocked
585
  return fnmatch($uaPattern, $_SERVER['HTTP_USER_AGENT'], FNM_CASEFOLD);
586
  }
 
 
 
587
  public static function rangeToCIDRs($startIP, $endIP){
588
  $startIPBin = sprintf('%032b', $startIP);
589
  $endIPBin = sprintf('%032b', $endIP);
584
  public static function isUABlocked($uaPattern){ // takes a pattern using asterisks as wildcards, turns it into regex and checks it against the visitor UA returning true if blocked
585
  return fnmatch($uaPattern, $_SERVER['HTTP_USER_AGENT'], FNM_CASEFOLD);
586
  }
587
+ public static function isRefererBlocked($refPattern){
588
+ return fnmatch($refPattern, $_SERVER['HTTP_REFERER'], FNM_CASEFOLD);
589
+ }
590
  public static function rangeToCIDRs($startIP, $endIP){
591
  $startIPBin = sprintf('%032b', $startIP);
592
  $endIPBin = sprintf('%032b', $endIP);
lib/wordfenceClass.php CHANGED
@@ -1845,13 +1845,17 @@ class wordfence {
1845
  public static function ajax_blockIPUARange_callback(){
1846
  $ipRange = trim($_POST['ipRange']);
1847
  $uaRange = trim($_POST['uaRange']);
 
1848
  $reason = trim($_POST['reason']);
1849
- if(preg_match('/\|+/', $ipRange . $uaRange)){
1850
- return array('err' => 1, 'errorMsg' => "You are not allowed to include a pipe character \"|\" in your IP range or browser pattern");
1851
  }
1852
  if( (! $ipRange) && wfUtils::isUABlocked($uaRange)){
1853
  return array('err' => 1, 'errorMsg' => "The browser pattern you specified will block you from your own website. We have not accepted this pattern to protect you from being blocked.");
1854
  }
 
 
 
1855
  if($ipRange && (! preg_match('/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\-\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/', $ipRange ))){
1856
  return array('err' => 1, 'errorMsg' => "The IP range you specified is not valid. Please specify an IP range like the following example: \"1.2.3.4 - 1.2.3.8\" without quotes.");
1857
  }
@@ -1868,7 +1872,7 @@ class wordfence {
1868
  }
1869
  $ipRange = $ip1 . '-' . $ip2;
1870
  }
1871
- $range = $ipRange . '|' . $uaRange;
1872
  self::getLog()->blockRange('IU', $range, $reason);
1873
  return array('ok' => 1);
1874
  }
@@ -2645,7 +2649,6 @@ EOL;
2645
  public static function menu_whois(){
2646
  require 'menu_whois.php';
2647
  }
2648
-
2649
  public static function menu_rangeBlocking(){
2650
  require 'menu_rangeBlocking.php';
2651
  }
@@ -2897,6 +2900,25 @@ EOL;
2897
  //PUBLIC API
2898
  public static function doNotCache(){ //Call this to prevent Wordfence from caching the current page.
2899
  wfCache::doNotCache();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2900
  }
2901
  }
2902
  ?>
1845
  public static function ajax_blockIPUARange_callback(){
1846
  $ipRange = trim($_POST['ipRange']);
1847
  $uaRange = trim($_POST['uaRange']);
1848
+ $referer = trim($_POST['referer']);
1849
  $reason = trim($_POST['reason']);
1850
+ if(preg_match('/\|+/', $ipRange . $uaRange . $referer)){
1851
+ return array('err' => 1, 'errorMsg' => "You are not allowed to include a pipe character \"|\" in your IP range, browser pattern or referer");
1852
  }
1853
  if( (! $ipRange) && wfUtils::isUABlocked($uaRange)){
1854
  return array('err' => 1, 'errorMsg' => "The browser pattern you specified will block you from your own website. We have not accepted this pattern to protect you from being blocked.");
1855
  }
1856
+ if(fnmatch($referer, site_url(), FNM_CASEFOLD)){
1857
+ return array('err' => 1, 'errorMsg' => "The referer pattern you specified matches your own website and will block visitors as they surf from one page to another on your site. You can't enter this pattern.");
1858
+ }
1859
  if($ipRange && (! preg_match('/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\-\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/', $ipRange ))){
1860
  return array('err' => 1, 'errorMsg' => "The IP range you specified is not valid. Please specify an IP range like the following example: \"1.2.3.4 - 1.2.3.8\" without quotes.");
1861
  }
1872
  }
1873
  $ipRange = $ip1 . '-' . $ip2;
1874
  }
1875
+ $range = $ipRange . '|' . $uaRange . '|' . $referer;
1876
  self::getLog()->blockRange('IU', $range, $reason);
1877
  return array('ok' => 1);
1878
  }
2649
  public static function menu_whois(){
2650
  require 'menu_whois.php';
2651
  }
 
2652
  public static function menu_rangeBlocking(){
2653
  require 'menu_rangeBlocking.php';
2654
  }
2900
  //PUBLIC API
2901
  public static function doNotCache(){ //Call this to prevent Wordfence from caching the current page.
2902
  wfCache::doNotCache();
2903
+ return true;
2904
+ }
2905
+ public static function whitelistIP($IP){ //IP as a string in dotted quad notation e.g. '10.11.12.13'
2906
+ $IP = trim($IP);
2907
+ if(! preg_match('/^[\[\]\-\d]+\.[\[\]\-\d]+\.[\[\]\-\d]+\.[\[\]\-\d]+$/', $IP)){
2908
+ throw new Exception("The IP you provided must be in dotted quad notation or use ranges with square brackets. e.g. 10.11.12.13 or 10.11.12.[1-50]");
2909
+ }
2910
+ $whites = wfConfig::get('whitelisted', '');
2911
+ $arr = explode(',', $whites);
2912
+ $arr2 = array();
2913
+ foreach($arr as $e){
2914
+ if($e == $IP){
2915
+ return false;
2916
+ }
2917
+ $arr2[] = trim($e);
2918
+ }
2919
+ $arr2[] = $IP;
2920
+ wfConfig::set('whitelisted', implode(',', $arr2));
2921
+ return true;
2922
  }
2923
  }
2924
  ?>
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, woocommerce support, woocommerce caching
4
  Requires at least: 3.3.1
5
  Tested up to: 4.0
6
- Stable tag: 5.3.1
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
 
@@ -165,6 +165,10 @@ cause a security hole on your site.
165
 
166
  == Changelog ==
167
 
 
 
 
 
168
  = 5.3.1 =
169
  * IP to Country database updated to November 4th 2014 version.
170
  * Options export and import now also exports Country Blocking and Scan Schedule configuration.
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, woocommerce support, woocommerce caching
4
  Requires at least: 3.3.1
5
  Tested up to: 4.0
6
+ Stable tag: 5.3.2
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
 
165
 
166
  == Changelog ==
167
 
168
+ = 5.3.2 =
169
+ * Feature: Advanced blocking now includes referer blocking. i.e. you can block visitors arriving from certain websites or pretending to. See updated http://docs.wordfence.com/en/Advanced_Blocking
170
+ * Feature: Developers, you can now ask Wordfence to whitelist your server IP by calling wordfence::whitelistIP(). See http://docs.wordfence.com/en/WhitelistIP
171
+
172
  = 5.3.1 =
173
  * IP to Country database updated to November 4th 2014 version.
174
  * Options export and import now also exports Country Blocking and Scan Schedule configuration.
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 High Speed Cache
6
  Author: Wordfence
7
- Version: 5.3.1
8
  Author URI: http://www.wordfence.com/
9
  */
10
  if(defined('WP_INSTALLING') && WP_INSTALLING){
11
  return;
12
  }
13
- define('WORDFENCE_VERSION', '5.3.1');
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 High Speed Cache
6
  Author: Wordfence
7
+ Version: 5.3.2
8
  Author URI: http://www.wordfence.com/
9
  */
10
  if(defined('WP_INSTALLING') && WP_INSTALLING){
11
  return;
12
  }
13
+ define('WORDFENCE_VERSION', '5.3.2');
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
  }