Wordfence Security – Firewall & Malware Scan - Version 6.3.15

Version Description

  • Improvement: Reduced memory usage on scan forking and during the known files scan stage.
  • Improvement: Added additional scan options to allow for disabling the blacklist checks while still allowing malware scanning to be enabled.
  • Improvement: Added a Wordfence Application Firewall code block for the lsapi variant of LiteSpeed.
  • Improvement: Updated the bundled GeoIP database.
  • Fix: Added a validation check to IP range whitelisting to avoid log warnings if they're malformed.
Download this release

Release Info

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

Code changes from version 6.3.14 to 6.3.15

lib/GeoIP.dat CHANGED
Binary file
lib/GeoIPv6.dat CHANGED
Binary file
lib/menu_options.php CHANGED
@@ -8,19 +8,6 @@ $w = new wfConfig();
8
$pageTitle = "Wordfence Options";
9
$wantsLiveActivity = true;
10
include( 'pageTitle.php' ); ?>
11
- <!-- <div class="wordfenceLive">
12
- <table border="0" cellpadding="0" cellspacing="0" class="wordfenceLiveActivity">
13
- <tr>
14
- <td><h2>Wordfence Live Activity:</h2></td>
15
- <td id="wfLiveStatus"></td>
16
- </tr>
17
- </table>
18
- <table border="0" cellpadding="0" cellspacing="0" class="wordfenceLiveStateMessage">
19
- <tr>
20
- <td>Live Updates Paused &mdash; Click inside window to resume</td>
21
- </tr>
22
- </table>
23
- </div> -->
24
25
<div class="wf-container-fluid">
26
<div class="wf-row">
@@ -108,6 +95,13 @@ $w = new wfConfig();
108
<span class="wf-help-block"><span style="color: #F00;">Premium Feature</span> In addition to free comment filtering (see below) this option filters comments against several additional real-time lists of known spammers and infected hosts.</span>
109
</div>
110
</div>
111
<div class="wf-form-group">
112
<label for="spamvertizeCheck" class="wf-col-sm-5 wf-control-label">Check if this website is being "Spamvertised" <a href="http://docs.wordfence.com/en/Wordfence_options#Check_if_this_website_is_being_.22Spamvertized.22" target="_blank" rel="noopener noreferrer" class="wfhelp"></a></label>
113
<div class="wf-col-sm-7">
@@ -440,6 +434,10 @@ $w = new wfConfig();
440
),
441
),
442
),
443
array(
444
'id' => 'scansEnabled_posts',
445
'label' => 'Scan posts for known dangerous URLs and suspicious content <a href="http://docs.wordfence.com/en/Wordfence_options#Scan_posts_for_known_dangerous_URLs_and_suspicious_content" target="_blank" rel="noopener noreferrer" class="wfhelp"></a>',
8
$pageTitle = "Wordfence Options";
9
$wantsLiveActivity = true;
10
include( 'pageTitle.php' ); ?>
11
12
<div class="wf-container-fluid">
13
<div class="wf-row">
95
<span class="wf-help-block"><span style="color: #F00;">Premium Feature</span> In addition to free comment filtering (see below) this option filters comments against several additional real-time lists of known spammers and infected hosts.</span>
96
</div>
97
</div>
98
+ <div class="wf-form-group">
99
+ <label for="scansEnabled_checkGSB" class="wf-col-sm-5 wf-control-label">Check if this website is on a domain blacklist <a href="http://docs.wordfence.com/en/Wordfence_options#Check_if_this_website_is_on_a_domain_blacklist" target="_blank" rel="noopener noreferrer" class="wfhelp"></a></label>
100
+ <div class="wf-col-sm-7">
101
+ <div class="wf-checkbox"><input type="checkbox" id="scansEnabled_checkGSB" class="wfConfigElem" name="scansEnabled_checkGSB" value="1" <?php $w->cbp( 'scansEnabled_checkGSB' ); if (!wfConfig::get('isPaid')) { ?>onclick="alert('This is a paid feature because it places significant additional load on our servers.'); jQuery('#scansEnabled_checkGSB').attr('checked', false); return false;" <?php } ?>></div>
102
+ <span class="wf-help-block"><span style="color: #F00;">Premium Feature</span> When doing a scan, Wordfence will check with multiple domain blacklists to see if your site is listed.</span>
103
+ </div>
104
+ </div>
105
<div class="wf-form-group">
106
<label for="spamvertizeCheck" class="wf-col-sm-5 wf-control-label">Check if this website is being "Spamvertised" <a href="http://docs.wordfence.com/en/Wordfence_options#Check_if_this_website_is_being_.22Spamvertized.22" target="_blank" rel="noopener noreferrer" class="wfhelp"></a></label>
107
<div class="wf-col-sm-7">
434
),
435
),
436
),
437
+ array(
438
+ 'id' => 'scansEnabled_fileContentsGSB',
439
+ 'label' => 'Scan file contents for malicious URLs <a href="http://docs.wordfence.com/en/Wordfence_options#Scan_file_contents_for_malicious_URLs" target="_blank" rel="noopener noreferrer" class="wfhelp"></a>',
440
+ ),
441
array(
442
'id' => 'scansEnabled_posts',
443
'label' => 'Scan posts for known dangerous URLs and suspicious content <a href="http://docs.wordfence.com/en/Wordfence_options#Scan_posts_for_known_dangerous_URLs_and_suspicious_content" target="_blank" rel="noopener noreferrer" class="wfhelp"></a>',
lib/menu_scan_options.php CHANGED
@@ -55,6 +55,10 @@ $w = new wfConfig();
55
),
56
),
57
),
58
array(
59
'id' => 'scansEnabled_posts',
60
'label' => 'Scan posts for known dangerous URLs and suspicious content <a href="http://docs.wordfence.com/en/Wordfence_options#Scan_posts_for_known_dangerous_URLs_and_suspicious_content" target="_blank" rel="noopener noreferrer" class="wfhelp"></a>',
55
),
56
),
57
),
58
+ array(
59
+ 'id' => 'scansEnabled_fileContentsGSB',
60
+ 'label' => 'Scan file contents for malicious URLs <a href="http://docs.wordfence.com/en/Wordfence_options#Scan_file_contents_for_malicious_URLs" target="_blank" rel="noopener noreferrer" class="wfhelp"></a>',
61
+ ),
62
array(
63
'id' => 'scansEnabled_posts',
64
'label' => 'Scan posts for known dangerous URLs and suspicious content <a href="http://docs.wordfence.com/en/Wordfence_options#Scan_posts_for_known_dangerous_URLs_and_suspicious_content" target="_blank" rel="noopener noreferrer" class="wfhelp"></a>',
lib/wfAPI.php CHANGED
@@ -122,8 +122,8 @@ class wfAPI {
122
throw new Exception("The Wordfence scanning servers are currently unavailable. This may be for maintenance or a temporary outage. If this still occurs in an hour, please contact support. [$this->lastHTTPStatus]");
123
}
124
125
- $this->curlContent = wp_remote_retrieve_body($response);
126
- return $this->curlContent;
127
}
128
129
public function binCall($func, $postData) {
122
throw new Exception("The Wordfence scanning servers are currently unavailable. This may be for maintenance or a temporary outage. If this still occurs in an hour, please contact support. [$this->lastHTTPStatus]");
123
}
124
125
+ $content = wp_remote_retrieve_body($response);
126
+ return $content;
127
}
128
129
public function binCall($func, $postData) {
lib/wfConfig.php CHANGED
@@ -34,6 +34,7 @@ class wfConfig {
34
//"perfLoggingEnabled" => array('value' => false, 'autoload' => self::AUTOLOAD),
35
"scheduledScansEnabled" => array('value' => true, 'autoload' => self::AUTOLOAD),
36
"lowResourceScansEnabled" => array('value' => false, 'autoload' => self::AUTOLOAD),
37
"scansEnabled_checkHowGetIPs" => array('value' => true, 'autoload' => self::AUTOLOAD),
38
"scansEnabled_core" => array('value' => true, 'autoload' => self::AUTOLOAD),
39
"scansEnabled_themes" => array('value' => false, 'autoload' => self::AUTOLOAD),
@@ -41,6 +42,7 @@ class wfConfig {
41
"scansEnabled_coreUnknown" => array('value' => true, 'autoload' => self::AUTOLOAD),
42
"scansEnabled_malware" => array('value' => true, 'autoload' => self::AUTOLOAD),
43
"scansEnabled_fileContents" => array('value' => true, 'autoload' => self::AUTOLOAD),
44
"scansEnabled_checkReadableConfig" => array('value' => true, 'autoload' => self::AUTOLOAD),
45
"scansEnabled_suspectedFiles" => array('value' => true, 'autoload' => self::AUTOLOAD),
46
"scansEnabled_posts" => array('value' => true, 'autoload' => self::AUTOLOAD),
34
//"perfLoggingEnabled" => array('value' => false, 'autoload' => self::AUTOLOAD),
35
"scheduledScansEnabled" => array('value' => true, 'autoload' => self::AUTOLOAD),
36
"lowResourceScansEnabled" => array('value' => false, 'autoload' => self::AUTOLOAD),
37
+ "scansEnabled_checkGSB" => array('value' => true, 'autoload' => self::AUTOLOAD),
38
"scansEnabled_checkHowGetIPs" => array('value' => true, 'autoload' => self::AUTOLOAD),
39
"scansEnabled_core" => array('value' => true, 'autoload' => self::AUTOLOAD),
40
"scansEnabled_themes" => array('value' => false, 'autoload' => self::AUTOLOAD),
42
"scansEnabled_coreUnknown" => array('value' => true, 'autoload' => self::AUTOLOAD),
43
"scansEnabled_malware" => array('value' => true, 'autoload' => self::AUTOLOAD),
44
"scansEnabled_fileContents" => array('value' => true, 'autoload' => self::AUTOLOAD),
45
+ "scansEnabled_fileContentsGSB" => array('value' => true, 'autoload' => self::AUTOLOAD),
46
"scansEnabled_checkReadableConfig" => array('value' => true, 'autoload' => self::AUTOLOAD),
47
"scansEnabled_suspectedFiles" => array('value' => true, 'autoload' => self::AUTOLOAD),
48
"scansEnabled_posts" => array('value' => true, 'autoload' => self::AUTOLOAD),
lib/wfLog.php CHANGED
@@ -1307,6 +1307,10 @@ class wfUserIPRange {
1307
$IPparts = explode('.', $ip);
1308
$whiteParts = explode('.', $ip_string);
1309
$mismatch = false;
1310
for ($i = 0; $i <= 3; $i++) {
1311
if (preg_match('/^\[(\d+)\-(\d+)\]#x2F;', $whiteParts[$i], $m)) {
1312
if ($IPparts[$i] < $m[1] || $IPparts[$i] > $m[2]) {
@@ -1331,6 +1335,10 @@ class wfUserIPRange {
1331
$IPparts = explode(':', $ip);
1332
$whiteParts = explode(':', $ip_string);
1333
$mismatch = false;
1334
for ($i = 0; $i <= 7; $i++) {
1335
if (preg_match('/^\[([a-f0-9]+)\-([a-f0-9]+)\]#x2F;i', $whiteParts[$i], $m)) {
1336
$ip_group = hexdec($IPparts[$i]);
1307
$IPparts = explode('.', $ip);
1308
$whiteParts = explode('.', $ip_string);
1309
$mismatch = false;
1310
+ if (count($whiteParts) != 4 || count($IPparts) != 4) {
1311
+ return false;
1312
+ }
1313
+
1314
for ($i = 0; $i <= 3; $i++) {
1315
if (preg_match('/^\[(\d+)\-(\d+)\]#x2F;', $whiteParts[$i], $m)) {
1316
if ($IPparts[$i] < $m[1] || $IPparts[$i] > $m[2]) {
1335
$IPparts = explode(':', $ip);
1336
$whiteParts = explode(':', $ip_string);
1337
$mismatch = false;
1338
+ if (count($whiteParts) != 8 || count($IPparts) != 8) {
1339
+ return false;
1340
+ }
1341
+
1342
for ($i = 0; $i <= 7; $i++) {
1343
if (preg_match('/^\[([a-f0-9]+)\-([a-f0-9]+)\]#x2F;i', $whiteParts[$i], $m)) {
1344
$ip_group = hexdec($IPparts[$i]);
lib/wfScanEngine.php CHANGED
@@ -138,23 +138,22 @@ class wfScanEngine {
138
$jobs[] = 'checkGSB';
139
$jobs[] = 'checkHowGetIPs';
140
$jobs[] = 'knownFiles';
141
- foreach (array('knownFiles', 'checkReadableConfig', 'fileContents', 'suspectedFiles',
142
- // 'wpscan_fullPathDisclosure', 'wpscan_directoryListingEnabled',
143
- 'posts', 'comments', 'passwds', 'dns', 'diskSpace', 'oldVersions', 'suspiciousAdminUsers') as $job) {
144
- if (wfConfig::get('scansEnabled_' . $job)) {
145
- $jobs[] = $job;
146
- }
147
- }
148
}
149
else if ($scanMode == self::SCAN_MODE_QUICK) {
150
- foreach (array('oldVersions') as $job) {
151
- if (wfConfig::get('scansEnabled_' . $job)) {
152
- $jobs[] = $job;
153
- }
154
- }
155
}
156
return $jobs;
157
}
158
159
public function __sleep(){ //Same order here as above for properties that are included in serialization
160
return array('hasher', 'jobList', 'i', 'wp_version', 'apiKey', 'startTime', 'maxExecTime', 'publicScanEnabled', 'fileContentsResults', 'scanner', 'scanQueue', 'hoover', 'scanData', 'statusIDX', 'userPasswdQueue', 'passwdHasIssues', 'suspectedFiles', 'dbScanner', 'knownFilesLoader', 'metrics', 'checkHowGetIPsRequestTime', 'gsbMultisiteBlogOffset', 'updateCheck', 'pluginRepoStatus', 'malwarePrefixesHash', 'scanMode');
@@ -411,14 +410,23 @@ class wfScanEngine {
411
412
private function scan_checkGSB_init() {
413
if (wfConfig::get('isPaid')) {
414
- $this->statusIDX['checkGSB'] = wfIssues::statusStart("Checking if your site is on a domain blacklist");
415
- $h = new wordfenceURLHoover($this->apiKey, $this->wp_version);
416
- $h->cleanup();
417
}
418
}
419
420
private function scan_checkGSB_main() {
421
- if (wfConfig::get('isPaid')) {
422
if (is_multisite()) {
423
global $wpdb;
424
$h = new wordfenceURLHoover($this->apiKey, $this->wp_version, false, true);
@@ -441,7 +449,7 @@ class wfScanEngine {
441
}
442
443
private function scan_checkGSB_finish() {
444
- if (wfConfig::get('isPaid')) {
445
if (is_multisite()) {
446
$h = new wordfenceURLHoover($this->apiKey, $this->wp_version, false, true);
447
$badURLs = $h->getBaddies();
@@ -531,9 +539,6 @@ class wfScanEngine {
531
}
532
533
wfIssues::statusEnd($this->statusIDX['checkGSB'], $haveIssues);
534
- } else {
535
- wfIssues::statusPaidOnly("Checking if your site is on a domain blacklist is for paid members only");
536
- sleep(2);
537
}
538
}
539
@@ -792,38 +797,65 @@ class wfScanEngine {
792
private function scan_knownFiles_finish(){
793
}
794
private function scan_fileContents_init(){
795
- $this->statusIDX['infect'] = wfIssues::statusStart('Scanning file contents for infections and vulnerabilities');
796
- $this->statusIDX['GSB'] = wfIssues::statusStart('Scanning files for URLs on a domain blacklist');
797
- $this->scanner = new wordfenceScanner($this->apiKey, $this->wp_version, ABSPATH);
798
- $this->status(2, 'info', "Starting scan of file contents");
799
}
800
private function scan_fileContents_main(){
801
- $this->fileContentsResults = $this->scanner->scan($this);
802
}
803
private function scan_fileContents_finish(){
804
- $this->status(2, 'info', "Done file contents scan");
805
- if($this->scanner->errorMsg){
806
- throw new Exception($this->scanner->errorMsg);
807
- }
808
- $this->scanner = null;
809
- $haveIssues = wfIssues::STATUS_SECURE;
810
- $haveIssuesGSB = wfIssues::STATUS_SECURE;
811
- foreach($this->fileContentsResults as $issue){
812
- $this->status(2, 'info', "Adding issue: " . $issue['shortMsg']);
813
- $added = $this->addIssue($issue['type'], $issue['severity'], $issue['ignoreP'], $issue['ignoreC'], $issue['shortMsg'], $issue['longMsg'], $issue['data']);
814
815
- if (isset($issue['data']['gsb'])) {
816
- if ($added == wfIssues::ISSUE_ADDED || $added == wfIssues::ISSUE_UPDATED) { $haveIssuesGSB = wfIssues::STATUS_PROBLEM; }
817
- else if ($haveIssuesGSB != wfIssues::STATUS_PROBLEM && ($added == wfIssues::ISSUE_IGNOREP || $added == wfIssues::ISSUE_IGNOREC)) { $haveIssuesGSB = wfIssues::STATUS_IGNORED; }
818
}
819
- else {
820
- if ($added == wfIssues::ISSUE_ADDED || $added == wfIssues::ISSUE_UPDATED) { $haveIssues = wfIssues::STATUS_PROBLEM; }
821
- else if ($haveIssues != wfIssues::STATUS_PROBLEM && ($added == wfIssues::ISSUE_IGNOREP || $added == wfIssues::ISSUE_IGNOREC)) { $haveIssues = wfIssues::STATUS_IGNORED; }
822
}
823
}
824
- $this->fileContentsResults = null;
825
- wfIssues::statusEnd($this->statusIDX['infect'], $haveIssues);
826
- wfIssues::statusEnd($this->statusIDX['GSB'], $haveIssuesGSB);
827
}
828
829
private function scan_suspectedFiles() {
138
$jobs[] = 'checkGSB';
139
$jobs[] = 'checkHowGetIPs';
140
$jobs[] = 'knownFiles';
141
+ self::_enqueueJobs(array('knownFiles', 'checkReadableConfig'), $jobs);
142
+ $jobs[] = 'fileContents';
143
+ self::_enqueueJobs(array('suspectedFiles', 'posts', 'comments', 'passwds', 'dns', 'diskSpace', 'oldVersions', 'suspiciousAdminUsers'), $jobs);
144
}
145
else if ($scanMode == self::SCAN_MODE_QUICK) {
146
+ self::_enqueueJobs(array('oldVersions'), $jobs);
147
}
148
return $jobs;
149
}
150
+ private static function _enqueueJobs($possibleJobs, &$jobs) {
151
+ foreach ($possibleJobs as $job) {
152
+ if (wfConfig::get('scansEnabled_' . $job)) {
153
+ $jobs[] = $job;
154
+ }
155
+ }
156
+ }
157
158
public function __sleep(){ //Same order here as above for properties that are included in serialization
159
return array('hasher', 'jobList', 'i', 'wp_version', 'apiKey', 'startTime', 'maxExecTime', 'publicScanEnabled', 'fileContentsResults', 'scanner', 'scanQueue', 'hoover', 'scanData', 'statusIDX', 'userPasswdQueue', 'passwdHasIssues', 'suspectedFiles', 'dbScanner', 'knownFilesLoader', 'metrics', 'checkHowGetIPsRequestTime', 'gsbMultisiteBlogOffset', 'updateCheck', 'pluginRepoStatus', 'malwarePrefixesHash', 'scanMode');
410
411
private function scan_checkGSB_init() {
412
if (wfConfig::get('isPaid')) {
413
+ if (wfConfig::get('scansEnabled_checkGSB')) {
414
+ $this->statusIDX['checkGSB'] = wfIssues::statusStart("Checking if your site is on a domain blacklist");
415
+ $h = new wordfenceURLHoover($this->apiKey, $this->wp_version);
416
+ $h->cleanup();
417
+ }
418
+ else {
419
+ wfIssues::statusDisabled("Skipping check if your site is on a domain blacklist");
420
+ }
421
+ }
422
+ else {
423
+ wfIssues::statusPaidOnly("Checking if your site is on a domain blacklist is for paid members only");
424
+ sleep(2);
425
}
426
}
427
428
private function scan_checkGSB_main() {
429
+ if (wfConfig::get('isPaid') && wfConfig::get('scansEnabled_checkGSB')) {
430
if (is_multisite()) {
431
global $wpdb;
432
$h = new wordfenceURLHoover($this->apiKey, $this->wp_version, false, true);
449
}
450
451
private function scan_checkGSB_finish() {
452
+ if (wfConfig::get('isPaid') && wfConfig::get('scansEnabled_checkGSB')) {
453
if (is_multisite()) {
454
$h = new wordfenceURLHoover($this->apiKey, $this->wp_version, false, true);
455
$badURLs = $h->getBaddies();
539
}
540
541
wfIssues::statusEnd($this->statusIDX['checkGSB'], $haveIssues);
542
}
543
}
544
797
private function scan_knownFiles_finish(){
798
}
799
private function scan_fileContents_init(){
800
+ if (wfConfig::get('scansEnabled_fileContents')) {
801
+ $this->statusIDX['infect'] = wfIssues::statusStart('Scanning file contents for infections and vulnerabilities');
802
+ }
803
+ else {
804
+ wfIssues::statusDisabled("Skipping scan of file contents for infections and vulnerabilities");
805
+ }
806
+
807
+ if (wfConfig::get('scansEnabled_fileContentsGSB')) {
808
+ $this->statusIDX['GSB'] = wfIssues::statusStart('Scanning file contents for URLs on a domain blacklist');
809
+ }
810
+ else {
811
+ wfIssues::statusDisabled("Skipping scan of file contents for URLs on a domain blacklist");
812
+ }
813
+
814
+ if (wfConfig::get('scansEnabled_fileContents') || wfConfig::get('scansEnabled_fileContentsGSB')) {
815
+ $this->scanner = new wordfenceScanner($this->apiKey, $this->wp_version, ABSPATH);
816
+ $this->status(2, 'info', "Starting scan of file contents");
817
+ }
818
+ else {
819
+ $this->scanner = false;
820
+ }
821
}
822
private function scan_fileContents_main(){
823
+ if (wfConfig::get('scansEnabled_fileContents') || wfConfig::get('scansEnabled_fileContentsGSB')) {
824
+ $this->fileContentsResults = $this->scanner->scan($this);
825
+ }
826
}
827
private function scan_fileContents_finish(){
828
+ if (wfConfig::get('scansEnabled_fileContents') || wfConfig::get('scansEnabled_fileContentsGSB')) {
829
+ $this->status(2, 'info', "Done file contents scan");
830
+ if($this->scanner->errorMsg){
831
+ throw new Exception($this->scanner->errorMsg);
832
+ }
833
+ $this->scanner = null;
834
+ $haveIssues = wfIssues::STATUS_SECURE;
835
+ $haveIssuesGSB = wfIssues::STATUS_SECURE;
836
+ foreach($this->fileContentsResults as $issue){
837
+ $this->status(2, 'info', "Adding issue: " . $issue['shortMsg']);
838
+ $added = $this->addIssue($issue['type'], $issue['severity'], $issue['ignoreP'], $issue['ignoreC'], $issue['shortMsg'], $issue['longMsg'], $issue['data']);
839
+
840
+ if (isset($issue['data']['gsb'])) {
841
+ if ($added == wfIssues::ISSUE_ADDED || $added == wfIssues::ISSUE_UPDATED) { $haveIssuesGSB = wfIssues::STATUS_PROBLEM; }
842
+ else if ($haveIssuesGSB != wfIssues::STATUS_PROBLEM && ($added == wfIssues::ISSUE_IGNOREP || $added == wfIssues::ISSUE_IGNOREC)) { $haveIssuesGSB = wfIssues::STATUS_IGNORED; }
843
+ }
844
+ else {
845
+ if ($added == wfIssues::ISSUE_ADDED || $added == wfIssues::ISSUE_UPDATED) { $haveIssues = wfIssues::STATUS_PROBLEM; }
846
+ else if ($haveIssues != wfIssues::STATUS_PROBLEM && ($added == wfIssues::ISSUE_IGNOREP || $added == wfIssues::ISSUE_IGNOREC)) { $haveIssues = wfIssues::STATUS_IGNORED; }
847
+ }
848
+ }
849
+ $this->fileContentsResults = null;
850
851
+ if (wfConfig::get('scansEnabled_fileContents')) {
852
+ wfIssues::statusEnd($this->statusIDX['infect'], $haveIssues);
853
}
854
+
855
+ if (wfConfig::get('scansEnabled_fileContentsGSB')) {
856
+ wfIssues::statusEnd($this->statusIDX['GSB'], $haveIssuesGSB);
857
}
858
}
859
}
860
861
private function scan_suspectedFiles() {
lib/wordfenceClass.php CHANGED
@@ -725,6 +725,15 @@ SQL
725
$wpdb->query("ALTER TABLE {$hooverTable} CHANGE `hostKey` `hostKey` VARBINARY(124) NULL DEFAULT NULL");
726
}
727
728
729
//Check the How does Wordfence get IPs setting
730
wfUtils::requestDetectProxyCallback();
@@ -5532,7 +5541,7 @@ document.location.href=$adminURL;
5532
array("cgi", 'Apache + CGI/FastCGI', $serverInfo->isApache() &&
5533
!$serverInfo->isApacheSuPHP() &&
5534
($serverInfo->isCGI() || $serverInfo->isFastCGI())),
5535
- array("litespeed", 'LiteSpeed', $serverInfo->isLiteSpeed()),
5536
array("nginx", 'NGINX', $serverInfo->isNGINX()),
5537
array("iis", 'Windows (IIS)', $serverInfo->isIIS()),
5538
);
@@ -5666,7 +5675,7 @@ vulnerable code runs. This PHP setting currently refers to the Wordfence file at
5666
array("cgi", 'Apache + CGI/FastCGI', $serverInfo->isApache() &&
5667
!$serverInfo->isApacheSuPHP() &&
5668
($serverInfo->isCGI() || $serverInfo->isFastCGI())),
5669
- array("litespeed", 'LiteSpeed', $serverInfo->isLiteSpeed()),
5670
array("nginx", 'NGINX', $serverInfo->isNGINX()),
5671
array("iis", 'Windows (IIS)', $serverInfo->isIIS()),
5672
);
@@ -7644,13 +7653,17 @@ $userIniHtaccessDirectives
7644
break;
7645
7646
case 'litespeed':
7647
$autoPrependDirective = sprintf("# Wordfence WAF
7648
<IfModule LiteSpeed>
7649
php_value auto_prepend_file '%s'
7650
</IfModule>
7651
$userIniHtaccessDirectives
7652
# END Wordfence WAF
7653
- ", addcslashes($bootstrapPath, "'"));
7654
break;
7655
7656
case 'apache-suphp':
725
$wpdb->query("ALTER TABLE {$hooverTable} CHANGE `hostKey` `hostKey` VARBINARY(124) NULL DEFAULT NULL");
726
}
727
728
+ //6.3.15
729
+ $scanFileContents = wfConfig::get('scansEnabled_fileContents', false);
730
+ if (!wfConfig::get('fileContentsGSB6315Migration', false)) {
731
+ if (!$scanFileContents) {
732
+ wfConfig::set('scansEnabled_fileContentsGSB', false);
733
+ }
734
+ wfConfig::set('fileContentsGSB6315Migration', 1);
735
+ }
736
+
737
738
//Check the How does Wordfence get IPs setting
739
wfUtils::requestDetectProxyCallback();
5541
array("cgi", 'Apache + CGI/FastCGI', $serverInfo->isApache() &&
5542
!$serverInfo->isApacheSuPHP() &&
5543
($serverInfo->isCGI() || $serverInfo->isFastCGI())),
5544
+ array("litespeed", 'LiteSpeed/lsapi', $serverInfo->isLiteSpeed()),
5545
array("nginx", 'NGINX', $serverInfo->isNGINX()),
5546
array("iis", 'Windows (IIS)', $serverInfo->isIIS()),
5547
);
5675
array("cgi", 'Apache + CGI/FastCGI', $serverInfo->isApache() &&
5676
!$serverInfo->isApacheSuPHP() &&
5677
($serverInfo->isCGI() || $serverInfo->isFastCGI())),
5678
+ array("litespeed", 'LiteSpeed/lsapi', $serverInfo->isLiteSpeed()),
5679
array("nginx", 'NGINX', $serverInfo->isNGINX()),
5680
array("iis", 'Windows (IIS)', $serverInfo->isIIS()),
5681
);
7653
break;
7654
7655
case 'litespeed':
7656
+ $escapedBootstrapPath = addcslashes($bootstrapPath, "'");
7657
$autoPrependDirective = sprintf("# Wordfence WAF
7658
<IfModule LiteSpeed>
7659
php_value auto_prepend_file '%s'
7660
</IfModule>
7661
+ <IfModule lsapi_module>
7662
+ php_value auto_prepend_file '%s'
7663
+ </IfModule>
7664
$userIniHtaccessDirectives
7665
# END Wordfence WAF
7666
+ ", $escapedBootstrapPath, $escapedBootstrapPath);
7667
break;
7668
7669
case 'apache-suphp':
lib/wordfenceScanner.php CHANGED
@@ -59,8 +59,19 @@ class wordfenceScanner {
59
$this->results = array();
60
$this->errorMsg = false;
61
//First extract hosts or IP's and their URL's into $this->hostsFound and URL's into $this->urlsFound
62
- $this->urlHoover = new wordfenceURLHoover($this->apiKey, $this->wordpressVersion);
63
- $this->setupSigs();
64
}
65
66
/**
@@ -69,7 +80,6 @@ class wordfenceScanner {
69
* @throws Exception
70
*/
71
protected function setupSigs() {
72
- $this->api = new wfAPI($this->apiKey, $this->wordpressVersion);
73
$sigData = $this->api->call('get_patterns', array(), array());
74
if(! (is_array($sigData) && isset($sigData['rules'])) ){
75
throw new Exception("Wordfence could not get the attack signature patterns from the scanning server.");
@@ -192,7 +202,10 @@ class wordfenceScanner {
192
}
193
194
//The site's own URL is checked in an earlier scan stage so we exclude it here.
195
- $hooverExclusions = wordfenceURLHoover::standardExcludedHosts();
196
197
$lastCount = 'whatever';
198
$excludePattern = self::getExcludeFilePattern(self::EXCLUSION_PATTERNS_USER | self::EXCLUSION_PATTERNS_MALWARE);
@@ -318,122 +331,124 @@ class wordfenceScanner {
318
}
319
320
$treatAsBinary = ($isPHP || $isHTML || wfConfig::get('scansEnabled_scanImages'));
321
- if ($treatAsBinary && wfUtils::strpos($data, '$allowed'.'Sites') !== false && wfUtils::strpos($data, "define ('VER"."SION', '1.") !== false && wfUtils::strpos($data, "TimThum"."b script created by") !== false) {
322
- $this->addResult(array(
323
- 'type' => 'file',
324
- 'severity' => 1,
325
- 'ignoreP' => $this->path . $file,
326
- 'ignoreC' => $fileSum,
327
- 'shortMsg' => "File is an old version of TimThumb which is vulnerable.",
328
- 'longMsg' => "This file appears to be an old version of the TimThumb script which makes your system vulnerable to attackers. Please upgrade the theme or plugin that uses this or remove it." . $extraMsg,
329
- 'data' => array_merge(array(
330
- 'file' => $file,
331
- 'shac' => $record->SHAC,
332
- ), $dataForFile),
333
- ));
334
- break;
335
- }
336
- else {
337
- $allCommonStrings = $this->patterns['commonStrings'];
338
- $commonStringsFound = array_fill(0, count($allCommonStrings), null); //Lazily looked up below
339
-
340
- $regexMatched = false;
341
- foreach ($this->patterns['rules'] as $rule) {
342
- $stoppedOnSignature = $record->stoppedOnSignature;
343
- if (!empty($stoppedOnSignature)) { //Advance until we find the rule we stopped on last time
344
- //wordfence::status(4, 'info', "Searching for malware scan resume point (". $stoppedOnSignature . ") at rule " . $rule[0]);
345
- if ($stoppedOnSignature == $rule[0]) {
346
- $record->updateStoppedOn('', $currentPosition);
347
- wordfence::status(4, 'info', "Resuming malware scan at rule {$rule[0]}.");
348
- }
349
- continue;
350
- }
351
-
352
- $type = (isset($rule[4]) && !empty($rule[4])) ? $rule[4] : 'server';
353
- $logOnly = (isset($rule[5]) && !empty($rule[5])) ? $rule[5] : false;
354
- $commonStringIndexes = (isset($rule[6]) && is_array($rule[6])) ? $rule[6] : array();
355
- if ($type == 'server' && !$treatAsBinary) { continue; }
356
- else if (($type == 'both' || $type == 'browser') && $fileExt == 'js') { $extraMsg = ''; }
357
- else if (($type == 'both' || $type == 'browser') && !$treatAsBinary) { continue; }
358
359
- foreach ($commonStringIndexes as $i) {
360
- if ($commonStringsFound[$i] === null) {
361
- $s = $allCommonStrings[$i];
362
- $commonStringsFound[$i] = (preg_match('/' . $s . '/i', $data) == 1);
363
}
364
365
- if (!$commonStringsFound[$i]) {
366
- //wordfence::status(4, 'info', "Skipping malware signature ({$rule[0]}) due to short circuit.");
367
- continue 2;
368
}
369
- }
370
-
371
- /*if (count($commonStringIndexes) > 0) {
372
- wordfence::status(4, 'info', "Processing malware signature ({$rule[0]}) because short circuit matched.");
373
- }*/
374
-
375
- if (preg_match('/(' . $rule[2] . ')/iS', $data, $matches, PREG_OFFSET_CAPTURE)) {
376
- $matchString = $matches[1][0];
377
- $matchOffset = $matches[1][1];
378
- $beforeString = wfWAFUtils::substr($data, max(0, $matchOffset - 100), $matchOffset - max(0, $matchOffset - 100));
379
- $afterString = wfWAFUtils::substr($data, $matchOffset + strlen($matchString), 100);
380
- if (!$logOnly) {
381
- $this->addResult(array(
382
- 'type' => 'file',
383
- 'severity' => 1,
384
- 'ignoreP' => $this->path . $file,
385
- 'ignoreC' => $fileSum,
386
- 'shortMsg' => "File appears to be malicious: " . esc_html($file),
387
- 'longMsg' => "This file appears to be installed by a hacker to perform malicious activity. If you know about this file you can choose to ignore it to exclude it from future scans. The text we found in this file that matches a known malicious file is: <strong style=\"color: #F00;\" class=\"wf-split-word\">\"" . wfUtils::potentialBinaryStringToHTML((wfUtils::strlen($matchString) > 200 ? wfUtils::substr($matchString, 0, 200) . '...' : $matchString)) . "\"</strong>. The infection type is: <strong>" . esc_html($rule[3]) . '</strong>.' . $extraMsg,
388
- 'data' => array_merge(array(
389
- 'file' => $file,
390
- 'shac' => $record->SHAC,
391
- ), $dataForFile),
392
- ));
393
}
394
- $regexMatched = true;
395
- $this->scanEngine->recordMetric('malwareSignature', $rule[0], array('file' => $file, 'match' => $matchString, 'before' => $beforeString, 'after' => $afterString), false);
396
- break;
397
- }
398
-
399
- if ($forkObj->shouldFork()) {
400
- $record->updateStoppedOn($rule[0], $currentPosition);
401
- fclose($fh);
402
403
- wordfence::status(4, 'info', "Forking during malware scan ({$rule[0]}) to ensure continuity.");
404
- $forkObj->fork(); //exits
405
}
406
}
407
- if ($regexMatched) { break; }
408
- }
409
- if ($treatAsBinary && wfConfig::get('scansEnabled_highSense')) {
410
- $badStringFound = false;
411
- if (strpos($data, $this->patterns['badstrings'][0]) !== false) {
412
- for ($i = 1; $i < sizeof($this->patterns['badstrings']); $i++) {
413
- if (wfUtils::strpos($data, $this->patterns['badstrings'][$i]) !== false) {
414
- $badStringFound = $this->patterns['badstrings'][$i];
415
- break;
416
}
417
}
418
- }
419
- if ($badStringFound) {
420
- $this->addResult(array(
421
- 'type' => 'file',
422
- 'severity' => 1,
423
- 'ignoreP' => $this->path . $file,
424
- 'ignoreC' => $fileSum,
425
- 'shortMsg' => "This file may contain malicious executable code: " . esc_html($this->path . $file),
426
- 'longMsg' => "This file is a PHP executable file and contains the word 'eval' (without quotes) and the word '<span class=\"wf-split-word\">" . esc_html($badStringFound) . "</span>' (without quotes). The eval() function along with an encoding function like the one mentioned are commonly used by hackers to hide their code. If you know about this file you can choose to ignore it to exclude it from future scans. This file was detected because you have enabled HIGH SENSITIVITY scanning. This option is more aggressive than the usual scans, and may cause false positives.",
427
- 'data' => array_merge(array(
428
- 'file' => $file,
429
- 'shac' => $record->SHAC,
430
- ), $dataForFile),
431
));
432
- break;
433
}
434
}
435
436
- if (!$dontScanForURLs) {
437
$this->urlHoover->hoover($file, $data, $hooverExclusions);
438
}
439
@@ -453,74 +468,76 @@ class wordfenceScanner {
453
}
454
}
455
$this->writeScanningStatus();
456
- wordfence::status(2, 'info', "Asking Wordfence to check URLs against malware list.");
457
- $hooverResults = $this->urlHoover->getBaddies();
458
- if($this->urlHoover->errorMsg){
459
- $this->errorMsg = $this->urlHoover->errorMsg;
460
- return false;
461
- }
462
- $this->urlHoover->cleanup();
463
-
464
- foreach($hooverResults as $file => $hresults){
465
- $record = wordfenceMalwareScanFile::fileForPath($file);
466
- $dataForFile = $this->dataForFile($file, $this->path . $file);
467
-
468
- foreach($hresults as $result){
469
- if(preg_match('/wfBrowscapCache\.php#x2F;', $file)){
470
- continue;
471
- }
472
-
473
- if (empty($result['URL'])) {
474
- continue;
475
- }
476
-
477
- if ($result['badList'] == 'goog-malware-shavar') {
478
- $this->addResult(array(
479
- 'type' => 'file',
480
- 'severity' => 1,
481
- 'ignoreP' => $this->path . $file,
482
- 'ignoreC' => md5_file($this->path . $file),
483
- 'shortMsg' => "File contains suspected malware URL: " . esc_html($this->path . $file),
484
- 'longMsg' => "This file contains a suspected malware URL listed on Google's list of malware sites. Wordfence decodes " . esc_html($this->patterns['word3']) . " when scanning files so the URL may not be visible if you view this file. The URL is: " . esc_html($result['URL']) . " - More info available at <a href=\"http://safebrowsing.clients.google.com/safebrowsing/diagnostic?site=" . urlencode($result['URL']) . "&client=googlechrome&hl=en-US\" target=\"_blank\" rel=\"noopener noreferrer\">Google Safe Browsing diagnostic page</a>.",
485
- 'data' => array_merge(array(
486
- 'file' => $file,
487
- 'shac' => $record->SHAC,
488
- 'badURL' => $result['URL'],
489
- 'gsb' => 'goog-malware-shavar'
490
- ), $dataForFile),
491
- ));
492
- }
493
- else if ($result['badList'] == 'googpub-phish-shavar') {
494
- $this->addResult(array(
495
- 'type' => 'file',
496
- 'severity' => 1,
497
- 'ignoreP' => $this->path . $file,
498
- 'ignoreC' => md5_file($this->path . $file),
499
- 'shortMsg' => "File contains suspected phishing URL: " . esc_html($this->path . $file),
500
- 'longMsg' => "This file contains a URL that is a suspected phishing site that is currently listed on Google's list of known phishing sites. The URL is: " . esc_html($result['URL']),
501
- 'data' => array_merge(array(
502
- 'file' => $file,
503
- 'shac' => $record->SHAC,
504
- 'badURL' => $result['URL'],
505
- 'gsb' => 'googpub-phish-shavar'
506
- ), $dataForFile),
507
- ));
508
- }
509
- else if ($result['badList'] == 'wordfence-dbl') {
510
- $this->addResult(array(
511
- 'type' => 'file',
512
- 'severity' => 1,
513
- 'ignoreP' => $this->path . $file,
514
- 'ignoreC' => md5_file($this->path . $file),
515
- 'shortMsg' => "File contains suspected malware URL: " . esc_html($this->path . $file),
516
- 'longMsg' => "This file contains a URL that is currently listed on Wordfence's domain blacklist. The URL is: " . esc_html($result['URL']),
517
- 'data' => array_merge(array(
518
- 'file' => $file,
519
- 'shac' => $record->SHAC,
520
- 'badURL' => $result['URL'],
521
- 'gsb' => 'wordfence-dbl'
522
- ), $dataForFile),
523
- ));
524
}
525
}
526
}
59
$this->results = array();
60
$this->errorMsg = false;
61
//First extract hosts or IP's and their URL's into $this->hostsFound and URL's into $this->urlsFound
62
+ if (wfConfig::get('scansEnabled_fileContentsGSB')) {
63
+ $this->urlHoover = new wordfenceURLHoover($this->apiKey, $this->wordpressVersion);
64
+ }
65
+ else {
66
+ $this->urlHoover = false;
67
+ }
68
+
69
+ if (wfConfig::get('scansEnabled_fileContents')) {
70
+ $this->setupSigs();
71
+ }
72
+ else {
73
+ $this->patterns = array();
74
+ }
75
}
76
77
/**
80
* @throws Exception
81
*/
82
protected function setupSigs() {
83
$sigData = $this->api->call('get_patterns', array(), array());
84
if(! (is_array($sigData) && isset($sigData['rules'])) ){
85
throw new Exception("Wordfence could not get the attack signature patterns from the scanning server.");
202
}
203
204
//The site's own URL is checked in an earlier scan stage so we exclude it here.
205
+ $hooverExclusions = array();
206
+ if (wfConfig::get('scansEnabled_fileContentsGSB')) {
207
+ $hooverExclusions = wordfenceURLHoover::standardExcludedHosts();
208
+ }
209
210
$lastCount = 'whatever';
211
$excludePattern = self::getExcludeFilePattern(self::EXCLUSION_PATTERNS_USER | self::EXCLUSION_PATTERNS_MALWARE);
331
}
332
333
$treatAsBinary = ($isPHP || $isHTML || wfConfig::get('scansEnabled_scanImages'));
334
+ if (wfConfig::get('scansEnabled_fileContents')) {
335
+ if ($treatAsBinary && wfUtils::strpos($data, '$allowed'.'Sites') !== false && wfUtils::strpos($data, "define ('VER"."SION', '1.") !== false && wfUtils::strpos($data, "TimThum"."b script created by") !== false) {
336
+ $this->addResult(array(
337
+ 'type' => 'file',
338
+ 'severity' => 1,
339
+ 'ignoreP' => $this->path . $file,
340
+ 'ignoreC' => $fileSum,
341
+ 'shortMsg' => "File is an old version of TimThumb which is vulnerable.",
342
+ 'longMsg' => "This file appears to be an old version of the TimThumb script which makes your system vulnerable to attackers. Please upgrade the theme or plugin that uses this or remove it." . $extraMsg,
343
+ 'data' => array_merge(array(
344
+ 'file' => $file,
345
+ 'shac' => $record->SHAC,
346
+ ), $dataForFile),
347
+ ));
348
+ break;
349
+ }
350
+ else {
351
+ $allCommonStrings = $this->patterns['commonStrings'];
352
+ $commonStringsFound = array_fill(0, count($allCommonStrings), null); //Lazily looked up below
353
354
+ $regexMatched = false;
355
+ foreach ($this->patterns['rules'] as $rule) {
356
+ $stoppedOnSignature = $record->stoppedOnSignature;
357
+ if (!empty($stoppedOnSignature)) { //Advance until we find the rule we stopped on last time
358
+ //wordfence::status(4, 'info', "Searching for malware scan resume point (". $stoppedOnSignature . ") at rule " . $rule[0]);
359
+ if ($stoppedOnSignature == $rule[0]) {
360
+ $record->updateStoppedOn('', $currentPosition);
361
+ wordfence::status(4, 'info', "Resuming malware scan at rule {$rule[0]}.");
362
+ }
363
+ continue;
364
}
365
366
+ $type = (isset($rule[4]) && !empty($rule[4])) ? $rule[4] : 'server';
367
+ $logOnly = (isset($rule[5]) && !empty($rule[5])) ? $rule[5] : false;
368
+ $commonStringIndexes = (isset($rule[6]) && is_array($rule[6])) ? $rule[6] : array();
369
+ if ($type == 'server' && !$treatAsBinary) { continue; }
370
+ else if (($type == 'both' || $type == 'browser') && $fileExt == 'js') { $extraMsg = ''; }
371
+ else if (($type == 'both' || $type == 'browser') && !$treatAsBinary) { continue; }
372
+
373
+ foreach ($commonStringIndexes as $i) {
374
+ if ($commonStringsFound[$i] === null) {
375
+ $s = $allCommonStrings[$i];
376
+ $commonStringsFound[$i] = (preg_match('/' . $s . '/i', $data) == 1);
377
+ }
378
+
379
+ if (!$commonStringsFound[$i]) {
380
+ //wordfence::status(4, 'info', "Skipping malware signature ({$rule[0]}) due to short circuit.");
381
+ continue 2;
382
+ }
383
}
384
+
385
+ /*if (count($commonStringIndexes) > 0) {
386
+ wordfence::status(4, 'info', "Processing malware signature ({$rule[0]}) because short circuit matched.");
387
+ }*/
388
+
389
+ if (preg_match('/(' . $rule[2] . ')/iS', $data, $matches, PREG_OFFSET_CAPTURE)) {
390
+ $matchString = $matches[1][0];
391
+ $matchOffset = $matches[1][1];
392
+ $beforeString = wfWAFUtils::substr($data, max(0, $matchOffset - 100), $matchOffset - max(0, $matchOffset - 100));
393
+ $afterString = wfWAFUtils::substr($data, $matchOffset + strlen($matchString), 100);
394
+ if (!$logOnly) {
395
+ $this->addResult(array(
396
+ 'type' => 'file',
397
+ 'severity' => 1,
398
+ 'ignoreP' => $this->path . $file,
399
+ 'ignoreC' => $fileSum,
400
+ 'shortMsg' => "File appears to be malicious: " . esc_html($file),
401
+ 'longMsg' => "This file appears to be installed by a hacker to perform malicious activity. If you know about this file you can choose to ignore it to exclude it from future scans. The text we found in this file that matches a known malicious file is: <strong style=\"color: #F00;\" class=\"wf-split-word\">\"" . wfUtils::potentialBinaryStringToHTML((wfUtils::strlen($matchString) > 200 ? wfUtils::substr($matchString, 0, 200) . '...' : $matchString)) . "\"</strong>. The infection type is: <strong>" . esc_html($rule[3]) . '</strong>.' . $extraMsg,
402
+ 'data' => array_merge(array(
403
+ 'file' => $file,
404
+ 'shac' => $record->SHAC,
405
+ ), $dataForFile),
406
+ ));
407
+ }
408
+ $regexMatched = true;
409
+ $this->scanEngine->recordMetric('malwareSignature', $rule[0], array('file' => $file, 'match' => $matchString, 'before' => $beforeString, 'after' => $afterString), false);
410
+ break;
411
}
412
413
+ if ($forkObj->shouldFork()) {
414
+ $record->updateStoppedOn($rule[0], $currentPosition);
415
+ fclose($fh);
416
+
417
+ wordfence::status(4, 'info', "Forking during malware scan ({$rule[0]}) to ensure continuity.");
418
+ $forkObj->fork(); //exits
419
+ }
420
}
421
+ if ($regexMatched) { break; }
422
}
423
+ if ($treatAsBinary && wfConfig::get('scansEnabled_highSense')) {
424
+ $badStringFound = false;
425
+ if (strpos($data, $this->patterns['badstrings'][0]) !== false) {
426
+ for ($i = 1; $i < sizeof($this->patterns['badstrings']); $i++) {
427
+ if (wfUtils::strpos($data, $this->patterns['badstrings'][$i]) !== false) {
428
+ $badStringFound = $this->patterns['badstrings'][$i];
429
+ break;
430
+ }
431
}
432
}
433
+ if ($badStringFound) {
434
+ $this->addResult(array(
435
+ 'type' => 'file',
436
+ 'severity' => 1,
437
+ 'ignoreP' => $this->path . $file,
438
+ 'ignoreC' => $fileSum,
439
+ 'shortMsg' => "This file may contain malicious executable code: " . esc_html($this->path . $file),
440
+ 'longMsg' => "This file is a PHP executable file and contains the word 'eval' (without quotes) and the word '<span class=\"wf-split-word\">" . esc_html($badStringFound) . "</span>' (without quotes). The eval() function along with an encoding function like the one mentioned are commonly used by hackers to hide their code. If you know about this file you can choose to ignore it to exclude it from future scans. This file was detected because you have enabled HIGH SENSITIVITY scanning. This option is more aggressive than the usual scans, and may cause false positives.",
441
+ 'data' => array_merge(array(
442
+ 'file' => $file,
443
+ 'shac' => $record->SHAC,
444
+ ), $dataForFile),
445
));
446
+ break;
447
+ }
448
}
449
}
450
451
+ if (!$dontScanForURLs && wfConfig::get('scansEnabled_fileContentsGSB')) {
452
$this->urlHoover->hoover($file, $data, $hooverExclusions);
453
}
454
468
}
469
}
470
$this->writeScanningStatus();
471
+ if (wfConfig::get('scansEnabled_fileContentsGSB')) {
472
+ wordfence::status(2, 'info', "Asking Wordfence to check URLs against malware list.");
473
+ $hooverResults = $this->urlHoover->getBaddies();
474
+ if($this->urlHoover->errorMsg){
475
+ $this->errorMsg = $this->urlHoover->errorMsg;
476
+ return false;
477
+ }
478
+ $this->urlHoover->cleanup();
479
+
480
+ foreach($hooverResults as $file => $hresults){
481
+ $record = wordfenceMalwareScanFile::fileForPath($file);
482
+ $dataForFile = $this->dataForFile($file, $this->path . $file);
483
+
484
+ foreach($hresults as $result){
485
+ if(preg_match('/wfBrowscapCache\.php#x2F;', $file)){
486
+ continue;
487
+ }
488
+
489
+ if (empty($result['URL'])) {
490
+ continue;
491
+ }
492
+
493
+ if ($result['badList'] == 'goog-malware-shavar') {
494
+ $this->addResult(array(
495
+ 'type' => 'file',
496
+ 'severity' => 1,
497
+ 'ignoreP' => $this->path . $file,
498
+ 'ignoreC' => md5_file($this->path . $file),
499
+ 'shortMsg' => "File contains suspected malware URL: " . esc_html($this->path . $file),
500
+ 'longMsg' => "This file contains a suspected malware URL listed on Google's list of malware sites. Wordfence decodes " . esc_html($this->patterns['word3']) . " when scanning files so the URL may not be visible if you view this file. The URL is: " . esc_html($result['URL']) . " - More info available at <a href=\"http://safebrowsing.clients.google.com/safebrowsing/diagnostic?site=" . urlencode($result['URL']) . "&client=googlechrome&hl=en-US\" target=\"_blank\" rel=\"noopener noreferrer\">Google Safe Browsing diagnostic page</a>.",
501
+ 'data' => array_merge(array(
502
+ 'file' => $file,
503
+ 'shac' => $record->SHAC,
504
+ 'badURL' => $result['URL'],
505
+ 'gsb' => 'goog-malware-shavar'
506
+ ), $dataForFile),
507
+ ));
508
+ }
509
+ else if ($result['badList'] == 'googpub-phish-shavar') {
510
+ $this->addResult(array(
511
+ 'type' => 'file',
512
+ 'severity' => 1,
513
+ 'ignoreP' => $this->path . $file,
514
+ 'ignoreC' => md5_file($this->path . $file),
515
+ 'shortMsg' => "File contains suspected phishing URL: " . esc_html($this->path . $file),
516
+ 'longMsg' => "This file contains a URL that is a suspected phishing site that is currently listed on Google's list of known phishing sites. The URL is: " . esc_html($result['URL']),
517
+ 'data' => array_merge(array(
518
+ 'file' => $file,
519
+ 'shac' => $record->SHAC,
520
+ 'badURL' => $result['URL'],
521
+ 'gsb' => 'googpub-phish-shavar'
522
+ ), $dataForFile),
523
+ ));
524
+ }
525
+ else if ($result['badList'] == 'wordfence-dbl') {
526
+ $this->addResult(array(
527
+ 'type' => 'file',
528
+ 'severity' => 1,
529
+ 'ignoreP' => $this->path . $file,
530
+ 'ignoreC' => md5_file($this->path . $file),
531
+ 'shortMsg' => "File contains suspected malware URL: " . esc_html($this->path . $file),
532
+ 'longMsg' => "This file contains a URL that is currently listed on Wordfence's domain blacklist. The URL is: " . esc_html($result['URL']),
533
+ 'data' => array_merge(array(
534
+ 'file' => $file,
535
+ 'shac' => $record->SHAC,
536
+ 'badURL' => $result['URL'],
537
+ 'gsb' => 'wordfence-dbl'
538
+ ), $dataForFile),
539
+ ));
540
+ }
541
}
542
}
543
}
readme.txt CHANGED
@@ -2,8 +2,8 @@
2
Contributors: mmaunder
3
Tags: security, secure, security plugin, wordpress security, login security, firewall, malware, antivirus, web application firewall, block hackers, country blocking
4
Requires at least: 3.9
5
- Tested up to: 4.8.0
6
- Stable tag: 6.3.14
7
8
Secure your website with the most comprehensive WordPress security plugin. Firewall, malware scan, blocking, live traffic, login security & more.
9
@@ -160,6 +160,13 @@ Secure your website with Wordfence.
160
161
== Changelog ==
162
163
= 6.3.14 =
164
* Improvement: Introduced smart scan distribution. Scan times are now distributed intelligently across servers to provide consistent server performance.
165
* Improvement: Introduced light-weight scan that runs frequently to perform checks that do not use any server resources.
2
Contributors: mmaunder
3
Tags: security, secure, security plugin, wordpress security, login security, firewall, malware, antivirus, web application firewall, block hackers, country blocking
4
Requires at least: 3.9
5
+ Tested up to: 4.8.1
6
+ Stable tag: 6.3.15
7
8
Secure your website with the most comprehensive WordPress security plugin. Firewall, malware scan, blocking, live traffic, login security & more.
9
160
161
== Changelog ==
162
163
+ = 6.3.15 =
164
+ * Improvement: Reduced memory usage on scan forking and during the known files scan stage.
165
+ * Improvement: Added additional scan options to allow for disabling the blacklist checks while still allowing malware scanning to be enabled.
166
+ * Improvement: Added a Wordfence Application Firewall code block for the lsapi variant of LiteSpeed.
167
+ * Improvement: Updated the bundled GeoIP database.
168
+ * Fix: Added a validation check to IP range whitelisting to avoid log warnings if they're malformed.
169
+
170
= 6.3.14 =
171
* Improvement: Introduced smart scan distribution. Scan times are now distributed intelligently across servers to provide consistent server performance.
172
* Improvement: Introduced light-weight scan that runs frequently to perform checks that do not use any server resources.
waf/wfWAFUserIPRange.php CHANGED
@@ -41,6 +41,10 @@ class wfWAFUserIPRange {
41
$IPparts = explode('.', $ip);
42
$whiteParts = explode('.', $ip_string);
43
$mismatch = false;
44
for ($i = 0; $i <= 3; $i++) {
45
if (preg_match('/^\[(\d+)\-(\d+)\]#x2F;', $whiteParts[$i], $m)) {
46
if ($IPparts[$i] < $m[1] || $IPparts[$i] > $m[2]) {
@@ -65,6 +69,10 @@ class wfWAFUserIPRange {
65
$IPparts = explode(':', $ip);
66
$whiteParts = explode(':', $ip_string);
67
$mismatch = false;
68
for ($i = 0; $i <= 7; $i++) {
69
if (preg_match('/^\[([a-f0-9]+)\-([a-f0-9]+)\]#x2F;i', $whiteParts[$i], $m)) {
70
$ip_group = hexdec($IPparts[$i]);
41
$IPparts = explode('.', $ip);
42
$whiteParts = explode('.', $ip_string);
43
$mismatch = false;
44
+ if (count($whiteParts) != 4 || count($IPparts) != 4) {
45
+ return false;
46
+ }
47
+
48
for ($i = 0; $i <= 3; $i++) {
49
if (preg_match('/^\[(\d+)\-(\d+)\]#x2F;', $whiteParts[$i], $m)) {
50
if ($IPparts[$i] < $m[1] || $IPparts[$i] > $m[2]) {
69
$IPparts = explode(':', $ip);
70
$whiteParts = explode(':', $ip_string);
71
$mismatch = false;
72
+ if (count($whiteParts) != 8 || count($IPparts) != 8) {
73
+ return false;
74
+ }
75
+
76
for ($i = 0; $i <= 7; $i++) {
77
if (preg_match('/^\[([a-f0-9]+)\-([a-f0-9]+)\]#x2F;i', $whiteParts[$i], $m)) {
78
$ip_group = hexdec($IPparts[$i]);
wordfence.php CHANGED
@@ -4,14 +4,14 @@ Plugin Name: Wordfence Security
4
Plugin URI: http://www.wordfence.com/
5
Description: Wordfence Security - Anti-virus, Firewall and Malware Scan
6
Author: Wordfence
7
- Version: 6.3.14
8
Author URI: http://www.wordfence.com/
9
Network: true
10
*/
11
if(defined('WP_INSTALLING') && WP_INSTALLING){
12
return;
13
}
14
- define('WORDFENCE_VERSION', '6.3.14');
15
define('WORDFENCE_BASENAME', function_exists('plugin_basename') ? plugin_basename(__FILE__) :
16
basename(dirname(__FILE__)) . '/' . basename(__FILE__));
17
4
Plugin URI: http://www.wordfence.com/
5
Description: Wordfence Security - Anti-virus, Firewall and Malware Scan
6
Author: Wordfence
7
+ Version: 6.3.15
8
Author URI: http://www.wordfence.com/
9
Network: true
10
*/
11
if(defined('WP_INSTALLING') && WP_INSTALLING){
12
return;
13
}
14
+ define('WORDFENCE_VERSION', '6.3.15');
15
define('WORDFENCE_BASENAME', function_exists('plugin_basename') ? plugin_basename(__FILE__) :
16
basename(dirname(__FILE__)) . '/' . basename(__FILE__));
17