Wordfence Security – Firewall & Malware Scan - Version 5.0.4

Version Description

  • Feature: We now scan for the infamous heartbleed openssl vulnerability using a non-intrusive scan method safe for production servers.
  • Improvement: We now check if .htaccess is writable and if not we give you rules to manually enable Falcon.
  • Improvement: Once Falcon is enabled, if we cant write to .htaccess, we fall back to PHP based IP blocking.
  • Feature: You can now clear pages and posts from the cache on the list-posts page under each item or on their edit pages next to the Update button.
  • Fix: We now support sites who use a root URI but store their files and .htaccess in a subdirectory of the web root.
  • Fix: Added an additional filter to prevent crawlers like Bing who execute javascript from being logged as humans.
  • Fix: Changed the extension of the backup .htaccess to be .txt to avoid anti-virus software alerting on a download with .com extension. [Props to Scott N. for catching this]
Download this release

Release Info

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

Code changes from version 5.0.3 to 5.0.4

js/admin.js CHANGED
@@ -1219,16 +1219,23 @@ window['wordfenceAdmin'] = {
1219
  });
1220
  },
1221
  switchToFalcon: function(){
1222
- this.colorbox('400px', "Enabling Falcon Engine", 'First read this <a href="http://www.wordfence.com/introduction-to-wordfence-falcon-engine/" target="_blank">Introduction to Falcon Engine</a>. Falcon modifies your website configuration file which is called your .htaccess file. To enable Falcon we ask that you make a backup of this file. This is a safety precaution in case for some reason Falcon is not compatible with your site.<br /><br /><a href="' + WordfenceAdminVars.ajaxURL + '?action=wordfence_downloadHtaccess&nonce=' + this.nonce + '" onclick="jQuery(\'#wfNextBut\').prop(\'disabled\', false); return true;">Click here to download a backup copy of your .htaccess file now</a><br /><br /><input type="button" name="but1" id="wfNextBut" value="Click to Enable Falcon Engine" disabled="disabled" onclick="WFAD.confirmSwitchToFalcon();" />');
1223
- },
1224
- switchToFalconTwo: function(){
 
 
 
 
 
 
1225
  },
1226
- confirmSwitchToFalcon: function(){
1227
  jQuery.colorbox.close();
1228
  var cacheType = 'falcon';
1229
  var self = this;
1230
  this.ajax('wordfence_saveCacheConfig', {
1231
- cacheType: cacheType
 
1232
  }, function(res){
1233
  if(res.ok){
1234
  self.colorbox('400px', res.heading, res.body);
@@ -1252,13 +1259,14 @@ window['wordfenceAdmin'] = {
1252
  );
1253
  },
1254
  saveCacheOptions: function(){
 
1255
  this.ajax('wordfence_saveCacheOptions', {
1256
  allowHTTPSCaching: (jQuery('#wfallowHTTPSCaching').is(':checked') ? 1 : 0),
1257
  addCacheComment: (jQuery('#wfaddCacheComment').is(':checked') ? 1 : 0)
1258
  }, function(res){
1259
- //if(res.ok){
1260
- // self.colorbox('400px', res.heading, res.body);
1261
- //}
1262
  }
1263
  );
1264
  },
1219
  });
1220
  },
1221
  switchToFalcon: function(){
1222
+ var self = this;
1223
+ this.ajax('wordfence_checkFalconHtaccess', {
1224
+ }, function(res){
1225
+ if(res.ok){
1226
+ self.colorbox('400px', "Enabling Falcon Engine", 'First read this <a href="http://www.wordfence.com/introduction-to-wordfence-falcon-engine/" target="_blank">Introduction to Falcon Engine</a>. Falcon modifies your website configuration file which is called your .htaccess file. To enable Falcon we ask that you make a backup of this file. This is a safety precaution in case for some reason Falcon is not compatible with your site.<br /><br /><a href="' + WordfenceAdminVars.ajaxURL + '?action=wordfence_downloadHtaccess&nonce=' + self.nonce + '" onclick="jQuery(\'#wfNextBut\').prop(\'disabled\', false); return true;">Click here to download a backup copy of your .htaccess file now</a><br /><br /><input type="button" name="but1" id="wfNextBut" value="Click to Enable Falcon Engine" disabled="disabled" onclick="WFAD.confirmSwitchToFalcon(0);" />');
1227
+ } else if(res.err){
1228
+ self.colorbox('400px', "We encountered a problem", "We can't modify your .htaccess file for you because: " + res.err + "<br /><br />Advanced users: If you would like to manually enable Falcon yourself by editing your .htaccess, you can add the rules below to the beginning of your .htaccess file. Then click the button below to enable Falcon. Don't do this unless you understand website configuration.<br /><textarea style='width: 300px; height:100px;' readonly>" + jQuery('<div/>').text(res.code).html() + "</textarea><br /><input type='button' value='Enable Falcon after manually editing .htaccess' onclick='WFAD.confirmSwitchToFalcon(1);' />");
1229
+ }
1230
+ });
1231
  },
1232
+ confirmSwitchToFalcon: function(noEditHtaccess){
1233
  jQuery.colorbox.close();
1234
  var cacheType = 'falcon';
1235
  var self = this;
1236
  this.ajax('wordfence_saveCacheConfig', {
1237
+ cacheType: cacheType,
1238
+ noEditHtaccess: noEditHtaccess
1239
  }, function(res){
1240
  if(res.ok){
1241
  self.colorbox('400px', res.heading, res.body);
1259
  );
1260
  },
1261
  saveCacheOptions: function(){
1262
+ var self = this;
1263
  this.ajax('wordfence_saveCacheOptions', {
1264
  allowHTTPSCaching: (jQuery('#wfallowHTTPSCaching').is(':checked') ? 1 : 0),
1265
  addCacheComment: (jQuery('#wfaddCacheComment').is(':checked') ? 1 : 0)
1266
  }, function(res){
1267
+ if(res.updateErr){
1268
+ self.colorbox('400px', "You need to manually update your .htaccess", res.updateErr + "<br />Your option was updated but you need to change the Wordfence code in your .htaccess to the following:<br /><textarea style='width: 300px; height: 120px;'>" + jQuery('<div/>').text(res.code).html() + '</textarea>');
1269
+ }
1270
  }
1271
  );
1272
  },
js/tourTip.js CHANGED
@@ -1,3 +1,75 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  if(! window['wordfenceTour']){
2
  window['wordfenceTour'] = {
3
  wfClearEmailField: function(){
@@ -42,7 +114,7 @@ window['wordfenceTour'] = {
42
  return false;
43
  }
44
  }
45
- }
46
  }
47
 
48
  jQuery(function(){
@@ -79,3 +151,4 @@ if(WordfenceAdminVars.tourClosed != '1'){
79
  jQuery('#pointer-primary').click(function(){ window.location.href = 'admin.php?page=Wordfence'; });
80
  }
81
  });
 
1
+ if(! window['wordfenceExt']){
2
+ window['wordfenceExt'] = {
3
+ nonce: false,
4
+ loadingCount: 0,
5
+ init: function(){
6
+ this.nonce = WordfenceAdminVars.firstNonce;
7
+ },
8
+ showLoading: function(){
9
+ this.loadingCount++;
10
+ if(this.loadingCount == 1){
11
+ jQuery('<div style="padding: 2px 8px 2px 24px; z-index: 100000; position: fixed; right: 2px; bottom: 2px; border: 1px solid #000; background-color: #F00; color: #FFF; font-size: 12px; font-weight: bold; font-family: Arial; text-align: center;" id="wordfenceWorking">Wordfence is working...</div>').appendTo('body');
12
+ }
13
+ },
14
+ removeLoading: function(){
15
+ this.loadingCount--;
16
+ if(this.loadingCount == 0){
17
+ jQuery('#wordfenceWorking').remove();
18
+ }
19
+ },
20
+ removeFromCache: function(postID){
21
+ this.ajax('wordfence_removeFromCache', {
22
+ id: postID
23
+ },
24
+ function(res){ if(res.ok){ alert("Item removed from the Wordfence cache."); } },
25
+ function(){}
26
+ );
27
+ },
28
+ ajax: function(action, data, cb, cbErr, noLoading){
29
+ if(typeof(data) == 'string'){
30
+ if(data.length > 0){
31
+ data += '&';
32
+ }
33
+ data += 'action=' + action + '&nonce=' + this.nonce;
34
+ } else if(typeof(data) == 'object'){
35
+ data['action'] = action;
36
+ data['nonce'] = this.nonce;
37
+ }
38
+ if(! cbErr){
39
+ cbErr = function(){};
40
+ }
41
+ var self = this;
42
+ if(! noLoading){
43
+ this.showLoading();
44
+ }
45
+ jQuery.ajax({
46
+ type: 'POST',
47
+ url: WordfenceAdminVars.ajaxURL,
48
+ dataType: "json",
49
+ data: data,
50
+ success: function(json){
51
+ if(! noLoading){
52
+ self.removeLoading();
53
+ }
54
+ if(json && json.nonce){
55
+ self.nonce = json.nonce;
56
+ }
57
+ cb(json);
58
+ },
59
+ error: function(){
60
+ if(! noLoading){
61
+ self.removeLoading();
62
+ }
63
+ cbErr();
64
+ }
65
+ });
66
+ }
67
+ };
68
+ }
69
+ jQuery(function(){
70
+ wordfenceExt.init();
71
+ });
72
+
73
  if(! window['wordfenceTour']){
74
  window['wordfenceTour'] = {
75
  wfClearEmailField: function(){
114
  return false;
115
  }
116
  }
117
+ };
118
  }
119
 
120
  jQuery(function(){
151
  jQuery('#pointer-primary').click(function(){ window.location.href = 'admin.php?page=Wordfence'; });
152
  }
153
  });
154
+
lib/menu_options.php CHANGED
@@ -107,6 +107,7 @@ var WFSLevels = <?php echo json_encode(wfConfig::$securityLevels); ?>;
107
  <?php } else { ?>
108
  <tr><th style="color: #F00;">Scan public facing site for vulnerabilities? (<a href="https://www.wordfence.com/wordfence-signup/" target="_blank">Paid members only</a>)</th><td><input type="checkbox" id="scansEnabled_public" class="wfConfigElem" name="scansEnabled_public" value="1" DISABLED ?></td></tr>
109
  <?php } ?>
 
110
  <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>
111
 
112
  <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>
107
  <?php } else { ?>
108
  <tr><th style="color: #F00;">Scan public facing site for vulnerabilities? (<a href="https://www.wordfence.com/wordfence-signup/" target="_blank">Paid members only</a>)</th><td><input type="checkbox" id="scansEnabled_public" class="wfConfigElem" name="scansEnabled_public" value="1" DISABLED ?></td></tr>
109
  <?php } ?>
110
+ <tr><th>Scan for the HeartBleed vulnerability?</th><td><input type="checkbox" id="scansEnabled_heartbleed" class="wfConfigElem" name="scansEnabled_heartbleed" value="1" <?php $w->cb('scansEnabled_heartbleed'); ?></td></tr>
111
  <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>
112
 
113
  <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>
lib/menu_scan.php CHANGED
@@ -621,6 +621,37 @@
621
  </div>
622
  </script>
623
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
624
 
625
 
626
 
621
  </div>
622
  </script>
623
 
624
+ <script type="text/x-jquery-template" id="issueTmpl_heartbleed">
625
+ <div>
626
+ <div class="wfIssue">
627
+ <h2>${shortMsg}</h2>
628
+ <p>
629
+ <table border="0" class="wfIssue" cellspacing="0" cellpadding="0">
630
+ <tr><th>Severity:</th><td>{{if severity == '1'}}Critical{{else}}Warning{{/if}}</td></tr>
631
+ <tr><th>Status</th><td>
632
+ {{if status == 'new' }}New{{/if}}
633
+ {{if status == 'ignoreC' }}This redirect will be ignored until it changes.{{/if}}
634
+ {{if status == 'ignoreP' }}This redirect is permanently ignored.{{/if}}
635
+ </td></tr>
636
+ </table>
637
+ </p>
638
+ <p>
639
+ {{html longMsg}}
640
+ </p>
641
+ <div class="wfIssueOptions">
642
+ {{if status == 'new'}}
643
+ <strong>Resolve:</strong>
644
+ <a href="#" onclick="WFAD.updateIssueStatus('${id}', 'delete'); return false;">I have fixed this issue</a>
645
+ <a href="#" onclick="WFAD.updateIssueStatus('${id}', 'ignoreP'); return false;">Ignore this problem</a>
646
+ {{/if}}
647
+ {{if status == 'ignoreP' || status == 'ignoreC'}}
648
+ <a href="#" onclick="WFAD.updateIssueStatus('${id}', 'delete'); return false;">Stop ignoring this issue</a>
649
+ {{/if}}
650
+ </div>
651
+ </div>
652
+ </div>
653
+ </script>
654
+
655
 
656
 
657
 
lib/wfCache.php CHANGED
@@ -150,7 +150,10 @@ class wfCache {
150
  return $buffer;
151
  }
152
  public static function fileFromRequest($host, $URI){
153
- $key = $host . $URI;
 
 
 
154
  if(isset(self::$fileCache[$key])){ return self::$fileCache[$key]; }
155
  $host = preg_replace('/[^a-zA-Z0-9\-\.]+/', '', $host);
156
  $URI = preg_replace('/(?:[^a-zA-Z0-9\-\_\.\~\/]+|\.{2,})/', '', $URI); //Strip out bad chars and multiple dots
@@ -161,7 +164,9 @@ class wfCache {
161
  $URI .= $i < 6 ? '~' : '';
162
  }
163
  }
164
- $file = WP_CONTENT_DIR . '/wfcache/' . $host . '_' . $URI . '_wfcache' . (self::isHTTPSPage() ? '_https' : '') . '.html';
 
 
165
  self::$fileCache[$key] = $file;
166
  return $file;
167
  }
@@ -353,8 +358,11 @@ class wfCache {
353
  if($action != 'add' && $action != 'remove'){
354
  die("Error: addHtaccessCode must be called with 'add' or 'remove' as param");
355
  }
356
- $htaccessPath = ABSPATH . '/.htaccess';
357
- $fh = fopen($htaccessPath, 'r+');
 
 
 
358
  if(! $fh){
359
  $err = error_get_last();
360
  return $err['message'];
@@ -378,7 +386,7 @@ class wfCache {
378
  fclose($fh);
379
  return false;
380
  }
381
- private static function getHtaccessCode(){
382
  $siteURL = site_url();
383
  $pathPrefix = "";
384
  $matchCaps = '$1/$2~$3~$4~$5~$6';
@@ -450,25 +458,28 @@ EOT;
450
  public static function scheduleUpdateBlockedIPs(){
451
  wp_clear_scheduled_hook('wordfence_update_blocked_IPs');
452
  if(wfConfig::get('cacheType') != 'falcon'){
453
- self::updateBlockedIPs('remove');
454
  return;
455
  }
456
- self::updateBlockedIPs('add');
457
  wp_schedule_single_event(time() + 300, 'wordfence_update_blocked_IPs');
458
  }
459
  public static function updateBlockedIPs($action){ //'add' or 'remove'
460
  if(wfConfig::get('cacheType') != 'falcon'){ return; }
461
 
462
- $htaccessPath = ABSPATH . '/.htaccess';
 
 
 
463
  if($action == 'remove'){
464
- $fh = fopen($htaccessPath, 'r+');
465
  if(! $fh){
466
  $err = error_get_last();
467
  return $err['message'];
468
  }
469
  flock($fh, LOCK_EX);
470
  fseek($fh, 0, SEEK_SET); //start of file
471
- $contents = fread($fh, filesize($htaccessPath));
472
  if(! $contents){
473
  fclose($fh);
474
  return "Could not read from $htaccessPath";
@@ -478,11 +489,17 @@ EOT;
478
 
479
  ftruncate($fh, 0);
480
  fseek($fh, 0, SEEK_SET);
481
- fwrite($fh, $contents);
482
  flock($fh, LOCK_UN);
483
  fclose($fh);
484
  return false;
485
  } else if($action == 'add'){
 
 
 
 
 
 
486
  $lines = array();
487
  $wfLog = new wfLog(wfConfig::get('apiKey'), wfUtils::getWPVersion());
488
  $IPs = $wfLog->getBlockedIPsAddrOnly();
@@ -535,16 +552,11 @@ EOT;
535
  $blockCode .= implode('', $lines);
536
  $blockCode .= "#Do not remove this line. Disable Web Caching in Wordfence to remove this data - WFIPBLOCKS\n";
537
 
538
- $fh = fopen($htaccessPath, 'r+');
539
- if(! $fh){
540
- $err = error_get_last();
541
- return $err['message'];
542
- }
543
 
544
  //Minimize time between lock/unlock
545
  flock($fh, LOCK_EX);
546
  fseek($fh, 0, SEEK_SET); //start of file
547
- $contents = fread($fh, filesize($htaccessPath));
548
  if(! $contents){
549
  fclose($fh);
550
  return "Could not read from $htaccessPath";
@@ -553,9 +565,21 @@ EOT;
553
  $contents = $blockCode . $contents;
554
  ftruncate($fh, 0);
555
  fseek($fh, 0, SEEK_SET);
556
- fwrite($fh, $contents);
557
  flock($fh, LOCK_UN);
558
  fclose($fh);
559
  return false;
560
  }
 
 
 
 
 
 
 
 
 
 
 
 
561
  }
150
  return $buffer;
151
  }
152
  public static function fileFromRequest($host, $URI){
153
+ return self::fileFromURI($host, $URI, self::isHTTPSPage());
154
+ }
155
+ public static function fileFromURI($host, $URI, $isHTTPS){
156
+ $key = $host . $URI . ($isHTTPS ? '_HTTPS' : '');
157
  if(isset(self::$fileCache[$key])){ return self::$fileCache[$key]; }
158
  $host = preg_replace('/[^a-zA-Z0-9\-\.]+/', '', $host);
159
  $URI = preg_replace('/(?:[^a-zA-Z0-9\-\_\.\~\/]+|\.{2,})/', '', $URI); //Strip out bad chars and multiple dots
164
  $URI .= $i < 6 ? '~' : '';
165
  }
166
  }
167
+ $ext = '';
168
+ if($isHTTPS){ $ext = '_https'; }
169
+ $file = WP_CONTENT_DIR . '/wfcache/' . $host . '_' . $URI . '_wfcache' . $ext . '.html';
170
  self::$fileCache[$key] = $file;
171
  return $file;
172
  }
358
  if($action != 'add' && $action != 'remove'){
359
  die("Error: addHtaccessCode must be called with 'add' or 'remove' as param");
360
  }
361
+ $htaccessPath = self::getHtaccessPath();
362
+ if(! $htaccessPath){
363
+ return "Wordfence could not find your .htaccess file.";
364
+ }
365
+ $fh = @fopen($htaccessPath, 'r+');
366
  if(! $fh){
367
  $err = error_get_last();
368
  return $err['message'];
386
  fclose($fh);
387
  return false;
388
  }
389
+ public static function getHtaccessCode(){
390
  $siteURL = site_url();
391
  $pathPrefix = "";
392
  $matchCaps = '$1/$2~$3~$4~$5~$6';
458
  public static function scheduleUpdateBlockedIPs(){
459
  wp_clear_scheduled_hook('wordfence_update_blocked_IPs');
460
  if(wfConfig::get('cacheType') != 'falcon'){
461
+ self::updateBlockedIPs('remove'); //Fail silently if .htaccess is not readable. Will fall back to old blocking via WP
462
  return;
463
  }
464
+ self::updateBlockedIPs('add'); //Fail silently if .htaccess is not readable. Will fall back to old blocking via WP
465
  wp_schedule_single_event(time() + 300, 'wordfence_update_blocked_IPs');
466
  }
467
  public static function updateBlockedIPs($action){ //'add' or 'remove'
468
  if(wfConfig::get('cacheType') != 'falcon'){ return; }
469
 
470
+ $htaccessPath = self::getHtaccessPath();
471
+ if(! $htaccessPath){
472
+ return "Wordfence could not find your .htaccess file.";
473
+ }
474
  if($action == 'remove'){
475
+ $fh = @fopen($htaccessPath, 'r+');
476
  if(! $fh){
477
  $err = error_get_last();
478
  return $err['message'];
479
  }
480
  flock($fh, LOCK_EX);
481
  fseek($fh, 0, SEEK_SET); //start of file
482
+ $contents = @fread($fh, filesize($htaccessPath));
483
  if(! $contents){
484
  fclose($fh);
485
  return "Could not read from $htaccessPath";
489
 
490
  ftruncate($fh, 0);
491
  fseek($fh, 0, SEEK_SET);
492
+ @fwrite($fh, $contents);
493
  flock($fh, LOCK_UN);
494
  fclose($fh);
495
  return false;
496
  } else if($action == 'add'){
497
+ $fh = @fopen($htaccessPath, 'r+');
498
+ if(! $fh){
499
+ $err = error_get_last();
500
+ return $err['message'];
501
+ }
502
+
503
  $lines = array();
504
  $wfLog = new wfLog(wfConfig::get('apiKey'), wfUtils::getWPVersion());
505
  $IPs = $wfLog->getBlockedIPsAddrOnly();
552
  $blockCode .= implode('', $lines);
553
  $blockCode .= "#Do not remove this line. Disable Web Caching in Wordfence to remove this data - WFIPBLOCKS\n";
554
 
 
 
 
 
 
555
 
556
  //Minimize time between lock/unlock
557
  flock($fh, LOCK_EX);
558
  fseek($fh, 0, SEEK_SET); //start of file
559
+ $contents = @fread($fh, filesize($htaccessPath));
560
  if(! $contents){
561
  fclose($fh);
562
  return "Could not read from $htaccessPath";
565
  $contents = $blockCode . $contents;
566
  ftruncate($fh, 0);
567
  fseek($fh, 0, SEEK_SET);
568
+ @fwrite($fh, $contents);
569
  flock($fh, LOCK_UN);
570
  fclose($fh);
571
  return false;
572
  }
573
+ public static function getHtaccessPath(){
574
+ if(file_exists(ABSPATH . '/.htaccess')){
575
+ return ABSPATH . '/.htaccess';
576
+ }
577
+ if(preg_match('/^https?:\/\/[^\/]+\/?$/i', home_url()) && preg_match('/^https?:\/\/[^\/]+\/.+/i', site_url())){
578
+ $path = realpath(ABSPATH . '/../.htaccess');
579
+ if(file_exists($path)){
580
+ return $path;
581
+ }
582
+ }
583
+ return false;
584
+ }
585
  }
lib/wfConfig.php CHANGED
@@ -23,6 +23,7 @@ class wfConfig {
23
  //"perfLoggingEnabled" => false,
24
  "scheduledScansEnabled" => false,
25
  "scansEnabled_public" => false,
 
26
  "scansEnabled_core" => false,
27
  "scansEnabled_themes" => false,
28
  "scansEnabled_plugins" => false,
@@ -96,6 +97,7 @@ class wfConfig {
96
  //"perfLoggingEnabled" => false,
97
  "scheduledScansEnabled" => true,
98
  "scansEnabled_public" => false,
 
99
  "scansEnabled_core" => true,
100
  "scansEnabled_themes" => false,
101
  "scansEnabled_plugins" => false,
@@ -169,6 +171,7 @@ class wfConfig {
169
  //"perfLoggingEnabled" => false,
170
  "scheduledScansEnabled" => true,
171
  "scansEnabled_public" => false,
 
172
  "scansEnabled_core" => true,
173
  "scansEnabled_themes" => false,
174
  "scansEnabled_plugins" => false,
@@ -242,6 +245,7 @@ class wfConfig {
242
  //"perfLoggingEnabled" => false,
243
  "scheduledScansEnabled" => true,
244
  "scansEnabled_public" => false,
 
245
  "scansEnabled_core" => true,
246
  "scansEnabled_themes" => false,
247
  "scansEnabled_plugins" => false,
@@ -315,6 +319,7 @@ class wfConfig {
315
  //"perfLoggingEnabled" => false,
316
  "scheduledScansEnabled" => true,
317
  "scansEnabled_public" => false,
 
318
  "scansEnabled_core" => true,
319
  "scansEnabled_themes" => false,
320
  "scansEnabled_plugins" => false,
@@ -446,7 +451,7 @@ class wfConfig {
446
  // for each request as long as set() isn't called which would start the whole process over again.
447
  if(! self::$diskCacheDisabled){ //We haven't had a write error to cache (so the cache is working) and clearDiskCache has not been called already
448
  $cacheFile = self::getCacheFile();
449
- unlink($cacheFile);
450
  wfConfig::$diskCache = array();
451
  }
452
  self::$diskCacheDisabled = true;
@@ -573,7 +578,7 @@ class wfConfig {
573
  }
574
  private static function deleteOldTempFile($filename){
575
  if(file_exists($filename)){
576
- unlink($filename);
577
  }
578
  }
579
  private static function getTempDir(){
23
  //"perfLoggingEnabled" => false,
24
  "scheduledScansEnabled" => false,
25
  "scansEnabled_public" => false,
26
+ "scansEnabled_heartbleed" => true,
27
  "scansEnabled_core" => false,
28
  "scansEnabled_themes" => false,
29
  "scansEnabled_plugins" => false,
97
  //"perfLoggingEnabled" => false,
98
  "scheduledScansEnabled" => true,
99
  "scansEnabled_public" => false,
100
+ "scansEnabled_heartbleed" => true,
101
  "scansEnabled_core" => true,
102
  "scansEnabled_themes" => false,
103
  "scansEnabled_plugins" => false,
171
  //"perfLoggingEnabled" => false,
172
  "scheduledScansEnabled" => true,
173
  "scansEnabled_public" => false,
174
+ "scansEnabled_heartbleed" => true,
175
  "scansEnabled_core" => true,
176
  "scansEnabled_themes" => false,
177
  "scansEnabled_plugins" => false,
245
  //"perfLoggingEnabled" => false,
246
  "scheduledScansEnabled" => true,
247
  "scansEnabled_public" => false,
248
+ "scansEnabled_heartbleed" => true,
249
  "scansEnabled_core" => true,
250
  "scansEnabled_themes" => false,
251
  "scansEnabled_plugins" => false,
319
  //"perfLoggingEnabled" => false,
320
  "scheduledScansEnabled" => true,
321
  "scansEnabled_public" => false,
322
+ "scansEnabled_heartbleed" => true,
323
  "scansEnabled_core" => true,
324
  "scansEnabled_themes" => false,
325
  "scansEnabled_plugins" => false,
451
  // for each request as long as set() isn't called which would start the whole process over again.
452
  if(! self::$diskCacheDisabled){ //We haven't had a write error to cache (so the cache is working) and clearDiskCache has not been called already
453
  $cacheFile = self::getCacheFile();
454
+ @unlink($cacheFile);
455
  wfConfig::$diskCache = array();
456
  }
457
  self::$diskCacheDisabled = true;
578
  }
579
  private static function deleteOldTempFile($filename){
580
  if(file_exists($filename)){
581
+ @unlink($filename);
582
  }
583
  }
584
  private static function getTempDir(){
lib/wfScanEngine.php CHANGED
@@ -50,6 +50,7 @@ class wfScanEngine {
50
  include('wfDict.php'); //$dictWords
51
  $this->dictWords = $dictWords;
52
  $this->jobList[] = 'publicSite';
 
53
  $this->jobList[] = 'knownFiles_init';
54
  $this->jobList[] = 'knownFiles_main';
55
  $this->jobList[] = 'knownFiles_finish';
@@ -128,6 +129,24 @@ class wfScanEngine {
128
  public function getCurrentJob(){
129
  return $this->jobList[0];
130
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
131
  private function scan_publicSite(){
132
  if(wfConfig::get('isPaid')){
133
  if(wfConfig::get('scansEnabled_public')){
50
  include('wfDict.php'); //$dictWords
51
  $this->dictWords = $dictWords;
52
  $this->jobList[] = 'publicSite';
53
+ $this->jobList[] = 'heartbleed';
54
  $this->jobList[] = 'knownFiles_init';
55
  $this->jobList[] = 'knownFiles_main';
56
  $this->jobList[] = 'knownFiles_finish';
129
  public function getCurrentJob(){
130
  return $this->jobList[0];
131
  }
132
+ private function scan_heartbleed(){
133
+ if(wfConfig::get('scansEnabled_heartbleed')){
134
+ $this->statusIDX['heartbleed'] = wordfence::statusStart("Scanning your site for the HeartBleed vulnerability");
135
+ $result = $this->api->call('scan_heartbleed', array(), array(
136
+ 'siteURL' => site_url()
137
+ ));
138
+ $haveIssues = false;
139
+ if($result['haveIssues'] && is_array($result['issues']) ){
140
+ foreach($result['issues'] as $issue){
141
+ $this->addIssue($issue['type'], $issue['level'], $issue['ignoreP'], $issue['ignoreC'], $issue['shortMsg'], $issue['longMsg'], $issue['data']);
142
+ $haveIssues = true;
143
+ }
144
+ }
145
+ wordfence::statusEnd($this->statusIDX['heartbleed'], $haveIssues);
146
+ } else {
147
+ wordfence::statusDisabled("Skipping HeartBleed scan");
148
+ }
149
+ }
150
  private function scan_publicSite(){
151
  if(wfConfig::get('isPaid')){
152
  if(wfConfig::get('scansEnabled_public')){
lib/wordfenceClass.php CHANGED
@@ -263,6 +263,11 @@ class wordfence {
263
  $db->queryWrite("update $prefix"."wfConfig set val='1' where name='scansEnabled_options'");
264
  }
265
 
 
 
 
 
 
266
  //Must be the final line
267
  }
268
  private static function doEarlyAccessLogging(){
@@ -358,6 +363,11 @@ class wordfence {
358
  add_action('admin_menu', 'wordfence::admin_menus');
359
  }
360
  add_filter('pre_update_option_permalink_structure', 'wordfence::disablePermalinksFilter', 10, 2);
 
 
 
 
 
361
  }
362
  }
363
  public static function ajax_testAjax_callback(){
@@ -387,6 +397,16 @@ class wordfence {
387
  die(json_encode(array('ok' => 1)));
388
  }
389
  public static function ajax_logHuman_callback(){
 
 
 
 
 
 
 
 
 
 
390
  ob_end_clean();
391
  if(! headers_sent()){
392
  header('Content-type: text/javascript');
@@ -394,12 +414,14 @@ class wordfence {
394
  header("Content-Length: 0");
395
  }
396
  flush();
397
- $hid = $_GET['hid'];
398
- $hid = wfUtils::decrypt($hid);
399
- if(! preg_match('/^\d+$/', $hid)){ exit(); }
400
- $db = new wfDB();
401
- global $wpdb; $p = $wpdb->base_prefix;
402
- $db->queryWrite("update $p"."wfHits set jsRun=1 where id=%d", $hid);
 
 
403
  die("");
404
  }
405
  public static function ajaxReceiver(){
@@ -1160,6 +1182,28 @@ class wordfence {
1160
  wfConfig::set('tourClosed', 1);
1161
  return array('ok' => 1);
1162
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1163
  public static function disablePermalinksFilter($newVal, $oldVal){
1164
  if(wfConfig::get('cacheType', false) == 'falcon' && $oldVal && (! $newVal) ){ //Falcon is enabled and admin is disabling permalinks
1165
  $err = wfCache::addHtaccessCode('remove');
@@ -1170,13 +1214,35 @@ class wordfence {
1170
  }
1171
  return $newVal;
1172
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1173
  public static function ajax_saveCacheOptions_callback(){
 
 
 
 
1174
  wfConfig::set('allowHTTPSCaching', $_POST['allowHTTPSCaching'] == '1' ? 1 : 0);
1175
  wfConfig::set('addCacheComment', $_POST['addCacheComment'] == 1 ? '1' : 0);
1176
- if(wfConfig::get('cacheType', false) == 'falcon'){
1177
  $err = wfCache::addHtaccessCode('add');
1178
  if($err){
1179
- return array('errorMsg' => "Wordfence could not edit your .htaccess code. The error was: " . $err);
1180
  }
1181
  }
1182
  wfCache::scheduleCacheClear();
@@ -1215,14 +1281,12 @@ class wordfence {
1215
  return array('errorMsg' => "You need to enable Permalinks for your site to use Falcon Engine. You can enable Permalinks in WordPress by going to the Settings - Permalinks menu and enabling it there. Permalinks change your site URL structure from something that looks like /p=123 to pretty URLs like /my-new-post-today/ that are generally more search engine friendly.");
1216
  }
1217
  }
 
1218
  if($cacheType == 'disable' || $cacheType == 'php'){
1219
  $removeError = wfCache::addHtaccessCode('remove');
1220
- if($removeError){
1221
- return array('ok' => 1, 'heading' => "Problem disabling caching.", 'body' => "We could not disable caching because you have code in your .htaccess file that could not be removed by Wordfence. You need to go in and remove any Wordfence code from your .htaccess file yourself. Then return here and disable caching. The error we received was: $removeError");
1222
- }
1223
- $removeError = wfCache::updateBlockedIPs('remove');
1224
- if($removeError){
1225
- return array('ok' => 1, 'heading' => "Problem disabling caching.", 'body' => "We could not remove the list of blocked IP's from your .htaccess file when updating the type of caching you have selected. You need to go in and remove any Wordfence code from your .htaccess file yourself. Then return here and disable caching. The error we received was: $removeError");
1226
  }
1227
  }
1228
  if($cacheType == 'php' || $cacheType == 'falcon'){
@@ -1236,17 +1300,22 @@ class wordfence {
1236
  if($cacheType != wfConfig::get('cacheType', false)){
1237
  wfCache::scheduleCacheClear();
1238
  }
1239
-
 
 
 
1240
  if($cacheType == 'disable'){
1241
  wfConfig::set('cacheType', false);
1242
- return array('ok' => 1, 'heading' => "Caching successfully disabled.", 'body' => "Caching has been disabled on your system.<br /><br /><center><input type='button' name='wfReload' value='Click here now to refresh this page' onclick='window.location.reload(true);' /></center>");
1243
  } else if($cacheType == 'php'){
1244
  wfConfig::set('cacheType', 'php');
1245
- return array('ok' => 1, 'heading' => "Wordfence Basic Caching Enabled", 'body' => "Wordfence basic caching has been enabled on your system.<br /><br /><center><input type='button' name='wfReload' value='Click here now to refresh this page' onclick='window.location.reload(true);' /></center>");
1246
  } else if($cacheType == 'falcon'){
1247
- $err = wfCache::addHtaccessCode('add');
1248
- if($err){
1249
- return array('ok' => 1, 'heading' => "Wordfence could not edit .htaccess", 'body' => "Wordfence could not edit your .htaccess code. The error was: " . $err);
 
 
1250
  }
1251
  wfConfig::set('cacheType', 'falcon');
1252
  wfCache::scheduleUpdateBlockedIPs(); //Runs every 5 mins until we change cachetype
@@ -1304,6 +1373,18 @@ class wordfence {
1304
  wfConfig::set($key, $val);
1305
  return array('ok' => 1);
1306
  }
 
 
 
 
 
 
 
 
 
 
 
 
1307
  public static function ajax_downloadHtaccess_callback(){
1308
  $url = site_url();
1309
  $url = preg_replace('/^https?:\/\//i', '', $url);
@@ -1311,8 +1392,8 @@ class wordfence {
1311
  $url = preg_replace('/^_+/', '', $url);
1312
  $url = preg_replace('/_+$/', '', $url);
1313
  header('Content-Type: application/octet-stream');
1314
- header('Content-Disposition: attachment; filename="htaccess_Backup_for_' . $url . '"');
1315
- $file = ABSPATH . '/.htaccess';
1316
  readfile($file);
1317
  die();
1318
  }
@@ -2143,7 +2224,7 @@ EOL;
2143
  }
2144
  public static function admin_init(){
2145
  if(! wfUtils::isAdmin()){ return; }
2146
- foreach(array('activate', 'scan', 'updateAlertEmail', 'sendActivityLog', 'restoreFile', 'bulkOperation', 'deleteFile', 'removeExclusion', 'activityLogUpdate', 'ticker', 'loadIssues', 'updateIssueStatus', 'deleteIssue', 'updateAllIssues', 'reverseLookup', 'unlockOutIP', 'loadBlockRanges', 'unblockRange', 'blockIPUARange', 'whois', 'unblockIP', 'blockIP', 'permBlockIP', 'loadStaticPanel', 'saveConfig', 'downloadHtaccess', 'updateConfig', 'saveCacheConfig', 'saveCacheOptions', 'clearPageCache', 'getCacheStats', 'clearAllBlocked', 'killScan', 'saveCountryBlocking', 'saveScanSchedule', 'tourClosed', 'startTourAgain', 'downgradeLicense', 'addTwoFactor', 'twoFacActivate', 'twoFacDel', 'loadTwoFactor', 'loadAvgSitePerf', 'addCacheExclusion', 'removeCacheExclusion', 'loadCacheExclusions') as $func){
2147
  add_action('wp_ajax_wordfence_' . $func, 'wordfence::ajaxReceiver');
2148
  }
2149
 
263
  $db->queryWrite("update $prefix"."wfConfig set val='1' where name='scansEnabled_options'");
264
  }
265
 
266
+ $optScanEnabled = $db->querySingle("select val from $prefix"."wfConfig where name='scansEnabled_heartbleed'");
267
+ if($optScanEnabled != '0' && $optScanEnabled != '1'){ //Enable heartbleed if no value is set.
268
+ wfConfig::set('scansEnabled_heartbleed', 1);
269
+ }
270
+
271
  //Must be the final line
272
  }
273
  private static function doEarlyAccessLogging(){
363
  add_action('admin_menu', 'wordfence::admin_menus');
364
  }
365
  add_filter('pre_update_option_permalink_structure', 'wordfence::disablePermalinksFilter', 10, 2);
366
+ if( preg_match('/^(?:falcon|php)$/', wfConfig::get('cacheType')) ){
367
+ add_filter('post_row_actions', 'wordfence::postRowActions', 0, 2);
368
+ add_filter('page_row_actions', 'wordfence::pageRowActions', 0, 2);
369
+ add_action('post_submitbox_start', 'wordfence::postSubmitboxStart');
370
+ }
371
  }
372
  }
373
  public static function ajax_testAjax_callback(){
397
  die(json_encode(array('ok' => 1)));
398
  }
399
  public static function ajax_logHuman_callback(){
400
+ $browscap = new wfBrowscap();
401
+ $UA = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : '';
402
+ $isCrawler = false;
403
+ if($UA){
404
+ $b = $browscap->getBrowser($res['UA']);
405
+ if($b['Crawler']){
406
+ $isCrawler = true;
407
+ }
408
+ }
409
+
410
  ob_end_clean();
411
  if(! headers_sent()){
412
  header('Content-type: text/javascript');
414
  header("Content-Length: 0");
415
  }
416
  flush();
417
+ if(! $isCrawler){
418
+ $hid = $_GET['hid'];
419
+ $hid = wfUtils::decrypt($hid);
420
+ if(! preg_match('/^\d+$/', $hid)){ exit(); }
421
+ $db = new wfDB();
422
+ global $wpdb; $p = $wpdb->base_prefix;
423
+ $db->queryWrite("update $p"."wfHits set jsRun=1 where id=%d", $hid);
424
+ }
425
  die("");
426
  }
427
  public static function ajaxReceiver(){
1182
  wfConfig::set('tourClosed', 1);
1183
  return array('ok' => 1);
1184
  }
1185
+ public static function postRowActions($actions, $post){
1186
+ if(wfUtils::isAdmin()){
1187
+ $actions = array_merge($actions, array(
1188
+ 'wfCachePurge' => '<a href="#" onclick="wordfenceExt.removeFromCache(\'' . $post->ID . '\'); return false;">Remove from Wordfence cache</a>'
1189
+ ));
1190
+ }
1191
+ return $actions;
1192
+ }
1193
+ public static function pageRowActions($actions, $post){
1194
+ if(wfUtils::isAdmin()){
1195
+ $actions = array_merge($actions, array(
1196
+ 'wfCachePurge' => '<a href="#" onclick="wordfenceExt.removeFromCache(\'' . $post->ID . '\'); return false;">Remove from Wordfence cache</a>'
1197
+ ));
1198
+ }
1199
+ return $actions;
1200
+ }
1201
+ public static function postSubmitboxStart(){
1202
+ if(wfUtils::isAdmin()){
1203
+ global $post;
1204
+ echo '<div><a href="#" onclick="wordfenceExt.removeFromCache(\'' . $post->ID . '\'); return false;">Remove from Wordfence cache</a></div>';
1205
+ }
1206
+ }
1207
  public static function disablePermalinksFilter($newVal, $oldVal){
1208
  if(wfConfig::get('cacheType', false) == 'falcon' && $oldVal && (! $newVal) ){ //Falcon is enabled and admin is disabling permalinks
1209
  $err = wfCache::addHtaccessCode('remove');
1214
  }
1215
  return $newVal;
1216
  }
1217
+ public static function ajax_removeFromCache_callback(){
1218
+ $id = $_POST['id'];
1219
+ $link = get_permalink($id);
1220
+ if(preg_match('/^https?:\/\/([^\/]+)(.*)$/i', $link, $matches)){
1221
+ $host = $matches[1];
1222
+ $URI = $matches[2];
1223
+ if(! $URI){
1224
+ $URI = '/';
1225
+ }
1226
+ $sslFile = wfCache::fileFromURI($host, $URI, true); //SSL
1227
+ $normalFile = wfCache::fileFromURI($host, $URI, false); //non-SSL
1228
+ @unlink($sslFile);
1229
+ @unlink($sslFile . '_gzip');
1230
+ @unlink($normalFile);
1231
+ @unlink($normalFile . '_gzip');
1232
+ }
1233
+ return array('ok' => 1);
1234
+ }
1235
  public static function ajax_saveCacheOptions_callback(){
1236
+ $changed = false;
1237
+ if($_POST['allowHTTPSCaching'] != wfConfig::get('allowHTTPSCaching', false)){
1238
+ $changed = true;
1239
+ }
1240
  wfConfig::set('allowHTTPSCaching', $_POST['allowHTTPSCaching'] == '1' ? 1 : 0);
1241
  wfConfig::set('addCacheComment', $_POST['addCacheComment'] == 1 ? '1' : 0);
1242
+ if($changed && wfConfig::get('cacheType', false) == 'falcon'){
1243
  $err = wfCache::addHtaccessCode('add');
1244
  if($err){
1245
+ return array('updateErr' => "Wordfence could not edit your .htaccess file. The error was: " . $err, 'code' => wfCache::getHtaccessCode() );
1246
  }
1247
  }
1248
  wfCache::scheduleCacheClear();
1281
  return array('errorMsg' => "You need to enable Permalinks for your site to use Falcon Engine. You can enable Permalinks in WordPress by going to the Settings - Permalinks menu and enabling it there. Permalinks change your site URL structure from something that looks like /p=123 to pretty URLs like /my-new-post-today/ that are generally more search engine friendly.");
1282
  }
1283
  }
1284
+ $warnHtaccess = false;
1285
  if($cacheType == 'disable' || $cacheType == 'php'){
1286
  $removeError = wfCache::addHtaccessCode('remove');
1287
+ $removeError2 = wfCache::updateBlockedIPs('remove');
1288
+ if($removeError || $removeError2){
1289
+ $warnHtaccess = true;
 
 
 
1290
  }
1291
  }
1292
  if($cacheType == 'php' || $cacheType == 'falcon'){
1300
  if($cacheType != wfConfig::get('cacheType', false)){
1301
  wfCache::scheduleCacheClear();
1302
  }
1303
+ $htMsg = "";
1304
+ if($warnHtaccess){
1305
+ $htMsg = " <strong style='color: #F00;'>Warning: We could not remove the caching code from your .htaccess file. you need to remove this manually yourself.</strong> ";
1306
+ }
1307
  if($cacheType == 'disable'){
1308
  wfConfig::set('cacheType', false);
1309
+ return array('ok' => 1, 'heading' => "Caching successfully disabled.", 'body' => "{$htMsg}Caching has been disabled on your system.<br /><br /><center><input type='button' name='wfReload' value='Click here now to refresh this page' onclick='window.location.reload(true);' /></center>");
1310
  } else if($cacheType == 'php'){
1311
  wfConfig::set('cacheType', 'php');
1312
+ return array('ok' => 1, 'heading' => "Wordfence Basic Caching Enabled", 'body' => "{$htMsg}Wordfence basic caching has been enabled on your system.<br /><br /><center><input type='button' name='wfReload' value='Click here now to refresh this page' onclick='window.location.reload(true);' /></center>");
1313
  } else if($cacheType == 'falcon'){
1314
+ if($_POST['noEditHtaccess'] != '1'){
1315
+ $err = wfCache::addHtaccessCode('add');
1316
+ if($err){
1317
+ return array('ok' => 1, 'heading' => "Wordfence could not edit .htaccess", 'body' => "Wordfence could not edit your .htaccess code. The error was: " . $err);
1318
+ }
1319
  }
1320
  wfConfig::set('cacheType', 'falcon');
1321
  wfCache::scheduleUpdateBlockedIPs(); //Runs every 5 mins until we change cachetype
1373
  wfConfig::set($key, $val);
1374
  return array('ok' => 1);
1375
  }
1376
+ public static function ajax_checkFalconHtaccess_callback(){
1377
+ $file = wfCache::getHtaccessPath();
1378
+ if(! $file){
1379
+ return array('err' => "We could not find your .htaccess file to modify it.", 'code' => wfCache::getHtaccessCode() );
1380
+ }
1381
+ $fh = @fopen($file, 'r+');
1382
+ if(! $fh){
1383
+ $err = error_get_last();
1384
+ return array('err' => "We found your .htaccess file but could not open it for writing: " . $err['message'], 'code' => wfCache::getHtaccessCode() );
1385
+ }
1386
+ return array('ok' => 1);
1387
+ }
1388
  public static function ajax_downloadHtaccess_callback(){
1389
  $url = site_url();
1390
  $url = preg_replace('/^https?:\/\//i', '', $url);
1392
  $url = preg_replace('/^_+/', '', $url);
1393
  $url = preg_replace('/_+$/', '', $url);
1394
  header('Content-Type: application/octet-stream');
1395
+ header('Content-Disposition: attachment; filename="htaccess_Backup_for_' . $url . '.txt"');
1396
+ $file = wfCache::getHtaccessPath();
1397
  readfile($file);
1398
  die();
1399
  }
2224
  }
2225
  public static function admin_init(){
2226
  if(! wfUtils::isAdmin()){ return; }
2227
+ foreach(array('activate', 'scan', 'updateAlertEmail', 'sendActivityLog', 'restoreFile', 'bulkOperation', 'deleteFile', 'removeExclusion', 'activityLogUpdate', 'ticker', 'loadIssues', 'updateIssueStatus', 'deleteIssue', 'updateAllIssues', 'reverseLookup', 'unlockOutIP', 'loadBlockRanges', 'unblockRange', 'blockIPUARange', 'whois', 'unblockIP', 'blockIP', 'permBlockIP', 'loadStaticPanel', 'saveConfig', 'downloadHtaccess', 'checkFalconHtaccess', 'updateConfig', 'saveCacheConfig', 'removeFromCache', 'saveCacheOptions', 'clearPageCache', 'getCacheStats', 'clearAllBlocked', 'killScan', 'saveCountryBlocking', 'saveScanSchedule', 'tourClosed', 'startTourAgain', 'downgradeLicense', 'addTwoFactor', 'twoFacActivate', 'twoFacDel', 'loadTwoFactor', 'loadAvgSitePerf', 'addCacheExclusion', 'removeCacheExclusion', 'loadCacheExclusions') as $func){
2228
  add_action('wp_ajax_wordfence_' . $func, 'wordfence::ajaxReceiver');
2229
  }
2230
 
lib/wordfenceConstants.php CHANGED
@@ -1,5 +1,5 @@
1
  <?php
2
- define('WORDFENCE_API_VERSION', '2.8');
3
  define('WORDFENCE_API_URL_SEC', 'https://noc1.wordfence.com/');
4
  define('WORDFENCE_API_URL_NONSEC', 'http://noc1.wordfence.com/');
5
  define('WORDFENCE_MAX_SCAN_TIME', 86400); //Increased this from 10 mins to 1 day because very big scans run for a long time. Users can use kill.
1
  <?php
2
+ define('WORDFENCE_API_VERSION', '2.9');
3
  define('WORDFENCE_API_URL_SEC', 'https://noc1.wordfence.com/');
4
  define('WORDFENCE_API_URL_NONSEC', 'http://noc1.wordfence.com/');
5
  define('WORDFENCE_MAX_SCAN_TIME', 86400); //Increased this from 10 mins to 1 day because very big scans run for a long time. Users can use kill.
lib/wordfenceHash.php CHANGED
@@ -63,7 +63,7 @@ class wordfenceHash {
63
  $this->knownFiles = @json_decode($dataArr['data'], true);
64
  if(! is_array($this->knownFiles)){
65
  wordfence::statusEndErr();
66
- throw new Exception("Invaid response from Wordfence servers.");
67
  }
68
  wordfence::statusEnd($fetchCoreHashesStatus, false, true);
69
 
63
  $this->knownFiles = @json_decode($dataArr['data'], true);
64
  if(! is_array($this->knownFiles)){
65
  wordfence::statusEndErr();
66
+ throw new Exception("Invalid response from Wordfence servers.");
67
  }
68
  wordfence::statusEnd($fetchCoreHashesStatus, false, true);
69
 
readme.txt CHANGED
@@ -1,9 +1,9 @@
1
  === Wordfence Security ===
2
  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
4
  Requires at least: 3.3.1
5
- Tested up to: 3.8.1
6
- Stable tag: 5.0.3
7
 
8
  Wordfence Security is a free enterprise class security plugin that makes your site up to 50 times faster and more secure.
9
 
@@ -30,6 +30,7 @@ Wordfence Security:
30
  * Real-time blocking of known attackers. If another site using Wordfence is attacked and blocks the attacker, your site is automatically protected.
31
  * 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.
32
  * Includes two-factor authentication, also referred to as cellphone sign-in.
 
33
  * Wordfence includes two caching modes for compatability and has cache management features like the ability to clear the cache and monitor cache usage.
34
  * Enforce strong passwords among your administrators, publishers and users. Improve login security.
35
  * Scans core files, themes and plugins against WordPress.org repository versions to check their integrity. Verify security of your source.
@@ -161,6 +162,15 @@ cause a security hole on your site.
161
 
162
  == Changelog ==
163
 
 
 
 
 
 
 
 
 
 
164
  = 5.0.3 =
165
  * Removed ability to disable XML-RPC. The feature broke many mobile apps and other remote services.
166
 
1
  === Wordfence Security ===
2
  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
4
  Requires at least: 3.3.1
5
+ Tested up to: 3.9
6
+ Stable tag: 5.0.4
7
 
8
  Wordfence Security is a free enterprise class security plugin that makes your site up to 50 times faster and more secure.
9
 
30
  * Real-time blocking of known attackers. If another site using Wordfence is attacked and blocks the attacker, your site is automatically protected.
31
  * 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.
32
  * Includes two-factor authentication, also referred to as cellphone sign-in.
33
+ * Scans for the HeartBleed vulnerability - included in the free scan for all users.
34
  * Wordfence includes two caching modes for compatability and has cache management features like the ability to clear the cache and monitor cache usage.
35
  * Enforce strong passwords among your administrators, publishers and users. Improve login security.
36
  * Scans core files, themes and plugins against WordPress.org repository versions to check their integrity. Verify security of your source.
162
 
163
  == Changelog ==
164
 
165
+ = 5.0.4 =
166
+ * Feature: We now scan for the infamous heartbleed openssl vulnerability using a non-intrusive scan method safe for production servers.
167
+ * Improvement: We now check if .htaccess is writable and if not we give you rules to manually enable Falcon.
168
+ * Improvement: Once Falcon is enabled, if we can’t write to .htaccess, we fall back to PHP based IP blocking.
169
+ * Feature: You can now clear pages and posts from the cache on the list-posts page under each item or on their edit pages next to the Update button.
170
+ * Fix: We now support sites who use a root URI but store their files and .htaccess in a subdirectory of the web root.
171
+ * Fix: Added an additional filter to prevent crawlers like Bing who execute javascript from being logged as humans.
172
+ * Fix: Changed the extension of the backup .htaccess to be .txt to avoid anti-virus software alerting on a download with .com extension. [Props to Scott N. for catching this]
173
+
174
  = 5.0.3 =
175
  * Removed ability to disable XML-RPC. The feature broke many mobile apps and other remote services.
176
 
wordfence.php CHANGED
@@ -2,15 +2,15 @@
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: Wordfence
7
- Version: 5.0.3
8
  Author URI: http://www.wordfence.com/
9
  */
10
  if(defined('WP_INSTALLING') && WP_INSTALLING){
11
  return;
12
  }
13
- define('WORDFENCE_VERSION', '5.0.3');
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
  }
2
  /*
3
  Plugin Name: Wordfence Security
4
  Plugin URI: http://www.wordfence.com/
5
+ Description: Wordfence Security - Anti-virus, Firewal and Site Speedup
6
  Author: Wordfence
7
+ Version: 5.0.4
8
  Author URI: http://www.wordfence.com/
9
  */
10
  if(defined('WP_INSTALLING') && WP_INSTALLING){
11
  return;
12
  }
13
+ define('WORDFENCE_VERSION', '5.0.4');
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
  }