Wordfence Security – Firewall & Malware Scan - Version 3.8.4

Version Description

  • Removed Wordfence .htaccess because it doesn't offer any security functionality and increases incompatibility.
  • Fixed spelling errors.
  • Added check to see if $_SERVER['HTTP_USER_AGENT'] is defined before using it to suppress large number of warnings on some sites.
  • Changed the way we call admin_url() to the correct syntax.
  • Correctly escaped HTML on error messages.
  • Fixed issue that generated non-compliant query string.
  • Updated GeoIP database to newest version.
Download this release

Release Info

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

Code changes from version 3.8.3 to 3.8.4

.htaccess DELETED
@@ -1,29 +0,0 @@
1
- <Files .htaccess>
2
- Order Allow,Deny
3
- Deny From All
4
- </Files>
5
- <Files readme.txt>
6
- Order Allow,Deny
7
- Deny From All
8
- </Files>
9
- <Files screenshot-1.png>
10
- Order Allow,Deny
11
- Deny From All
12
- </Files>
13
- <Files screenshot-2.png>
14
- Order Allow,Deny
15
- Deny From All
16
- </Files>
17
- <Files screenshot-3.png>
18
- Order Allow,Deny
19
- Deny From All
20
- </Files>
21
- <Files screenshot-4.png>
22
- Order Allow,Deny
23
- Deny From All
24
- </Files>
25
- <Files screenshot-5.png>
26
- Order Allow,Deny
27
- Deny From All
28
- </Files>
29
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/GeoIP.dat CHANGED
Binary file
lib/wf503.php CHANGED
@@ -13,7 +13,7 @@ will need to regain access to your site, go to the Wordfence "options" page, go
13
  if you were blocked because it was detected that you are a fake Google crawler, then disable the rule that blocks fake google crawlers. Or if you were blocked because you
14
  were accessing your site too quickly, then increase the number of accesses allowed per minute.
15
  <br /><br />
16
- If you're still having trouble, then simply disable the Wordfence firwall and you will
17
  still benefit from the other security features that Wordfence provides.
18
 
19
  <br /><br />
13
  if you were blocked because it was detected that you are a fake Google crawler, then disable the rule that blocks fake google crawlers. Or if you were blocked because you
14
  were accessing your site too quickly, then increase the number of accesses allowed per minute.
15
  <br /><br />
16
+ If you're still having trouble, then simply disable the Wordfence firewall and you will
17
  still benefit from the other security features that Wordfence provides.
18
 
19
  <br /><br />
lib/wfCrawl.php CHANGED
@@ -49,7 +49,7 @@ class wfCrawl {
49
  }
50
  }
51
  public static function isBingCrawler(){
52
- $UA = $_SERVER['HTTP_USER_AGENT'];
53
  foreach(self::$bingPat as $pat){
54
  if(preg_match($pat . 'i', $UA)){
55
  return true;
@@ -71,14 +71,14 @@ class wfCrawl {
71
  '@^msnbot/1\\.1.*$@'
72
  );
73
  public static function isGooglebot(){
74
- $UA = $_SERVER['HTTP_USER_AGENT'];
75
  if(preg_match('/Googlebot\/\d\.\d/', $UA)){ // UA: Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html) or (rarely used): Googlebot/2.1 (+http://www.google.com/bot.html)
76
  return true;
77
  }
78
  return false;
79
  }
80
  public static function isGoogleCrawler(){
81
- $UA = $_SERVER['HTTP_USER_AGENT'];
82
  foreach(self::$googPat as $pat){
83
  if(preg_match($pat . 'i', $UA)){
84
  return true;
49
  }
50
  }
51
  public static function isBingCrawler(){
52
+ $UA = (isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : '');
53
  foreach(self::$bingPat as $pat){
54
  if(preg_match($pat . 'i', $UA)){
55
  return true;
71
  '@^msnbot/1\\.1.*$@'
72
  );
73
  public static function isGooglebot(){
74
+ $UA = (isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : '');
75
  if(preg_match('/Googlebot\/\d\.\d/', $UA)){ // UA: Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html) or (rarely used): Googlebot/2.1 (+http://www.google.com/bot.html)
76
  return true;
77
  }
78
  return false;
79
  }
80
  public static function isGoogleCrawler(){
81
+ $UA = (isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : '');
82
  foreach(self::$googPat as $pat){
83
  if(preg_match($pat . 'i', $UA)){
84
  return true;
lib/wfLog.php CHANGED
@@ -104,7 +104,7 @@ class wfLog {
104
  }
105
  }
106
  }
107
- if(wfCrawl::isCrawler($_SERVER['HTTP_USER_AGENT'])){
108
  if($type == 'hit' && wfConfig::get('maxRequestsCrawlers') != 'DISABLED' && $hitsPerMinute > wfConfig::get('maxRequestsCrawlers')){
109
  $this->takeBlockingAction('maxRequestsCrawlers', "Exceeded the maximum number of requests per minute for crawlers."); //may not exit
110
  } else if($type == '404' && wfConfig::get('max404Crawlers') != 'DISABLED' && $hitsPerMinute > wfConfig::get('max404Crawlers')){
@@ -483,7 +483,9 @@ class wfLog {
483
  public function logHitOK(){
484
  if(stristr($_SERVER['REQUEST_URI'], 'wp-admin/admin-ajax.php')){ return false; } //Don't log wordpress ajax requests.
485
  if(is_admin()){ return false; } //Don't log admin pageviews
486
- if(preg_match('/WordPress\/' . $this->wp_version . '/i', $_SERVER['HTTP_USER_AGENT'])){ return false; } //Ignore requests generated by WP UA.
 
 
487
  if($userID = get_current_user_id()){
488
  if(wfConfig::get('liveTraf_ignorePublishers') && (current_user_can('publish_posts') || current_user_can('publish_pages')) ){ return false; } //User is logged in and can publish, so we don't log them.
489
  $user = get_userdata($userID);
@@ -506,7 +508,7 @@ class wfLog {
506
  }
507
  }
508
  }
509
- if(wfConfig::get('liveTraf_ignoreUA')){
510
  if($_SERVER['HTTP_USER_AGENT'] == wfConfig::get('liveTraf_ignoreUA')){
511
  return false;
512
  }
@@ -687,7 +689,7 @@ class wfLog {
687
  exit();
688
  }
689
  private function googleSafetyCheckOK(){ //returns true if OK to block. Returns false if we must not block.
690
- $cacheKey = md5($_SERVER['HTTP_USER_AGENT'] . ' ' . wfUtils::getIP());
691
  //Cache so we can call this multiple times in one request
692
  if(! isset(self::$gbSafeCache[$cacheKey])){
693
  $nb = wfConfig::get('neverBlockBG');
104
  }
105
  }
106
  }
107
+ if(isset($_SERVER['HTTP_USER_AGENT']) && wfCrawl::isCrawler($_SERVER['HTTP_USER_AGENT'])){
108
  if($type == 'hit' && wfConfig::get('maxRequestsCrawlers') != 'DISABLED' && $hitsPerMinute > wfConfig::get('maxRequestsCrawlers')){
109
  $this->takeBlockingAction('maxRequestsCrawlers', "Exceeded the maximum number of requests per minute for crawlers."); //may not exit
110
  } else if($type == '404' && wfConfig::get('max404Crawlers') != 'DISABLED' && $hitsPerMinute > wfConfig::get('max404Crawlers')){
483
  public function logHitOK(){
484
  if(stristr($_SERVER['REQUEST_URI'], 'wp-admin/admin-ajax.php')){ return false; } //Don't log wordpress ajax requests.
485
  if(is_admin()){ return false; } //Don't log admin pageviews
486
+ if(isset($_SERVER['HTTP_USER_AGENT'])){
487
+ if(preg_match('/WordPress\/' . $this->wp_version . '/i', $_SERVER['HTTP_USER_AGENT'])){ return false; } //Ignore requests generated by WP UA.
488
+ }
489
  if($userID = get_current_user_id()){
490
  if(wfConfig::get('liveTraf_ignorePublishers') && (current_user_can('publish_posts') || current_user_can('publish_pages')) ){ return false; } //User is logged in and can publish, so we don't log them.
491
  $user = get_userdata($userID);
508
  }
509
  }
510
  }
511
+ if( isset($_SERVER['HTTP_USER_AGENT']) && wfConfig::get('liveTraf_ignoreUA') ){
512
  if($_SERVER['HTTP_USER_AGENT'] == wfConfig::get('liveTraf_ignoreUA')){
513
  return false;
514
  }
689
  exit();
690
  }
691
  private function googleSafetyCheckOK(){ //returns true if OK to block. Returns false if we must not block.
692
+ $cacheKey = md5( (isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : '') . ' ' . wfUtils::getIP());
693
  //Cache so we can call this multiple times in one request
694
  if(! isset(self::$gbSafeCache[$cacheKey])){
695
  $nb = wfConfig::get('neverBlockBG');
lib/wfScanEngine.php CHANGED
@@ -869,7 +869,7 @@ class wfScanEngine {
869
  }
870
  }
871
  $timeout = self::getMaxExecutionTime() - 2; //2 seconds shorter than max execution time which ensures that only 2 HTTP processes are ever occupied
872
- $testURL = admin_url('admin-ajax.php') . '?action=wordfence_testAjax';
873
  $testResult = wp_remote_post($testURL, array(
874
  'timeout' => $timeout,
875
  'blocking' => true,
@@ -881,8 +881,8 @@ class wfScanEngine {
881
  wfConfig::set('currentCronKey', time() . ',' . $cronKey);
882
  if( (! is_wp_error($testResult)) && is_array($testResult) && strstr($testResult['body'], 'WFSCANTESTOK') !== false){
883
  //ajax requests can be sent by the server to itself
884
- $cronURL = admin_url('admin-ajax.php');
885
- $cronURL .= '?action=wordfence_doScan&isFork=' . ($isFork ? '1' : '0') . '&cronKey=' . $cronKey;
886
  $headers = array();
887
  wordfence::status(4, 'info', "Starting cron with normal ajax at URL $cronURL");
888
  $result = wp_remote_post( $cronURL, array(
869
  }
870
  }
871
  $timeout = self::getMaxExecutionTime() - 2; //2 seconds shorter than max execution time which ensures that only 2 HTTP processes are ever occupied
872
+ $testURL = admin_url('admin-ajax.php?action=wordfence_testAjax');
873
  $testResult = wp_remote_post($testURL, array(
874
  'timeout' => $timeout,
875
  'blocking' => true,
881
  wfConfig::set('currentCronKey', time() . ',' . $cronKey);
882
  if( (! is_wp_error($testResult)) && is_array($testResult) && strstr($testResult['body'], 'WFSCANTESTOK') !== false){
883
  //ajax requests can be sent by the server to itself
884
+ $cronURL = 'admin-ajax.php?action=wordfence_doScan&isFork=' . ($isFork ? '1' : '0') . '&cronKey=' . $cronKey;
885
+ $cronURL = admin_url($cronURL);
886
  $headers = array();
887
  wordfence::status(4, 'info', "Starting cron with normal ajax at URL $cronURL");
888
  $result = wp_remote_post( $cronURL, array(
lib/wordfenceClass.php CHANGED
@@ -699,7 +699,7 @@ class wordfence {
699
  throw new Exception("We could not fetch a core WordPress file from the Wordfence API.");
700
  }
701
  } catch (Exception $e){
702
- return array('errorMsg' => $e->getMessage());
703
  }
704
  }
705
  public static function ajax_addTwoFactor_callback(){
@@ -716,12 +716,12 @@ class wordfence {
716
  try {
717
  $codeResult = $api->call('twoFactor_verification', array(), array('phone' => $phone));
718
  } catch(Exception $e){
719
- return array('errorMsg' => "Could not contact Wordfence servers to generate a verification code: " . $e->getMessage());
720
  }
721
  if(isset($codeResult['ok']) && $codeResult['ok']){
722
  $code = $codeResult['code'];
723
  } else if(isset($codeResult['errorMsg']) && $codeResult['errorMsg']){
724
- return array('errorMsg' => $codeResult['errorMsg']);
725
  } else {
726
  return array('errorMsg' => "We could not generate a verification code.");
727
  }
@@ -750,7 +750,7 @@ class wordfence {
750
  $user = $twoFactorUsers[$i];
751
  break;
752
  } else {
753
- return array('errorMsg' => "That is not the correct code. Please look for an SMS containing an activation code on the phone with number: " . $twoFactorUsers[$i][1]);
754
  }
755
  }
756
  }
@@ -982,7 +982,7 @@ class wordfence {
982
  throw new Exception("Could not understand the response we received from the Wordfence servers when applying for a free API key.");
983
  }
984
  } catch(Exception $e){
985
- return array('errorMsg' => "Could not fetch free API key from Wordfence: " . $e->getMessage());
986
  }
987
  return array('ok' => 1);
988
  }
@@ -1007,7 +1007,7 @@ class wordfence {
1007
  }
1008
  }
1009
  if(sizeof($badEmails) > 0){
1010
- return array('errorMsg' => "The following emails are invalid: " . implode(', ', $badEmails));
1011
  }
1012
  $opts['alertEmails'] = implode(',', $emails);
1013
  } else {
@@ -1027,7 +1027,7 @@ class wordfence {
1027
  }
1028
  }
1029
  if(sizeof($badWhiteIPs) > 0){
1030
- return array('errorMsg' => "Please make sure you separate your IP addresses with commas. The following whitelisted IP addresses are invalid: " . implode(', ', $badWhiteIPs));
1031
  }
1032
  $opts['whitelisted'] = implode(',', $whiteIPs);
1033
  } else {
@@ -1051,7 +1051,7 @@ class wordfence {
1051
  }
1052
 
1053
  if(sizeof($invalidUsers) > 0){
1054
- return array('errorMsg' => "The following users you selected to ignore in live traffic reports are not valid on this system: " . implode(', ', $invalidUsers));
1055
  }
1056
  if(sizeof($validUsers) > 0){
1057
  $opts['liveTraf_ignoreUsers'] = implode(',', $validUsers);
@@ -1071,7 +1071,7 @@ class wordfence {
1071
  }
1072
  }
1073
  if(sizeof($invalidIPs) > 0){
1074
- return array('errorMsg' => "The following IPs you selected to ignore in live traffic reports are not valid: " . implode(', ', $invalidIPs));
1075
  }
1076
  if(sizeof($validIPs) > 0){
1077
  $opts['liveTraf_ignoreIPs'] = implode(',', $validIPs);
@@ -1114,7 +1114,7 @@ class wordfence {
1114
  throw new Exception("We could not understand the Wordfence server's response because it did not contain an 'ok' and 'apiKey' element.");
1115
  }
1116
  } catch(Exception $e){
1117
- return array('errorMsg' => "Your options have been saved, but we encountered a problem. You left your API key blank, so we tried to get you a free API key from the Wordfence servers. However we encountered a problem fetching the free key: " . $e->getMessage());
1118
  }
1119
  } else if($opts['apiKey'] != wfConfig::get('apiKey')){
1120
  $api = new wfAPI($opts['apiKey'], wfUtils::getWPVersion());
@@ -1131,7 +1131,7 @@ class wordfence {
1131
  throw new Exception("We could not understand the Wordfence API server reply when updating your API key.");
1132
  }
1133
  } catch (Exception $e){
1134
- return array('errorMsg' => "Your options have been saved. However we noticed you changed your API key and we tried to verify it with the Wordfence servers and received an error: " . $e->getMessage());
1135
  }
1136
  }
1137
  return array('ok' => 1, 'reload' => $reload, 'paidKeyMsg' => $paidKeyMsg );
@@ -1207,7 +1207,7 @@ class wordfence {
1207
  }
1208
  $clientIP = wfUtils::inet_aton(wfUtils::getIP());
1209
  if($ip1 <= $clientIP && $ip2 >= $clientIP){
1210
- return array('err' => 1, 'errorMsg' => "You are trying to block yourself. Your IP address is " . wfUtils::getIP() . " which falls into the range $ipRange. This blocking action has been cancelled so that you don't block yourself from your website.");
1211
  }
1212
  $ipRange = $ip1 . '-' . $ip2;
1213
  }
@@ -1233,7 +1233,7 @@ class wordfence {
1233
  return array('err' => 1, 'errorMsg' => "You can't block your own IP address.");
1234
  }
1235
  if(self::getLog()->isWhitelisted($IP)){
1236
- return array('err' => 1, 'errorMsg' => "The IP address $IP is whitelisted and can't be blocked or it is in a range of internal IP addresses that Wordfence does not block. You can remove this IP from the whitelist on the Wordfence options page.");
1237
  }
1238
  if(wfConfig::get('neverBlockBG') != 'treatAsOtherCrawlers'){ //Either neverBlockVerified or neverBlockUA is selected which means the user doesn't want to block google
1239
  if(wfCrawl::verifyCrawlerPTR('/googlebot\.com$/i', $IP)){
@@ -1358,7 +1358,7 @@ class wordfence {
1358
  );
1359
  } else {
1360
  $err = error_get_last();
1361
- return array('errorMsg' => "Could not delete file $file. The error was: " . $err['message']);
1362
  }
1363
  }
1364
  public static function ajax_restoreFile_callback(){
@@ -1408,7 +1408,7 @@ class wordfence {
1408
  self::status(4, 'info', "Ajax request received to start scan.");
1409
  $err = wfScanEngine::startScan();
1410
  if($err){
1411
- return array('errorMsg' => $err);
1412
  } else {
1413
  return array("ok" => 1);
1414
  }
@@ -1524,8 +1524,7 @@ class wordfence {
1524
  exit();
1525
  }
1526
  public static function wp_head(){
1527
- $URL = admin_url('admin-ajax.php');
1528
- $URL .= '?action=wordfence_logHuman&hid=' . wfUtils::encrypt(self::$hitID);
1529
  echo '<script type="text/javascript">var src="' . $URL . '"; if(window.location.protocol == "https:"){ src = src.replace("http:", "https:"); } var wfHTImg = new Image(); wfHTImg.src=src;</script>';
1530
  }
1531
  public static function shutdownAction(){
@@ -1594,7 +1593,7 @@ class wordfence {
1594
  public static function wfFunc_diff(){
1595
  $result = self::getWPFileContent($_GET['file'], $_GET['cType'], $_GET['cName'], $_GET['cVersion']);
1596
  if( isset( $result['errorMsg'] ) && $result['errorMsg']){
1597
- echo $result['errorMsg'];
1598
  exit(0);
1599
  } else if(! $result['fileContent']){
1600
  echo "We could not get the contents of the original file to do a comparison.";
699
  throw new Exception("We could not fetch a core WordPress file from the Wordfence API.");
700
  }
701
  } catch (Exception $e){
702
+ return array('errorMsg' => htmlentities($e->getMessage()));
703
  }
704
  }
705
  public static function ajax_addTwoFactor_callback(){
716
  try {
717
  $codeResult = $api->call('twoFactor_verification', array(), array('phone' => $phone));
718
  } catch(Exception $e){
719
+ return array('errorMsg' => "Could not contact Wordfence servers to generate a verification code: " . htmlentities($e->getMessage()) );
720
  }
721
  if(isset($codeResult['ok']) && $codeResult['ok']){
722
  $code = $codeResult['code'];
723
  } else if(isset($codeResult['errorMsg']) && $codeResult['errorMsg']){
724
+ return array('errorMsg' => htmlentities($codeResult['errorMsg']));
725
  } else {
726
  return array('errorMsg' => "We could not generate a verification code.");
727
  }
750
  $user = $twoFactorUsers[$i];
751
  break;
752
  } else {
753
+ return array('errorMsg' => "That is not the correct code. Please look for an SMS containing an activation code on the phone with number: " . htmlentities($twoFactorUsers[$i][1]) );
754
  }
755
  }
756
  }
982
  throw new Exception("Could not understand the response we received from the Wordfence servers when applying for a free API key.");
983
  }
984
  } catch(Exception $e){
985
+ return array('errorMsg' => "Could not fetch free API key from Wordfence: " . htmlentities($e->getMessage()));
986
  }
987
  return array('ok' => 1);
988
  }
1007
  }
1008
  }
1009
  if(sizeof($badEmails) > 0){
1010
+ return array('errorMsg' => "The following emails are invalid: " . htmlentities(implode(', ', $badEmails)) );
1011
  }
1012
  $opts['alertEmails'] = implode(',', $emails);
1013
  } else {
1027
  }
1028
  }
1029
  if(sizeof($badWhiteIPs) > 0){
1030
+ return array('errorMsg' => "Please make sure you separate your IP addresses with commas. The following whitelisted IP addresses are invalid: " . htmlentities(implode(', ', $badWhiteIPs)) );
1031
  }
1032
  $opts['whitelisted'] = implode(',', $whiteIPs);
1033
  } else {
1051
  }
1052
 
1053
  if(sizeof($invalidUsers) > 0){
1054
+ return array('errorMsg' => "The following users you selected to ignore in live traffic reports are not valid on this system: " . htmlentities(implode(', ', $invalidUsers)) );
1055
  }
1056
  if(sizeof($validUsers) > 0){
1057
  $opts['liveTraf_ignoreUsers'] = implode(',', $validUsers);
1071
  }
1072
  }
1073
  if(sizeof($invalidIPs) > 0){
1074
+ return array('errorMsg' => "The following IPs you selected to ignore in live traffic reports are not valid: " . htmlentities(implode(', ', $invalidIPs)) );
1075
  }
1076
  if(sizeof($validIPs) > 0){
1077
  $opts['liveTraf_ignoreIPs'] = implode(',', $validIPs);
1114
  throw new Exception("We could not understand the Wordfence server's response because it did not contain an 'ok' and 'apiKey' element.");
1115
  }
1116
  } catch(Exception $e){
1117
+ return array('errorMsg' => "Your options have been saved, but we encountered a problem. You left your API key blank, so we tried to get you a free API key from the Wordfence servers. However we encountered a problem fetching the free key: " . htmlentities($e->getMessage()) );
1118
  }
1119
  } else if($opts['apiKey'] != wfConfig::get('apiKey')){
1120
  $api = new wfAPI($opts['apiKey'], wfUtils::getWPVersion());
1131
  throw new Exception("We could not understand the Wordfence API server reply when updating your API key.");
1132
  }
1133
  } catch (Exception $e){
1134
+ return array('errorMsg' => "Your options have been saved. However we noticed you changed your API key and we tried to verify it with the Wordfence servers and received an error: " . htmlentities($e->getMessage()) );
1135
  }
1136
  }
1137
  return array('ok' => 1, 'reload' => $reload, 'paidKeyMsg' => $paidKeyMsg );
1207
  }
1208
  $clientIP = wfUtils::inet_aton(wfUtils::getIP());
1209
  if($ip1 <= $clientIP && $ip2 >= $clientIP){
1210
+ return array('err' => 1, 'errorMsg' => "You are trying to block yourself. Your IP address is " . htmlentities(wfUtils::getIP()) . " which falls into the range " . htmlentities($ipRange) . ". This blocking action has been cancelled so that you don't block yourself from your website.");
1211
  }
1212
  $ipRange = $ip1 . '-' . $ip2;
1213
  }
1233
  return array('err' => 1, 'errorMsg' => "You can't block your own IP address.");
1234
  }
1235
  if(self::getLog()->isWhitelisted($IP)){
1236
+ return array('err' => 1, 'errorMsg' => "The IP address " . htmlentities($IP) . " is whitelisted and can't be blocked or it is in a range of internal IP addresses that Wordfence does not block. You can remove this IP from the whitelist on the Wordfence options page.");
1237
  }
1238
  if(wfConfig::get('neverBlockBG') != 'treatAsOtherCrawlers'){ //Either neverBlockVerified or neverBlockUA is selected which means the user doesn't want to block google
1239
  if(wfCrawl::verifyCrawlerPTR('/googlebot\.com$/i', $IP)){
1358
  );
1359
  } else {
1360
  $err = error_get_last();
1361
+ return array('errorMsg' => "Could not delete file " . htmlentities($file) . ". The error was: " . htmlentities($err['message']));
1362
  }
1363
  }
1364
  public static function ajax_restoreFile_callback(){
1408
  self::status(4, 'info', "Ajax request received to start scan.");
1409
  $err = wfScanEngine::startScan();
1410
  if($err){
1411
+ return array('errorMsg' => htmlentities($err));
1412
  } else {
1413
  return array("ok" => 1);
1414
  }
1524
  exit();
1525
  }
1526
  public static function wp_head(){
1527
+ $URL = admin_url('admin-ajax.php?action=wordfence_logHuman&amp;hid=' . wfUtils::encrypt(self::$hitID));
 
1528
  echo '<script type="text/javascript">var src="' . $URL . '"; if(window.location.protocol == "https:"){ src = src.replace("http:", "https:"); } var wfHTImg = new Image(); wfHTImg.src=src;</script>';
1529
  }
1530
  public static function shutdownAction(){
1593
  public static function wfFunc_diff(){
1594
  $result = self::getWPFileContent($_GET['file'], $_GET['cType'], $_GET['cName'], $_GET['cVersion']);
1595
  if( isset( $result['errorMsg'] ) && $result['errorMsg']){
1596
+ echo htmlentities($result['errorMsg']);
1597
  exit(0);
1598
  } else if(! $result['fileContent']){
1599
  echo "We could not get the contents of the original file to do a comparison.";
readme.txt CHANGED
@@ -2,8 +2,8 @@
2
  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.6
6
- Stable tag: 3.8.3
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
 
@@ -150,6 +150,15 @@ cause a security hole on your site.
150
 
151
  == Changelog ==
152
 
 
 
 
 
 
 
 
 
 
153
  = 3.8.3 =
154
  * Updated GeoIP database for country blocking security.
155
  * Fixed bug in Wordfence Security where we called reverseLookup in wfUtils statically and it's a non-static method. Thanks Juliette.
2
  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.6.1
6
+ Stable tag: 3.8.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
 
150
 
151
  == Changelog ==
152
 
153
+ = 3.8.4 =
154
+ * Removed Wordfence .htaccess because it doesn't offer any security functionality and increases incompatibility.
155
+ * Fixed spelling errors.
156
+ * Added check to see if $_SERVER['HTTP_USER_AGENT'] is defined before using it to suppress large number of warnings on some sites.
157
+ * Changed the way we call admin_url() to the correct syntax.
158
+ * Correctly escaped HTML on error messages.
159
+ * Fixed issue that generated non-compliant query string.
160
+ * Updated GeoIP database to newest version.
161
+
162
  = 3.8.3 =
163
  * Updated GeoIP database for country blocking security.
164
  * Fixed bug in Wordfence Security where we called reverseLookup in wfUtils statically and it's a non-static method. Thanks Juliette.
wordfence.php CHANGED
@@ -4,10 +4,10 @@ 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.8.3
8
  Author URI: http://www.wordfence.com/
9
  */
10
- define('WORDFENCE_VERSION', '3.8.3');
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
  }
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.8.4
8
  Author URI: http://www.wordfence.com/
9
  */
10
+ define('WORDFENCE_VERSION', '3.8.4');
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
  }