Wordfence Security – Firewall & Malware Scan - Version 4.0.1

Version Description

  • Real-time WordPress Security Network Launched.
  • If another site is attacked and blocks the attacker, your site also blocks the attacker. Shared data among Wordfence sites.
  • See our home page on www.wordfence.com for a live map of attacks being blocked. Then blog about us!!
  • Fixed bug where wfBrowscapCache.php is reported as malicious.
  • Big improvement in scanning speed and efficiency of URL's and IP addresses.
  • Fixed preg_replace() warning by using newer preg_replace_callback() func.
Download this release

Release Info

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

Code changes from version 3.9.1 to 4.0.1

lib/menu_options.php CHANGED
@@ -246,7 +246,7 @@ var WFSLevels = <?php echo json_encode(wfConfig::$securityLevels); ?>;
246
  <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>
247
  <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>
248
  <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>
249
- <tr><th>Participate in the Wordfence Security Network</th><td><input type="checkbox" id="other_WFNet" class="wfConfigElem" name="other_WFNet" value="1" <?php $w->cb('other_WFNet'); ?> /></td></tr>
250
  <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>
251
  <tr><th>Maximum execution time for each scan stage</th><td><input type="text" id="maxExecutionTime" name="maxExecutionTime" value="<?php $w->f('maxExecutionTime'); ?>" size="4" />Blank for default. Must be greater than 9.</td></tr>
252
  <tr><th>Update interval in seconds (2 is default)</th><td><input type="text" id="actUpdateInterval" name="actUpdateInterval" value="<?php $w->f('actUpdateInterval'); ?>" size="4" />Setting higher will reduce browser traffic but slow scan starts, live traffic &amp; status updates.</td></tr>
246
  <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>
247
  <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>
248
  <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>
249
+ <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>
250
  <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>
251
  <tr><th>Maximum execution time for each scan stage</th><td><input type="text" id="maxExecutionTime" name="maxExecutionTime" value="<?php $w->f('maxExecutionTime'); ?>" size="4" />Blank for default. Must be greater than 9.</td></tr>
252
  <tr><th>Update interval in seconds (2 is default)</th><td><input type="text" id="actUpdateInterval" name="actUpdateInterval" value="<?php $w->f('actUpdateInterval'); ?>" size="4" />Setting higher will reduce browser traffic but slow scan starts, live traffic &amp; status updates.</td></tr>
lib/wfLog.php CHANGED
@@ -204,27 +204,36 @@ class wfLog {
204
  }
205
  return $results;
206
  }
207
- public function blockIP($IP, $reason, $wfsn = false, $permanent = false){ //wfsn indicates it comes from Wordfence secure network
208
  if($this->isWhitelisted($IP)){ return false; }
209
  $wfsn = $wfsn ? 1 : 0;
 
 
 
 
 
210
  if($permanent){
211
  //Insert permanent=1 or update existing perm or non-per block to be permanent
212
- $this->getDB()->queryWrite("insert into " . $this->blocksTable . " (IP, blockedTime, reason, wfsn, permanent) values (%s, unix_timestamp(), '%s', %d, %d) ON DUPLICATE KEY update blockedTime=unix_timestamp(), reason='%s', wfsn=%d, permanent=%d",
213
  wfUtils::inet_aton($IP),
 
214
  $reason,
215
  $wfsn,
216
  1,
 
217
  $reason,
218
  $wfsn,
219
  1
220
  );
221
  } else {
222
  //insert perm=0 but don't update and make perm blocks non-perm.
223
- $this->getDB()->queryWrite("insert into " . $this->blocksTable . " (IP, blockedTime, reason, wfsn, permanent) values (%s, unix_timestamp(), '%s', %d, %d) ON DUPLICATE KEY update blockedTime=unix_timestamp(), reason='%s', wfsn=%d",
224
  wfUtils::inet_aton($IP),
 
225
  $reason,
226
  $wfsn,
227
  0,
 
228
  $reason,
229
  $wfsn
230
  );
@@ -627,6 +636,9 @@ class wfLog {
627
  $this->getDB()->queryWrite("update " . $this->blocksTable . " set lastAttempt=unix_timestamp(), blockedHits = blockedHits + 1 where IP=%s", $IPnum);
628
  $now = $this->getDB()->querySingle("select unix_timestamp()");
629
  $secsToGo = ($rec['blockedTime'] + wfConfig::get('blockedTime')) - $now;
 
 
 
630
  $this->do503($secsToGo, $rec['reason']);
631
  }
632
  }
204
  }
205
  return $results;
206
  }
207
+ public function blockIP($IP, $reason, $wfsn = false, $permanent = false, $maxTimeBlocked = false){ //wfsn indicates it comes from Wordfence secure network
208
  if($this->isWhitelisted($IP)){ return false; }
209
  $wfsn = $wfsn ? 1 : 0;
210
+ $timeBlockOccurred = $this->getDB()->querySingle("select unix_timestamp() as ctime");
211
+ $durationOfBlocks = wfConfig::get('blockedTime');
212
+ if($maxTimeBlocked && $durationOfBlocks > $maxTimeBlocked){
213
+ $timeBlockOccurred -= ($durationOfBlocks - $maxTimeBlocked);
214
+ }
215
  if($permanent){
216
  //Insert permanent=1 or update existing perm or non-per block to be permanent
217
+ $this->getDB()->queryWrite("insert into " . $this->blocksTable . " (IP, blockedTime, reason, wfsn, permanent) values (%s, %d, '%s', %d, %d) ON DUPLICATE KEY update blockedTime=%d, reason='%s', wfsn=%d, permanent=%d",
218
  wfUtils::inet_aton($IP),
219
+ $timeBlockOccurred,
220
  $reason,
221
  $wfsn,
222
  1,
223
+ $timeBlockOccurred,
224
  $reason,
225
  $wfsn,
226
  1
227
  );
228
  } else {
229
  //insert perm=0 but don't update and make perm blocks non-perm.
230
+ $this->getDB()->queryWrite("insert into " . $this->blocksTable . " (IP, blockedTime, reason, wfsn, permanent) values (%s, %d, '%s', %d, %d) ON DUPLICATE KEY update blockedTime=%d, reason='%s', wfsn=%d",
231
  wfUtils::inet_aton($IP),
232
+ $timeBlockOccurred,
233
  $reason,
234
  $wfsn,
235
  0,
236
+ $timeBlockOccurred,
237
  $reason,
238
  $wfsn
239
  );
636
  $this->getDB()->queryWrite("update " . $this->blocksTable . " set lastAttempt=unix_timestamp(), blockedHits = blockedHits + 1 where IP=%s", $IPnum);
637
  $now = $this->getDB()->querySingle("select unix_timestamp()");
638
  $secsToGo = ($rec['blockedTime'] + wfConfig::get('blockedTime')) - $now;
639
+ if(wfConfig::get('other_WFNet') && strpos($_SERVER['REQUEST_URI'], '/wp-login.php') !== false){ //We're on the login page and this IP has been blocked
640
+ wordfence::wfsnReportBlockedAttempt($IP, 'login');
641
+ }
642
  $this->do503($secsToGo, $rec['reason']);
643
  }
644
  }
lib/wfScanEngine.php CHANGED
@@ -119,7 +119,7 @@ class wfScanEngine {
119
  $this->status(1, 'info', '-------------------');
120
  $this->status(1, 'info', "Scan Complete. Scanned " . $summary['totalFiles'] . " files, " . $summary['totalPlugins'] . " plugins, " . $summary['totalThemes'] . " themes, " . ($summary['totalPages'] + $summary['totalPosts']) . " pages, " . $summary['totalComments'] . " comments and " . $summary['totalRows'] . " records in " . (time() - $this->startTime) . " seconds.");
121
  if($this->i->totalIssues > 0){
122
- $this->status(10, 'info', "SUM_FINAL:Scan complete. You have " . $this->i->totalIssues . " new issues to fix. See below for details.");
123
  } else {
124
  $this->status(10, 'info', "SUM_FINAL:Scan complete. Congratulations, there were no problems found.");
125
  }
119
  $this->status(1, 'info', '-------------------');
120
  $this->status(1, 'info', "Scan Complete. Scanned " . $summary['totalFiles'] . " files, " . $summary['totalPlugins'] . " plugins, " . $summary['totalThemes'] . " themes, " . ($summary['totalPages'] + $summary['totalPosts']) . " pages, " . $summary['totalComments'] . " comments and " . $summary['totalRows'] . " records in " . (time() - $this->startTime) . " seconds.");
121
  if($this->i->totalIssues > 0){
122
+ $this->status(10, 'info', "SUM_FINAL:Scan complete. You have " . $this->i->totalIssues . " new issues to fix. See below.");
123
  } else {
124
  $this->status(10, 'info', "SUM_FINAL:Scan complete. Congratulations, there were no problems found.");
125
  }
lib/wordfenceClass.php CHANGED
@@ -609,8 +609,11 @@ class wordfence {
609
  if(self::getLog()->isWhitelisted($IP)){
610
  return $authResult;
611
  }
612
- if(is_wp_error($authResult) && ($authResult->get_error_code() == 'invalid_username' || $authResult->get_error_code() == 'incorrect_password') && wfConfig::get('loginSec_maskLoginErrors')){
613
- self::reportHackAttempt($IP, 'brute');
 
 
 
614
  }
615
  if($secEnabled){
616
  if(is_wp_error($authResult) && $authResult->get_error_code() == 'invalid_username' && wfConfig::get('loginSec_lockInvalidUsers')){
@@ -639,16 +642,39 @@ class wordfence {
639
  }
640
  return $authResult;
641
  }
642
- private static function reportHackAttempt($IP, $type){
643
- $curl = curl_init('http://noc3.wordfence.com:9050/hackAttempt/?k=' . wfConfig::get('apiKey') . '&IP=' . wfUtils::inet_aton($IP) . '&t=' . $type );
644
- curl_setopt($curl, CURLOPT_TIMEOUT, 1);
645
- curl_setopt ($curl, CURLOPT_USERAGENT, "Wordfence.com UA " . (defined('WORDFENCE_VERSION') ? WORDFENCE_VERSION : '[Unknown version]') );
646
- curl_setopt ($curl, CURLOPT_RETURNTRANSFER, TRUE);
647
- curl_setopt ($curl, CURLOPT_HEADER, 0);
648
- curl_setopt ($curl, CURLOPT_SSL_VERIFYPEER, false);
649
- curl_setopt ($curl, CURLOPT_SSL_VERIFYHOST, false);
650
- curl_setopt($curl, CURLOPT_POST, false);
651
- curl_exec($curl);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
652
  }
653
  public static function logoutAction(){
654
  $userID = get_current_user_id();
609
  if(self::getLog()->isWhitelisted($IP)){
610
  return $authResult;
611
  }
612
+ if(wfConfig::get('other_WFNet') && is_wp_error($authResult) && ($authResult->get_error_code() == 'invalid_username' || $authResult->get_error_code() == 'incorrect_password') && wfConfig::get('loginSec_maskLoginErrors')){
613
+ if($maxBlockTime = self::wfsnIsBlocked($IP, 'brute')){
614
+ self::getLog()->blockIP($IP, "Blocked by Wordfence Security Network", true, false, $maxBlockTime);
615
+ }
616
+
617
  }
618
  if($secEnabled){
619
  if(is_wp_error($authResult) && $authResult->get_error_code() == 'invalid_username' && wfConfig::get('loginSec_lockInvalidUsers')){
642
  }
643
  return $authResult;
644
  }
645
+ public static function wfsnReportBlockedAttempt($IP, $type){
646
+ try {
647
+ $curl = curl_init('http://noc3.wordfence.com:9050/hackAttempt/?blocked=1&k=' . wfConfig::get('apiKey') . '&IP=' . wfUtils::inet_aton($IP) . '&t=' . $type );
648
+ curl_setopt($curl, CURLOPT_TIMEOUT, 1);
649
+ curl_setopt ($curl, CURLOPT_USERAGENT, "Wordfence.com UA " . (defined('WORDFENCE_VERSION') ? WORDFENCE_VERSION : '[Unknown version]') );
650
+ curl_setopt ($curl, CURLOPT_RETURNTRANSFER, TRUE);
651
+ curl_setopt ($curl, CURLOPT_HEADER, 0);
652
+ curl_setopt ($curl, CURLOPT_SSL_VERIFYPEER, false);
653
+ curl_setopt ($curl, CURLOPT_SSL_VERIFYHOST, false);
654
+ curl_setopt($curl, CURLOPT_POST, false);
655
+ curl_exec($curl);
656
+ } catch(Exception $err){
657
+ return false;
658
+ }
659
+ }
660
+ private static function wfsnIsBlocked($IP, $type){
661
+ try {
662
+ $curl = curl_init('http://noc3.wordfence.com:9050/hackAttempt/?k=' . wfConfig::get('apiKey') . '&IP=' . wfUtils::inet_aton($IP) . '&t=' . $type );
663
+ curl_setopt($curl, CURLOPT_TIMEOUT, 3);
664
+ curl_setopt ($curl, CURLOPT_USERAGENT, "Wordfence.com UA " . (defined('WORDFENCE_VERSION') ? WORDFENCE_VERSION : '[Unknown version]') );
665
+ curl_setopt ($curl, CURLOPT_RETURNTRANSFER, TRUE);
666
+ curl_setopt ($curl, CURLOPT_HEADER, 0);
667
+ curl_setopt ($curl, CURLOPT_SSL_VERIFYPEER, false);
668
+ curl_setopt ($curl, CURLOPT_SSL_VERIFYHOST, false);
669
+ curl_setopt($curl, CURLOPT_POST, false);
670
+ $result = curl_exec($curl);
671
+ if(preg_match('/BLOCKED:(\d+)/', $result, $matches) && (! self::getLog()->isWhitelisted($IP)) ){
672
+ return $matches[1];
673
+ }
674
+ return false;
675
+ } catch(Exception $err){
676
+ return false;
677
+ }
678
  }
679
  public static function logoutAction(){
680
  $userID = get_current_user_id();
lib/wordfenceScanner.php CHANGED
@@ -215,6 +215,9 @@ class wordfenceScanner {
215
  $this->urlHoover->cleanup();
216
  foreach($hooverResults as $file => $hresults){
217
  foreach($hresults as $result){
 
 
 
218
  if($result['badList'] == 'goog-malware-shavar'){
219
  $this->addResult(array(
220
  'type' => 'file',
215
  $this->urlHoover->cleanup();
216
  foreach($hooverResults as $file => $hresults){
217
  foreach($hresults as $result){
218
+ if(preg_match('/wfBrowscapCache\.php$/', $file)){
219
+ continue;
220
+ }
221
  if($result['badList'] == 'goog-malware-shavar'){
222
  $this->addResult(array(
223
  'type' => 'file',
lib/wordfenceURLHoover.php CHANGED
@@ -11,6 +11,7 @@ class wordfenceURLHoover {
11
  private $useDB = true;
12
  private $hostKeys = array();
13
  private $hostList = array();
 
14
  private $dRegex = 'aero|asia|biz|cat|com|coop|edu|gov|info|int|jobs|mil|mobi|museum|name|net|org|pro|tel|travel|xxx|ac|ad|ae|af|ag|ai|al|am|an|ao|aq|ar|as|at|au|aw|ax|az|ba|bb|bd|be|bf|bg|bh|bi|bj|bm|bn|bo|br|bs|bt|bv|bw|by|bz|ca|cc|cd|cf|cg|ch|ci|ck|cl|cm|cn|co|cr|cs|cu|cv|cx|cy|cz|dd|de|dj|dk|dm|do|dz|ec|ee|eg|eh|er|es|et|eu|fi|fj|fk|fm|fo|fr|ga|gb|gd|ge|gf|gg|gh|gi|gl|gm|gn|gp|gq|gr|gs|gt|gu|gw|gy|hk|hm|hn|hr|ht|hu|id|ie|il|im|in|io|iq|ir|is|it|je|jm|jo|jp|ke|kg|kh|ki|km|kn|kp|kr|kw|ky|kz|la|lb|lc|li|lk|lr|ls|lt|lu|lv|ly|ma|mc|md|me|mg|mh|mk|ml|mm|mn|mo|mp|mq|mr|ms|mt|mu|mv|mw|mx|my|mz|na|nc|ne|nf|ng|ni|nl|no|np|nr|nu|nz|om|pa|pe|pf|pg|ph|pk|pl|pm|pn|pr|ps|pt|pw|py|qa|re|ro|rs|ru|rw|sa|sb|sc|sd|se|sg|sh|si|sj|sk|sl|sm|sn|so|sr|ss|st|su|sv|sy|sz|tc|td|tf|tg|th|tj|tk|tl|tm|tn|to|tp|tr|tt|tv|tw|tz|ua|ug|uk|us|uy|uz|va|vc|ve|vg|vi|vn|vu|wf|ws|ye|yt|za|zm|zw|xn--lgbbat1ad8j|xn--fiqs8s|xn--fiqz9s|xn--wgbh1c|xn--j6w193g|xn--h2brj9c|xn--mgbbh1a71e|xn--fpcrj9c3d|xn--gecrj9c|xn--s9brj9c|xn--xkc2dl3a5ee0h|xn--45brj9c|xn--mgba3a4f16a|xn--mgbayh7gpa|xn--mgbc0a9azcg|xn--ygbi2ammx|xn--wgbl6a|xn--p1ai|xn--mgberp4a5d4ar|xn--90a3ac|xn--yfro4i67o|xn--clchc0ea0b2g2a9gcd|xn--3e0b707e|xn--fzc2c9e2c|xn--xkc2al3hye2a|xn--mgbtf8fl|xn--kprw13d|xn--kpry57d|xn--o3cw4h|xn--pgbs0dh|xn--mgbaam7a8h|xn--54b7fta0cc|xn--90ae|xn--node|xn--4dbrk0ce|xn--80ao21a|xn--mgb9awbf|xn--mgbai9azgqp6j|xn--j1amh|xn--mgb2ddes|xn--kgbechtv|xn--hgbk6aj7f53bba|xn--0zwm56d|xn--g6w251d|xn--80akhbyknj4f|xn--11b5bs3a9aj6g|xn--jxalpdlp|xn--9t4b11yi5a|xn--deba0ad|xn--zckzah|xn--hlcj6aya9esc7a';
15
  private $api = false;
16
  private $db = false;
@@ -48,12 +49,17 @@ class wordfenceURLHoover {
48
  if(strpos($data, '.') === false){
49
  return;
50
  }
 
51
  try {
52
- @preg_replace("/(?<=^|[^a-zA-Z0-9\-])((?:[a-zA-Z0-9\-]+\.)+)(" . $this->dRegex . ")((?:$|[^a-zA-Z0-9\-\.\'\"])[^\r\n\s\t\"\'\$\{\}<>]*)/ie", "\$this->" . "addHost(\$id, '$1$2', '$3')", $data);
 
 
53
  } catch(Exception $e){
54
  //error_log("Regex error 1: $e");
55
  }
56
- @preg_replace("/(?<=[^\d]|^)(\d{8,10}|\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})([^\d\'\"][^\r\n\s\t\"\'\$\{\}<>]*)/e", "\$this->" . "addIP(\$id, \"$1\",\"$2\")", $data);
 
 
57
  $this->writeHosts();
58
  }
59
  private function dbg($msg){
@@ -61,7 +67,10 @@ class wordfenceURLHoover {
61
  //error_log("DEBUG: $msg\n");
62
  }
63
  }
64
- public function addHost($id, $host, $path){
 
 
 
65
  if(strpos($path, '/') !== 0){
66
  $path = '/';
67
  } else {
@@ -80,33 +89,35 @@ class wordfenceURLHoover {
80
  }
81
  if($this->hostsToAdd->size() > 1000){ $this->writeHosts(); }
82
  }
83
- public function addIP($id, $ipdata, $path){
 
 
 
84
  $this->dbg("Add IP called with $ipdata $path");
85
- if(strpos($path, '/') !== 0){
86
- $path = '/';
87
- } else {
88
- $path = preg_replace_callback('/([^A-Za-z0-9\-\.\_\~:\/\?\#\[\]\@\!\$\&\'\(\)\*\+\,;\=]+)/', 'wordfenceURLHoover::urlenc', $path);
89
- }
90
- if(strstr($ipdata, '.') === false && $ipdata >= 16777216 && $ipdata <= 4026531840){
91
- $ipdata = long2ip($ipdata);
92
  }
93
  $parts = explode('.', $ipdata);
94
- $isValid = true;
95
- if($parts[0] >= 240 || $parts[0] == '10' || $parts[0] == '172' || $parts[0] == '192' || $parts[0] == '127'){
96
- $isValid = false;
97
- }
98
- if($isValid){
99
- foreach($parts as $part){
100
- if($part < 1 || $part > 255){
101
- $isValid = false;
102
- }
103
  }
104
  }
105
- if($isValid && $ipdata){
106
- $hostKey = substr(hash('sha256', $ipdata . '/', true), 0, 4);
107
- $this->hostsToAdd->push(array('owner' => $id, 'host' => $ipdata, 'path' => $path, 'hostKey' => $hostKey));
108
- if($this->hostsToAdd->size() > 1000){ $this->writeHosts(); }
 
 
 
109
  }
 
 
 
110
  }
111
  public static function urlenc($m){
112
  return urlencode($m[1]);
11
  private $useDB = true;
12
  private $hostKeys = array();
13
  private $hostList = array();
14
+ public $currentHooverID = false;
15
  private $dRegex = 'aero|asia|biz|cat|com|coop|edu|gov|info|int|jobs|mil|mobi|museum|name|net|org|pro|tel|travel|xxx|ac|ad|ae|af|ag|ai|al|am|an|ao|aq|ar|as|at|au|aw|ax|az|ba|bb|bd|be|bf|bg|bh|bi|bj|bm|bn|bo|br|bs|bt|bv|bw|by|bz|ca|cc|cd|cf|cg|ch|ci|ck|cl|cm|cn|co|cr|cs|cu|cv|cx|cy|cz|dd|de|dj|dk|dm|do|dz|ec|ee|eg|eh|er|es|et|eu|fi|fj|fk|fm|fo|fr|ga|gb|gd|ge|gf|gg|gh|gi|gl|gm|gn|gp|gq|gr|gs|gt|gu|gw|gy|hk|hm|hn|hr|ht|hu|id|ie|il|im|in|io|iq|ir|is|it|je|jm|jo|jp|ke|kg|kh|ki|km|kn|kp|kr|kw|ky|kz|la|lb|lc|li|lk|lr|ls|lt|lu|lv|ly|ma|mc|md|me|mg|mh|mk|ml|mm|mn|mo|mp|mq|mr|ms|mt|mu|mv|mw|mx|my|mz|na|nc|ne|nf|ng|ni|nl|no|np|nr|nu|nz|om|pa|pe|pf|pg|ph|pk|pl|pm|pn|pr|ps|pt|pw|py|qa|re|ro|rs|ru|rw|sa|sb|sc|sd|se|sg|sh|si|sj|sk|sl|sm|sn|so|sr|ss|st|su|sv|sy|sz|tc|td|tf|tg|th|tj|tk|tl|tm|tn|to|tp|tr|tt|tv|tw|tz|ua|ug|uk|us|uy|uz|va|vc|ve|vg|vi|vn|vu|wf|ws|ye|yt|za|zm|zw|xn--lgbbat1ad8j|xn--fiqs8s|xn--fiqz9s|xn--wgbh1c|xn--j6w193g|xn--h2brj9c|xn--mgbbh1a71e|xn--fpcrj9c3d|xn--gecrj9c|xn--s9brj9c|xn--xkc2dl3a5ee0h|xn--45brj9c|xn--mgba3a4f16a|xn--mgbayh7gpa|xn--mgbc0a9azcg|xn--ygbi2ammx|xn--wgbl6a|xn--p1ai|xn--mgberp4a5d4ar|xn--90a3ac|xn--yfro4i67o|xn--clchc0ea0b2g2a9gcd|xn--3e0b707e|xn--fzc2c9e2c|xn--xkc2al3hye2a|xn--mgbtf8fl|xn--kprw13d|xn--kpry57d|xn--o3cw4h|xn--pgbs0dh|xn--mgbaam7a8h|xn--54b7fta0cc|xn--90ae|xn--node|xn--4dbrk0ce|xn--80ao21a|xn--mgb9awbf|xn--mgbai9azgqp6j|xn--j1amh|xn--mgb2ddes|xn--kgbechtv|xn--hgbk6aj7f53bba|xn--0zwm56d|xn--g6w251d|xn--80akhbyknj4f|xn--11b5bs3a9aj6g|xn--jxalpdlp|xn--9t4b11yi5a|xn--deba0ad|xn--zckzah|xn--hlcj6aya9esc7a';
16
  private $api = false;
17
  private $db = false;
49
  if(strpos($data, '.') === false){
50
  return;
51
  }
52
+ $this->currentHooverID = $id;
53
  try {
54
+ @preg_replace_callback("/(?<=^|[^a-zA-Z0-9\-])((?:[a-zA-Z0-9\-]+\.)+)(" . $this->dRegex . ")($|[\r\n\s\t]|\/[^\r\n\s\t\"\'\$\{\}<>]*)/i", array($this, 'addHost'), $data);
55
+ //((?:$|[^a-zA-Z0-9\-\.\'\"])[^\r\n\s\t\"\'\$\{\}<>]*)
56
+ //"\$this->" . "addHost(\$id, '$1$2', '$3')", $data);
57
  } catch(Exception $e){
58
  //error_log("Regex error 1: $e");
59
  }
60
+ @preg_replace_callback("/(?<=[^\d]|^)(\d{8,10}|\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})($|[\r\n\s\t]|\/[^\r\n\s\t\"\'\$\{\}<>]*)/", array($this, 'addIP'), $data);
61
+ //([^\d\'\"][^\r\n\s\t\"\'\$\{\}<>]*)
62
+ //"\$this->" . "addIP(\$id, \"$1\",\"$2\")", $data);
63
  $this->writeHosts();
64
  }
65
  private function dbg($msg){
67
  //error_log("DEBUG: $msg\n");
68
  }
69
  }
70
+ public function addHost($matches){
71
+ $id = $this->currentHooverID;
72
+ $host = $matches[1] . $matches[2];
73
+ $path = $matches[3];
74
  if(strpos($path, '/') !== 0){
75
  $path = '/';
76
  } else {
89
  }
90
  if($this->hostsToAdd->size() > 1000){ $this->writeHosts(); }
91
  }
92
+ public function addIP($matches){
93
+ $id = $this->currentHooverID;
94
+ $ipdata = $matches[1];
95
+ $path = $matches[2];
96
  $this->dbg("Add IP called with $ipdata $path");
97
+ if(strstr($ipdata, '.') === false){
98
+ if($ipdata >= 16777216 && $ipdata <= 4026531840){
99
+ $ipdata = long2ip($ipdata);
100
+ } else {
101
+ return; //Is int but invalid address.
102
+ }
 
103
  }
104
  $parts = explode('.', $ipdata);
105
+ foreach($parts as $part){
106
+ if($part < 0 || $part > 255){
107
+ return;
 
 
 
 
 
 
108
  }
109
  }
110
+ if($parts[0] >= 240 || $parts[0] == '10' || $parts[0] == '172' || $parts[0] == '192' || $parts[0] == '127' || $parts[0] == 0){
111
+ return;
112
+ }
113
+ if(strlen($path) == 1){
114
+ $path = '/'; //Because it's either a whitespace char or a / anyway.
115
+ } else if(strlen($path) > 1){
116
+ $path = preg_replace_callback('/([^A-Za-z0-9\-\.\_\~:\/\?\#\[\]\@\!\$\&\'\(\)\*\+\,;\=]+)/', 'wordfenceURLHoover::urlenc', $path);
117
  }
118
+ $hostKey = substr(hash('sha256', $ipdata . '/', true), 0, 4);
119
+ $this->hostsToAdd->push(array('owner' => $id, 'host' => $ipdata, 'path' => $path, 'hostKey' => $hostKey));
120
+ if($this->hostsToAdd->size() > 1000){ $this->writeHosts(); }
121
  }
122
  public static function urlenc($m){
123
  return urlencode($m[1]);
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, 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
4
  Requires at least: 3.3.1
5
  Tested up to: 3.8
6
- Stable tag: 3.9.1
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
 
@@ -19,6 +19,7 @@ Wordfence Security is now Multi-Site compatible and includes Cellphone Sign-in w
19
 
20
  Wordfence Security:
21
 
 
22
  * Sign-in using your password and your cellphone to vastly improve login security. This is called Two Factor Authentication and is used by banks, government agencies and military world-wide for highest security authentication.
23
  * Includes two-factor authentication, also referred to as cellphone sign-in.
24
  * Enforce strong passwords among your administrators, publishers and users. Improve login security.
@@ -152,6 +153,15 @@ cause a security hole on your site.
152
 
153
  == Changelog ==
154
 
 
 
 
 
 
 
 
 
 
155
  = 3.9.1 =
156
  * Fixed issue that caused Wordfence security to not log 404's.
157
  * Made 404's more visible on the live traffic page.
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, 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
4
  Requires at least: 3.3.1
5
  Tested up to: 3.8
6
+ Stable tag: 4.0.1
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
 
19
 
20
  Wordfence Security:
21
 
22
+ * Real-time blocking of known attackers. If another site using Wordfence is attacked and blocks the attacker, your site is automatically protected.
23
  * Sign-in using your password and your cellphone to vastly improve login security. This is called Two Factor Authentication and is used by banks, government agencies and military world-wide for highest security authentication.
24
  * Includes two-factor authentication, also referred to as cellphone sign-in.
25
  * Enforce strong passwords among your administrators, publishers and users. Improve login security.
153
 
154
  == Changelog ==
155
 
156
+ = 4.0.1 =
157
+ * Real-time WordPress Security Network Launched.
158
+ * If another site is attacked and blocks the attacker, your site also blocks the attacker. Shared data among Wordfence sites.
159
+ * See our home page on www.wordfence.com for a live map of attacks being blocked. Then blog about us!!
160
+ * Fixed bug where wfBrowscapCache.php is reported as malicious.
161
+ * Big improvement in scanning speed and efficiency of URL's and IP addresses.
162
+ * Fixed preg_replace() warning by using newer preg_replace_callback() func.
163
+
164
+
165
  = 3.9.1 =
166
  * Fixed issue that caused Wordfence security to not log 404's.
167
  * Made 404's more visible on the live traffic page.
wordfence.php CHANGED
@@ -2,12 +2,12 @@
2
  /*
3
  Plugin Name: Wordfence Security
4
  Plugin URI: http://www.wordfence.com/
5
- Description: Wordfence Security - Anti-virus and Firewall security plugin for WordPress
6
  Author: Mark Maunder
7
- Version: 3.9.1
8
  Author URI: http://www.wordfence.com/
9
  */
10
- define('WORDFENCE_VERSION', '3.9.1');
11
  if(get_option('wordfenceActivated') != 1){
12
  add_action('activated_plugin','wordfence_save_activation_error'); function wordfence_save_activation_error(){ update_option('wf_plugin_act_error', ob_get_contents()); }
13
  }
2
  /*
3
  Plugin Name: Wordfence Security
4
  Plugin URI: http://www.wordfence.com/
5
+ Description: Wordfence Security - Anti-virus, Firewall and real-time WordPress security Network
6
  Author: Mark Maunder
7
+ Version: 4.0.1
8
  Author URI: http://www.wordfence.com/
9
  */
10
+ define('WORDFENCE_VERSION', '4.0.1');
11
  if(get_option('wordfenceActivated') != 1){
12
  add_action('activated_plugin','wordfence_save_activation_error'); function wordfence_save_activation_error(){ update_option('wf_plugin_act_error', ob_get_contents()); }
13
  }