Wordfence Security – Firewall & Malware Scan - Version 6.2.8

Version Description

  • Improvement: Added support for hiding the username information revealed by the WordPress 4.7 REST API. Thanks Vladimir Smitka.
  • Improvement: Added vulnerability scanning for themes.
  • Improvement: Reduced memory usage by up to 90% when scanning comments.
  • Improvement: Performance improvements for the dashboard widget.
  • Improvement: Added progressive loading of addresses on the blocked IP list.
  • Improvement: The diagnostics page now displays a config reading/writing test.
  • Change: Support for the Falcon cache has been removed.
  • Fix: Better messaging when the WAF rules are manually updated.
  • Fix: The proxy detection check frequency has been reduced and no longer alerts if the server is unreachable.
  • Fix: Adjusted the behavior of parsing the X-Forwarded-For header for better accuracy. Thanks Jason Woods.
  • Fix: Typo fix on the options page.
  • Fix: Scan issue for known core file now shows the correct links.
  • Fix: Links in "unlock" emails now work for IPv6 and IPv4-mapped-IPv6 addresses.
  • Fix: Restricted caching of responses from the Wordfence Security Network.
  • Fix: Fixed a recording issue with Wordfence Security Network statistics.
Download this release

Release Info

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

Code changes from version 6.2.7 to 6.2.8

css/main.css CHANGED
@@ -537,48 +537,6 @@ h3.wfConfigHeading {
537
padding: 10px;
538
margin: 20px;
539
}
540
- .wfFalconNotice {
541
- width: 500px;
542
- background-color: #FFD7CE;
543
- border: 1px solid #000;
544
- padding: 10px;
545
- margin: 20px;
546
- }
547
- .wfFalcon {
548
- width: 63px;
549
- height: 63px;
550
- border-width: 0;
551
- background-color: transparent;
552
- background-image: url(../images/wordfenceFalcon.png);
553
- background-position: 0 0;
554
- background-repeat: no-repeat;
555
- position: absolute;
556
- right: 2px;
557
- top: 3px;
558
- }
559
- .wfFalconImage {
560
- width: 63px;
561
- height: 63px;
562
- border-width: 0;
563
- background-color: transparent;
564
- background-image: url(../images/wordfenceFalcon.png);
565
- background-position: 0 0;
566
- background-repeat: no-repeat;
567
- margin: 5px auto 15px auto;
568
- }
569
- .wfSmallFalcon {
570
- width: 33px;
571
- height: 16px;
572
- border-width: 0;
573
- background-color: transparent;
574
- background-image: url(../images/wordfenceFalconSmall.png);
575
- background-position: 0 0;
576
- background-repeat: no-repeat;
577
- margin: 0;
578
- padding: 0;
579
- display: inline;
580
- float: right;
581
- }
582
583
584
@@ -1241,4 +1199,9 @@ tr.wf-table-filters input {
1241
1242
.wf-hex-sequence {
1243
color: #587ECB;
1244
}
537
padding: 10px;
538
margin: 20px;
539
}
540
541
542
1199
1200
.wf-hex-sequence {
1201
color: #587ECB;
1202
+ }
1203
+
1204
+ .wfLoadMoreButton.disabled, .wfLoadMoreButton[disabled] {
1205
+ pointer-events: none;
1206
+ opacity: 0.65;
1207
}
images/wordfenceFalcon.png DELETED
Binary file
images/wordfenceFalconEngineSmall.png DELETED
Binary file
images/wordfenceFalconSmall.png DELETED
Binary file
js/admin.js CHANGED
@@ -42,6 +42,7 @@
42
serverTimestampOffset: 0,
43
serverMicrotime: 0,
44
wfLiveTraffic: null,
45
46
init: function() {
47
this.nonce = WordfenceAdminVars.firstNonce;
@@ -159,14 +160,9 @@
159
this.setupSwitches('wfLiveTrafficOnOff', 'liveTrafficEnabled', function() {
160
});
161
jQuery('#wfLiveTrafficOnOff').change(function() {
162
- if (/^(?:falcon|php)#x2F;.test(WordfenceAdminVars.cacheType)) {
163
- jQuery('#wfLiveTrafficOnOff').attr('checked', false);
164
- self.colorbox('400px', "Live Traffic not available in high performance mode", "Please note that you can't enable live traffic when Falcon Engine or basic caching is enabled. This is done for performance reasons. If you want live traffic, go to the 'Performance Setup' menu and disable caching.");
165
- } else {
166
- self.updateSwitch('wfLiveTrafficOnOff', 'liveTrafficEnabled', function() {
167
- window.location.reload(true);
168
- });
169
- }
170
});
171
172
if (WordfenceAdminVars.liveTrafficEnabled) {
@@ -210,6 +206,25 @@
210
self.tourRedir('WordfencePasswdAudit');
211
});
212
}
213
} else if (jQuery('#wordfenceMode_passwd').length > 0) {
214
this.mode = 'passwd';
215
startTicker = false;
@@ -267,15 +282,6 @@
267
self.tourRedir('WordfenceWhois');
268
});
269
}
270
- } else if (jQuery('#wordfenceMode_caching').length > 0) {
271
- this.mode = 'caching';
272
- startTicker = false;
273
- if (this.needTour()) {
274
- this.tour('wfWelcomeContentCaching', 'wfHeading', 'top', 'left', "Learn about IP Blocking", function() {
275
- self.tourRedir('WordfenceBlockedIPs');
276
- });
277
- }
278
- this.loadCacheExclusions();
279
} else {
280
this.mode = false;
281
}
@@ -1172,7 +1178,7 @@
1172
var title = "Full Path Disclosure";
1173
issueID = parseInt(issueID);
1174
1175
- this.ajax('wordfence_checkFalconHtaccess', {}, function(res) {
1176
if (res.ok) {
1177
self.colorbox("400px", title, 'We are about to change your <em>.htaccess</em> file. Please make a backup of this file proceeding'
1178
+ '<br/>'
@@ -1246,7 +1252,7 @@
1246
var nginx = "You will need to manually delete those files";
1247
issueID = parseInt(issueID, 10);
1248
1249
- this.ajax('wordfence_checkFalconHtaccess', {}, this._handleHtAccess(issueID, '_hideFile', title, nginx));
1250
},
1251
1252
restoreFile: function(issueID) {
@@ -1279,7 +1285,7 @@
1279
var title = "Disable Directory Listing";
1280
issueID = parseInt(issueID);
1281
1282
- this.ajax('wordfence_checkFalconHtaccess', {}, function(res) {
1283
if (res.ok) {
1284
self.colorbox("400px", title, 'We are about to change your <em>.htaccess</em> file. Please make a backup of this file proceeding'
1285
+ '<br/>'
@@ -1458,38 +1464,76 @@
1458
}
1459
this.activityMode = mode;
1460
1461
var self = this;
1462
- this.ajax('wordfence_loadStaticPanel', {
1463
- mode: this.activityMode
1464
}, function(res) {
1465
self.completeLoadStaticPanel(res);
1466
});
1467
},
1468
completeLoadStaticPanel: function(res) {
1469
var contentElem = '#wfActivity_' + this.activityMode;
1470
- jQuery(contentElem).empty();
1471
- if (res.results && res.results.length > 0) {
1472
var tmpl;
1473
if (this.activityMode == 'topScanners' || this.activityMode == 'topLeechers') {
1474
tmpl = '#wfLeechersTmpl';
1475
} else if (this.activityMode == 'blockedIPs') {
1476
tmpl = '#wfBlockedIPsTmpl';
1477
} else if (this.activityMode == 'lockedOutIPs') {
1478
tmpl = '#wfLockedOutIPsTmpl';
1479
} else if (this.activityMode == 'throttledIPs') {
1480
tmpl = '#wfThrottledIPsTmpl';
1481
} else {
1482
return;
1483
}
1484
- var i, j, chunk = 1000;
1485
- var bigArray = res.results.slice(0);
1486
- res.results = false;
1487
- for (i = 0, j = bigArray.length; i < j; i += chunk) {
1488
- res.results = bigArray.slice(i, i + chunk);
1489
- jQuery(tmpl).tmpl(res).appendTo(contentElem);
1490
}
1491
this.reverseLookupIPs();
1492
- } else {
1493
if (this.activityMode == 'topScanners' || this.activityMode == 'topLeechers') {
1494
jQuery(contentElem).html("No site hits have been logged yet. Check back soon.");
1495
} else if (this.activityMode == 'blockedIPs') {
@@ -1916,76 +1960,6 @@
1916
}, 2000);
1917
});
1918
},
1919
- getCacheStats: function() {
1920
- var self = this;
1921
- this.ajax('wordfence_getCacheStats', {}, function(res) {
1922
- if (res.ok) {
1923
- self.colorbox('400px', res.heading, res.body);
1924
- }
1925
- });
1926
- },
1927
- clearPageCache: function() {
1928
- var self = this;
1929
- this.ajax('wordfence_clearPageCache', {}, function(res) {
1930
- if (res.ok) {
1931
- self.colorbox('400px', res.heading, res.body);
1932
- }
1933
- });
1934
- },
1935
- switchToFalcon: function() {
1936
- var self = this;
1937
- this.ajax('wordfence_checkFalconHtaccess', {}, function(res) {
1938
- if (res.ok) {
1939
- 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);" />');
1940
- } else if (res.nginx) {
1941
- self.colorbox('400px', "Enabling Falcon Engine", 'You are using an Nginx web server and using a FastCGI processor like PHP5-FPM. To use Falcon you will need to manually modify your nginx.conf configuration file and reload your Nginx server for the changes to take effect. You can find the <a href="http://www.wordfence.com/blog/2014/05/nginx-wordfence-falcon-engine-php-fpm-fastcgi-fast-cgi/" target="_blank">rules you need to make these changes to nginx.conf on this page on wordfence.com</a>. Once you have made these changes, compressed cached files will be served to your visitors directly from Nginx making your site extremely fast. When you have made the changes and reloaded your Nginx server, you can click the button below to enable Falcon.<br /><br /><input type="button" name="but1" id="wfNextBut" value="Click to Enable Falcon Engine" onclick="WFAD.confirmSwitchToFalcon(1);" />');
1942
- } else if (res.err) {
1943
- 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);' />");
1944
- }
1945
- });
1946
- },
1947
- confirmSwitchToFalcon: function(noEditHtaccess) {
1948
- jQuery.colorbox.close();
1949
- var cacheType = 'falcon';
1950
- var self = this;
1951
- this.ajax('wordfence_saveCacheConfig', {
1952
- cacheType: cacheType,
1953
- noEditHtaccess: noEditHtaccess
1954
- }, function(res) {
1955
- if (res.ok) {
1956
- self.colorbox('400px', res.heading, res.body);
1957
- }
1958
- }
1959
- );
1960
- },
1961
- saveCacheConfig: function() {
1962
- var cacheType = jQuery('input:radio[name=cacheType]:checked').val();
1963
- if (cacheType == 'falcon') {
1964
- return this.switchToFalcon();
1965
- }
1966
- var self = this;
1967
- this.ajax('wordfence_saveCacheConfig', {
1968
- cacheType: cacheType
1969
- }, function(res) {
1970
- if (res.ok) {
1971
- self.colorbox('400px', res.heading, res.body);
1972
- }
1973
- }
1974
- );
1975
- },
1976
- saveCacheOptions: function() {
1977
- var self = this;
1978
- this.ajax('wordfence_saveCacheOptions', {
1979
- allowHTTPSCaching: (jQuery('#wfallowHTTPSCaching').is(':checked') ? 1 : 0),
1980
- addCacheComment: (jQuery('#wfaddCacheComment').is(':checked') ? 1 : 0),
1981
- clearCacheSched: (jQuery('#wfclearCacheSched').is(':checked') ? 1 : 0)
1982
- }, function(res) {
1983
- if (res.updateErr) {
1984
- 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>');
1985
- }
1986
- }
1987
- );
1988
- },
1989
saveConfig: function() {
1990
var qstr = jQuery('#wfConfigForm').serialize();
1991
var self = this;
@@ -2470,40 +2444,6 @@
2470
}
2471
},
2472
2473
- removeCacheExclusion: function(id) {
2474
- this.ajax('wordfence_removeCacheExclusion', {id: id}, function(res) {
2475
- window.location.reload(true);
2476
- });
2477
- },
2478
- addCacheExclusion: function(patternType, pattern) {
2479
- if (/^https?:\/\//.test(pattern)) {
2480
- this.colorbox('400px', "Incorrect pattern for exclusion", "You can not enter full URL's for exclusion from caching. You entered a full URL that started with http:// or https://. You must enter relative URL's e.g. /exclude/this/page/. You can also enter text that might be contained in the path part of a URL or at the end of the path part of a URL.");
2481
- return;
2482
- }
2483
-
2484
- this.ajax('wordfence_addCacheExclusion', {
2485
- patternType: patternType,
2486
- pattern: pattern
2487
- }, function(res) {
2488
- if (res.ok) { //Otherwise errorMsg will get caught
2489
- window.location.reload(true);
2490
- }
2491
- });
2492
- },
2493
- loadCacheExclusions: function() {
2494
- this.ajax('wordfence_loadCacheExclusions', {}, function(res) {
2495
- if (res.ex instanceof Array && res.ex.length > 0) {
2496
- for (var i = 0; i < res.ex.length; i++) {
2497
- var newElem = jQuery('#wfCacheExclusionTmpl').tmpl(res.ex[i]);
2498
- newElem.prependTo('#wfCacheExclusions').fadeIn();
2499
- }
2500
- jQuery('<h2>Cache Exclusions</h2>').prependTo('#wfCacheExclusions');
2501
- } else {
2502
- jQuery('<h2>Cache Exclusions</h2><p style="width: 500px;">There are not currently any exclusions. If you have a site that does not change often, it is perfectly normal to not have any pages you want to exclude from the cache.</p>').prependTo('#wfCacheExclusions');
2503
- }
2504
-
2505
- });
2506
- },
2507
exportSettings: function() {
2508
var self = this;
2509
this.ajax('wordfence_exportSettings', {}, function(res) {
@@ -2748,14 +2688,19 @@
2748
this.ajax('wordfence_updateWAFRules', {}, function(res) {
2749
self.wafData = res;
2750
self.wafConfigPageRender();
2751
- if (!self.wafData['isPaid']) {
2752
- self.colorbox('400px', 'Rules Updated', 'Your rules have been updated successfully. You are ' +
2753
- 'currently using the the free version of Wordfence. ' +
2754
- 'Upgrade to Wordfence premium to have your rules updated automatically as new threats emerge. ' +
2755
- '<a href="https://www.wordfence.com/wafUpdateRules1/wordfence-signup/">Click here to purchase a premium API key</a>. ' +
2756
- '<em>Note: Your rules will still update every 30 days as a free user.</em>');
2757
- } else {
2758
- self.colorbox('400px', 'Rules Updated', 'Your rules have been updated successfully.');
2759
}
2760
if (typeof onSuccess === 'function') {
2761
return onSuccess.apply(this, arguments);
42
serverTimestampOffset: 0,
43
serverMicrotime: 0,
44
wfLiveTraffic: null,
45
+ loadingBlockedIPs: false,
46
47
init: function() {
48
this.nonce = WordfenceAdminVars.firstNonce;
160
this.setupSwitches('wfLiveTrafficOnOff', 'liveTrafficEnabled', function() {
161
});
162
jQuery('#wfLiveTrafficOnOff').change(function() {
163
+ self.updateSwitch('wfLiveTrafficOnOff', 'liveTrafficEnabled', function() {
164
+ window.location.reload(true);
165
+ });
166
});
167
168
if (WordfenceAdminVars.liveTrafficEnabled) {
206
self.tourRedir('WordfencePasswdAudit');
207
});
208
}
209
+
210
+ var self = this;
211
+ var hasScrolled = false;
212
+ $(window).on('scroll', function() {
213
+ var win = $(this);
214
+ var wrapper = $('#wfActivity_' + self.activityMode);
215
+ // console.log(win.scrollTop() + window.innerHeight, liveTrafficWrapper.outerHeight() + liveTrafficWrapper.offset().top);
216
+ var currentScrollBottom = win.scrollTop() + window.innerHeight;
217
+ var scrollThreshold = wrapper.outerHeight() + wrapper.offset().top;
218
+ if (hasScrolled && !self.loadingBlockedIPs && currentScrollBottom >= scrollThreshold) {
219
+ // console.log('infinite scroll');
220
+ hasScrolled = false;
221
+
222
+ self.loadStaticPanelContent(true);
223
+ } else if (currentScrollBottom < scrollThreshold) {
224
+ hasScrolled = true;
225
+ // console.log('no infinite scroll');
226
+ }
227
+ });
228
} else if (jQuery('#wordfenceMode_passwd').length > 0) {
229
this.mode = 'passwd';
230
startTicker = false;
282
self.tourRedir('WordfenceWhois');
283
});
284
}
285
} else {
286
this.mode = false;
287
}
1178
var title = "Full Path Disclosure";
1179
issueID = parseInt(issueID);
1180
1181
+ this.ajax('wordfence_checkHtaccess', {}, function(res) {
1182
if (res.ok) {
1183
self.colorbox("400px", title, 'We are about to change your <em>.htaccess</em> file. Please make a backup of this file proceeding'
1184
+ '<br/>'
1252
var nginx = "You will need to manually delete those files";
1253
issueID = parseInt(issueID, 10);
1254
1255
+ this.ajax('wordfence_checkHtaccess', {}, this._handleHtAccess(issueID, '_hideFile', title, nginx));
1256
},
1257
1258
restoreFile: function(issueID) {
1285
var title = "Disable Directory Listing";
1286
issueID = parseInt(issueID);
1287
1288
+ this.ajax('wordfence_checkHtaccess', {}, function(res) {
1289
if (res.ok) {
1290
self.colorbox("400px", title, 'We are about to change your <em>.htaccess</em> file. Please make a backup of this file proceeding'
1291
+ '<br/>'
1464
}
1465
this.activityMode = mode;
1466
1467
+ this.loadStaticPanelContent(false);
1468
+ },
1469
+ loadStaticPanelContent: function(append) {
1470
+ append = !!append;
1471
var self = this;
1472
+ var offset = append ? $('tr.' + self.activityMode + 'Record').length : 0;
1473
+ self.loadingBlockedIPs = true;
1474
+ $('.wfLoadMoreButton').attr("disabled", "disabled");
1475
+ self.ajax('wordfence_loadStaticPanel', {
1476
+ mode: self.activityMode,
1477
+ offset: offset
1478
}, function(res) {
1479
self.completeLoadStaticPanel(res);
1480
+ self.loadingBlockedIPs = false;
1481
});
1482
},
1483
completeLoadStaticPanel: function(res) {
1484
var contentElem = '#wfActivity_' + this.activityMode;
1485
+ if (!res.continuation) {
1486
+ jQuery(contentElem).empty();
1487
+ }
1488
+
1489
+ if (res.hasMore) {
1490
+ $('.wfLoadMoreButton').removeAttr("disabled");
1491
+ }
1492
+
1493
+ if ((res.results && res.results.length > 0) || res.continuation) {
1494
+ if (!(res.results && res.results.length > 0)) {
1495
+ return;
1496
+ }
1497
+
1498
var tmpl;
1499
+ var wrapperTmpl;
1500
+ var wrapperID;
1501
if (this.activityMode == 'topScanners' || this.activityMode == 'topLeechers') {
1502
tmpl = '#wfLeechersTmpl';
1503
+ wrapperTmpl = '#wfLeechersWrapperTmpl';
1504
+ wrapperID = '#wfLeechersWrapper';
1505
} else if (this.activityMode == 'blockedIPs') {
1506
tmpl = '#wfBlockedIPsTmpl';
1507
+ wrapperTmpl = '#wfBlockedIPsWrapperTmpl';
1508
+ wrapperID = '#wfBlockedIPsWrapper';
1509
} else if (this.activityMode == 'lockedOutIPs') {
1510
tmpl = '#wfLockedOutIPsTmpl';
1511
+ wrapperTmpl = '#wfLockedOutIPsWrapperTmpl';
1512
+ wrapperID = '#wfLockedOutIPsWrapper';
1513
} else if (this.activityMode == 'throttledIPs') {
1514
tmpl = '#wfThrottledIPsTmpl';
1515
+ wrapperTmpl = '#wfThrottledIPsWrapperTmpl';
1516
+ wrapperID = '#wfThrottledIPsWrapper';
1517
} else {
1518
return;
1519
}
1520
+
1521
+ if (!res.continuation) {
1522
+ jQuery(wrapperTmpl).tmpl(res).appendTo(contentElem);
1523
+
1524
+ var self = this;
1525
+ $('.wfLoadMoreButton').on('click', function(event) {
1526
+ event.stopPropagation();
1527
+ event.preventDefault();
1528
+ self.loadStaticPanelContent(true);
1529
+ });
1530
}
1531
+
1532
+ jQuery(tmpl).tmpl(res).appendTo(jQuery(wrapperID));
1533
this.reverseLookupIPs();
1534
+ }
1535
+ else {
1536
+ $('.wfLoadMoreButton').hide();
1537
if (this.activityMode == 'topScanners' || this.activityMode == 'topLeechers') {
1538
jQuery(contentElem).html("No site hits have been logged yet. Check back soon.");
1539
} else if (this.activityMode == 'blockedIPs') {
1960
}, 2000);
1961
});
1962
},
1963
saveConfig: function() {
1964
var qstr = jQuery('#wfConfigForm').serialize();
1965
var self = this;
2444
}
2445
},
2446
2447
exportSettings: function() {
2448
var self = this;
2449
this.ajax('wordfence_exportSettings', {}, function(res) {
2688
this.ajax('wordfence_updateWAFRules', {}, function(res) {
2689
self.wafData = res;
2690
self.wafConfigPageRender();
2691
+ if (self.wafData['updated']) {
2692
+ if (!self.wafData['isPaid']) {
2693
+ self.colorbox('400px', 'Rules Updated', 'Your rules have been updated successfully. You are ' +
2694
+ 'currently using the the free version of Wordfence. ' +
2695
+ 'Upgrade to Wordfence premium to have your rules updated automatically as new threats emerge. ' +
2696
+ '<a href="https://www.wordfence.com/wafUpdateRules1/wordfence-signup/">Click here to purchase a premium API key</a>. ' +
2697
+ '<em>Note: Your rules will still update every 30 days as a free user.</em>');
2698
+ } else {
2699
+ self.colorbox('400px', 'Rules Updated', 'Your rules have been updated successfully.');
2700
+ }
2701
+ }
2702
+ else {
2703
+ self.colorbox('400px', 'Rule Update Failed', 'No rules were updated. Please verify you have permissions to write to the /wp-content/wflogs directory.');
2704
}
2705
if (typeof onSuccess === 'function') {
2706
return onSuccess.apply(this, arguments);
js/tourTip.js CHANGED
@@ -41,14 +41,6 @@ window['wordfenceExt'] = {
41
function(){ jQuery('#wordfenceSuPHPUpdateWarning').fadeOut(); }
42
);
43
},
44
- falconDeprecationChoice: function(choice) {
45
- this.ajax('wordfence_falconDeprecationChoice', {
46
- choice: choice
47
- },
48
- function(res){ jQuery('#wordfenceFalconDeprecationWarning').fadeOut(); },
49
- function(){ jQuery('#wordfenceFalconDeprecationWarning').fadeOut(); }
50
- );
51
- },
52
misconfiguredHowGetIPsChoice : function(choice) {
53
this.ajax('wordfence_misconfiguredHowGetIPsChoice', {
54
choice: choice
@@ -57,14 +49,6 @@ window['wordfenceExt'] = {
57
function(){ jQuery('#wordfenceMisconfiguredHowGetIPsNotice').fadeOut(); }
58
);
59
},
60
- removeFromCache: function(postID){
61
- this.ajax('wordfence_removeFromCache', {
62
- id: postID
63
- },
64
- function(res){ if(res.ok){ alert("Item removed from the Wordfence cache."); } },
65
- function(){}
66
- );
67
- },
68
ajax: function(action, data, cb, cbErr, noLoading){
69
if(typeof(data) == 'string'){
70
if(data.length > 0){
41
function(){ jQuery('#wordfenceSuPHPUpdateWarning').fadeOut(); }
42
);
43
},
44
misconfiguredHowGetIPsChoice : function(choice) {
45
this.ajax('wordfence_misconfiguredHowGetIPsChoice', {
46
choice: choice
49
function(){ jQuery('#wordfenceMisconfiguredHowGetIPsNotice').fadeOut(); }
50
);
51
},
52
ajax: function(action, data, cb, cbErr, noLoading){
53
if(typeof(data) == 'string'){
54
if(data.length > 0){
lib/email_newIssues.php CHANGED
@@ -24,6 +24,8 @@
24
<p>* <?php echo htmlspecialchars($i['shortMsg']) ?></p>
25
<?php if (isset($i['tmplData']['wpURL'])): ?>
26
<p><?php if ($i['tmplData']['vulnerabilityPatched']) { ?><strong>Update includes security-related fixes.</strong> <?php } echo $i['tmplData']['wpURL']; ?>/changelog</p>
27
<?php endif ?>
28
<?php if (!empty($i['tmplData']['badURL'])): ?>
29
<p><img src="<?php echo WORDFENCE_API_URL_BASE_NONSEC . "?" . http_build_query(array(
24
<p>* <?php echo htmlspecialchars($i['shortMsg']) ?></p>
25
<?php if (isset($i['tmplData']['wpURL'])): ?>
26
<p><?php if ($i['tmplData']['vulnerabilityPatched']) { ?><strong>Update includes security-related fixes.</strong> <?php } echo $i['tmplData']['wpURL']; ?>/changelog</p>
27
+ <?php elseif (isset($i['tmplData']['vulnerabilityPatched']) && $i['tmplData']['vulnerabilityPatched']): ?>
28
+ <p><strong>Update includes security-related fixes.</strong></p>
29
<?php endif ?>
30
<?php if (!empty($i['tmplData']['badURL'])): ?>
31
<p><img src="<?php echo WORDFENCE_API_URL_BASE_NONSEC . "?" . http_build_query(array(
lib/menuHeader.php DELETED
@@ -1,4 +0,0 @@
1
- <?php if(wfConfig::get('cacheType') == 'falcon'){ ?>
2
- <div title="Wordfence Falcon Engine Enabled for Maximum Site Performance" class="wfFalcon"></div>
3
- <?php } ?>
4
-
lib/menu_activity.php CHANGED
@@ -5,7 +5,6 @@
5
</div>
6
<?php endif ?>
7
<div class="wrap wordfence">
8
- <?php require('menuHeader.php'); ?>
9
10
<h2 id="wfHeading">
11
<div style="float: left;">
@@ -47,7 +46,7 @@
47
echo $rightRail;
48
?>
49
<?php if (!wfConfig::liveTrafficEnabled()): ?>
50
- <div id="wordfenceLiveActivityDisabled"><p><strong>Live activity is disabled.</strong> <?php if (wfConfig::get('cacheType') == 'falcon') { ?>This is done to improve performance because you have Wordfence Falcon Engine enabled.<?php } ?> Login and firewall activity will still appear below.</p></div>
51
<?php endif ?>
52
53
<div id="wf-live-traffic" class="wfTabsContainer">
5
</div>
6
<?php endif ?>
7
<div class="wrap wordfence">
8
9
<h2 id="wfHeading">
10
<div style="float: left;">
46
echo $rightRail;
47
?>
48
<?php if (!wfConfig::liveTrafficEnabled()): ?>
49
+ <div id="wordfenceLiveActivityDisabled"><p><strong>Live activity is disabled.</strong> Login and firewall activity will still appear below.</p></div>
50
<?php endif ?>
51
52
<div id="wf-live-traffic" class="wfTabsContainer">
lib/menu_blockedIPs.php CHANGED
@@ -1,6 +1,5 @@
1
<div class="wordfenceModeElem" id="wordfenceMode_blockedIPs"></div>
2
<div class="wrap wordfence">
3
- <?php require('menuHeader.php'); ?>
4
<?php $helpLink="http://docs.wordfence.com/en/Blocked_IPs"; $helpLabel="Learn more about Blocked IPs"; $pageTitle = "Wordfence Blocked IPs"; include('pageTitle.php'); ?>
5
<div class="wordfenceLive">
6
<table border="0" cellpadding="0" cellspacing="0" class="wordfenceLiveActivity">
@@ -40,139 +39,156 @@
40
</div>
41
42
</div>
43
- <script type="text/x-jquery-template" id="wfThrottledIPsTmpl">
44
- <div>
45
- <div style="border-bottom: 1px solid #CCC; padding-bottom: 10px; margin-bottom: 10px;">
46
- <table border="0" style="width: 100%">
47
- {{each(idx, elem) results}}
48
- <tr><td style="vertical-align: top;">
49
- <div>
50
- {{if loc}}
51
- <img src="<?php echo wfUtils::getBaseURL() . 'images/flags/'; ?>${loc.countryCode.toLowerCase()}.png" width="16" height="11" alt="${loc.countryName}" title="${loc.countryName}" class="wfFlag" />
52
- <a href="http://maps.google.com/maps?q=${loc.lat},${loc.lon}&z=6" target="_blank">{{if loc.city}}${loc.city}, {{/if}}${loc.countryName}</a>
53
- {{else}}
54
- An unknown location at IP <a href="${WFAD.makeIPTrafLink(IP)}" target="_blank">${IP}</a>
55
- {{/if}}
56
- </div>
57
- <div>
58
- <strong>IP:</strong>&nbsp;<a href="${WFAD.makeIPTrafLink(IP)}" target="_blank">${IP}</a>
59
- </div>
60
- <div>
61
- <strong>Reason:</strong>&nbsp;${lastReason}
62
- </div>
63
- <div>
64
- <span class="wfReverseLookup"><span style="display:none;">${IP}</span></span>
65
- </div>
66
<div>
67
- <span>Throttled <strong>${timesThrottled}</strong> times starting <strong>${startTimeAgo} ago</strong> and ending <strong>${endTimeAgo} ago</strong>.</span>
68
</div>
69
- </td>
70
</tr>
71
{{/each}}
72
- </table>
73
- </div>
74
- <!--<p><a class="button" href="#" onclick="WFAD.permanentlyBlockAllIPs('throttled'); return false;">Permanently block all throttled IP addresses</a></p>-->
75
- </div>
76
</script>
77
78
- <script type="text/x-jquery-template" id="wfLockedOutIPsTmpl">
79
- <div>
80
- <p><a class="button" href="#" onclick="WFAD.permanentlyBlockAllIPs('lockedOut'); return false;">Permanently block all locked out IP addresses</a></p>
81
- <div style="border-top: 1px solid #CCC; padding-top: 10px; margin-top: 10px;">
82
- <table border="0" style="width: 100%">
83
- {{each(idx, elem) results}}
84
- <tr><td>
85
- <div>
86
- {{if loc}}
87
- <img src="<?php echo wfUtils::getBaseURL() . 'images/flags/'; ?>${loc.countryCode.toLowerCase()}.png" width="16" height="11" alt="${loc.countryName}" title="${loc.countryName}" class="wfFlag" />
88
- <a href="http://maps.google.com/maps?q=${loc.lat},${loc.lon}&z=6" target="_blank">{{if loc.city}}${loc.city}, {{/if}}${loc.countryName}</a>
89
- {{else}}
90
- An unknown location at IP <a href="${WFAD.makeIPTrafLink(IP)}" target="_blank">${IP}</a>
91
- {{/if}}
92
- </div>
93
- <div>
94
- <strong>IP:</strong>&nbsp;<a href="${WFAD.makeIPTrafLink(IP)}" target="_blank">${IP}</a> [<a href="#" onclick="WFAD.unlockOutIP('${IP}'); return false;">unlock</a>]
95
- </div>
96
<div>
97
- <strong>Reason:</strong>&nbsp;${reason}
98
- </div>
99
- <div>
100
- <span class="wfReverseLookup"><span style="display:none;">${IP}</span></span>
101
</div>
102
<div>
103
- {{if lastAttemptAgo}}
104
- <span class="wfTimeAgo">Last blocked attempt to sign-in or use the forgot password form was <span class="wfTimeAgo-timestamp" data-timestamp="${lastAttempt}">${lastAttemptAgo} ago</span>.</span>
105
- {{else}}
106
- <span class="wfTimeAgo">No attempts have been made to sign-in or use the forgot password form since this IP was locked out.</span>
107
- {{/if}}
108
</div>
109
- </td>
110
- <td style="color: #999;">
111
- <ul>
112
- <li>${blockedHits} attempts have been blocked</li>
113
- <li>Will be unlocked in ${blockedForAgo}</li>
114
- </ul>
115
- </td></tr>
116
- {{/each}}
117
- </table>
118
- </div>
119
- </div>
120
</script>
121
122
<script type="text/x-jquery-template" id="wfBlockedIPsTmpl">
123
- <div>
124
- <p><a class="button" href="#" onclick="WFAD.permanentlyBlockAllIPs('blocked'); return false;">Permanently block all temporarily blocked IP addresses</a></p>
125
- <div style="border-top: 1px solid #CCC; padding-top: 10px; margin-top: 10px;">
126
- <table border="0" style="width: 100%">
127
{{each(idx, elem) results}}
128
- <tr><td>
129
- <div>
130
- {{if loc}}
131
- <img src="<?php echo wfUtils::getBaseURL() . 'images/flags/'; ?>${loc.countryCode.toLowerCase()}.png" width="16" height="11" alt="${loc.countryName}" title="${loc.countryName}" class="wfFlag" />
132
- <a href="http://maps.google.com/maps?q=${loc.lat},${loc.lon}&z=6" target="_blank">{{if loc.city}}${loc.city}, {{/if}}${loc.countryName}</a>
133
- {{else}}
134
- An unknown location at IP <a href="${WFAD.makeIPTrafLink(IP)}" target="_blank">${IP}</a>
135
- {{/if}}
136
- </div>
137
- <div>
138
- <strong>IP:</strong>&nbsp;<a href="${WFAD.makeIPTrafLink(IP)}" target="_blank">${IP}</a> [<a href="#" onclick="WFAD.unblockIPTwo('${IP}'); return false;">unblock</a>]
139
- {{if permanent == '1'}}
140
- [<span style="color: #F00;">permanently blocked</span>]
141
- {{else}}&nbsp;&nbsp;[<a href="#" onclick="WFAD.permBlockIP('${IP}'); return false;">make permanent</a>]{{/if}}
142
- </div>
143
- <div>
144
- <strong>Reason:</strong>&nbsp;${reason}
145
- </div>
146
- <div>
147
- <span class="wfReverseLookup"><span style="display:none;">${IP}</span></span>
148
- </div>
149
- <div>
150
- {{if lastAttemptAgo}}
151
- <span class="wfTimeAgo">Last blocked attempt to access the site was <span class="wfTimeAgo-timestamp" data-timestamp="${lastAttempt}">${lastAttemptAgo} ago</span>.</span>
152
- {{else}}
153
- <span class="wfTimeAgo">No attempts have been made to access the site since this IP was blocked.</span>
154
- {{/if}}
155
- </div>
156
- <div>
157
- {{if lastHitAgo}}
158
- <span class="wfTimeAgo">Last site access before this IP was blocked was <span class="wfTimeAgo-timestamp" data-timestamp="${lastHit}">${lastHitAgo} ago</span></span>
159
- {{/if}}
160
- </div>
161
- </td>
162
- <td style="color: #999;">
163
- <ul>
164
- <li>${totalHits} hits before blocked</li>
165
- <li>${blockedHits} blocked hits</li>
166
- <li>
167
- {{if permanent == '1'}}Permanently blocked{{else}}
168
- Will be unblocked in ${blockedForAgo}{{/if}}
169
- </li>
170
- </ul>
171
- </td></tr>
172
{{/each}}
173
- </table>
174
- </div>
175
- </div>
176
</script>
177
178
<script type="text/x-jquery-template" id="wfWelcomeContent4">
1
<div class="wordfenceModeElem" id="wordfenceMode_blockedIPs"></div>
2
<div class="wrap wordfence">
3
<?php $helpLink="http://docs.wordfence.com/en/Blocked_IPs"; $helpLabel="Learn more about Blocked IPs"; $pageTitle = "Wordfence Blocked IPs"; include('pageTitle.php'); ?>
4
<div class="wordfenceLive">
5
<table border="0" cellpadding="0" cellspacing="0" class="wordfenceLiveActivity">
39
</div>
40
41
</div>
42
+
43
+ <script type="text/x-jquery-template" id="wfThrottledIPsWrapperTmpl">
44
<div>
45
+ <div style="border-bottom: 1px solid #CCC; padding-bottom: 10px; margin-bottom: 10px;">
46
+ <table border="0" style="width: 100%" id="wfThrottledIPsWrapper">
47
+ </table>
48
+ </div>
49
+ <!--<p><a class="button" href="#" onclick="WFAD.permanentlyBlockAllIPs('throttled'); return false;">Permanently block all throttled IP addresses</a></p>-->
50
</div>
51
+ </script>
52
+
53
+ <script type="text/x-jquery-template" id="wfThrottledIPsTmpl">
54
+ {{each(idx, elem) results}}
55
+ <tr class="throttledIPsRecord">
56
+ <td style="vertical-align: top;">
57
+ <div>
58
+ {{if loc}}
59
+ <img src="<?php echo wfUtils::getBaseURL() . 'images/flags/'; ?>${loc.countryCode.toLowerCase()}.png" width="16" height="11" alt="${loc.countryName}" title="${loc.countryName}" class="wfFlag" />
60
+ <a href="http://maps.google.com/maps?q=${loc.lat},${loc.lon}&z=6" target="_blank">{{if loc.city}}${loc.city}, {{/if}}${loc.countryName}</a>
61
+ {{else}}
62
+ An unknown location at IP <a href="${WFAD.makeIPTrafLink(IP)}" target="_blank">${IP}</a>
63
+ {{/if}}
64
+ </div>
65
+ <div>
66
+ <strong>IP:</strong>&nbsp;<a href="${WFAD.makeIPTrafLink(IP)}" target="_blank">${IP}</a>
67
+ </div>
68
+ <div>
69
+ <strong>Reason:</strong>&nbsp;${lastReason}
70
+ </div>
71
+ <div>
72
+ <span class="wfReverseLookup"><span style="display:none;">${IP}</span></span>
73
+ </div>
74
+ <div>
75
+ <span>Throttled <strong>${timesThrottled}</strong> times starting <strong>${startTimeAgo} ago</strong> and ending <strong>${endTimeAgo} ago</strong>.</span>
76
+ </div>
77
+ </td>
78
</tr>
79
{{/each}}
80
</script>
81
82
+ <script type="text/x-jquery-template" id="wfLockedOutIPsWrapperTmpl">
83
<div>
84
+ <p><a class="button" href="#" onclick="WFAD.permanentlyBlockAllIPs('lockedOut'); return false;">Permanently block all locked out IP addresses</a></p>
85
+ <div style="border-top: 1px solid #CCC; padding-top: 10px; margin-top: 10px;">
86
+ <table border="0" style="width: 100%" id="wfLockedOutIPsWrapper">
87
+ </table>
88
+ </div>
89
+ <p><a class="button wfLoadMoreButton" href="#">Load More</a></p>
90
</div>
91
+ </script>
92
+
93
+ <script type="text/x-jquery-template" id="wfLockedOutIPsTmpl">
94
+ {{each(idx, elem) results}}
95
+ <tr class="lockedOutIPsRecord">
96
+ <td>
97
+ <div>
98
+ {{if loc}}
99
+ <img src="<?php echo wfUtils::getBaseURL() . 'images/flags/'; ?>${loc.countryCode.toLowerCase()}.png" width="16" height="11" alt="${loc.countryName}" title="${loc.countryName}" class="wfFlag" />
100
+ <a href="http://maps.google.com/maps?q=${loc.lat},${loc.lon}&z=6" target="_blank">{{if loc.city}}${loc.city}, {{/if}}${loc.countryName}</a>
101
+ {{else}}
102
+ An unknown location at IP <a href="${WFAD.makeIPTrafLink(IP)}" target="_blank">${IP}</a>
103
+ {{/if}}
104
+ </div>
105
+ <div>
106
+ <strong>IP:</strong>&nbsp;<a href="${WFAD.makeIPTrafLink(IP)}" target="_blank">${IP}</a> [<a href="#" onclick="WFAD.unlockOutIP('${IP}'); return false;">unlock</a>]
107
+ </div>
108
+ <div>
109
+ <strong>Reason:</strong>&nbsp;${reason}
110
+ </div>
111
+ <div>
112
+ <span class="wfReverseLookup"><span style="display:none;">${IP}</span></span>
113
+ </div>
114
+ <div>
115
+ {{if lastAttemptAgo}}
116
+ <span class="wfTimeAgo">Last blocked attempt to sign-in or use the forgot password form was <span class="wfTimeAgo-timestamp" data-timestamp="${lastAttempt}">${lastAttemptAgo} ago</span>.</span>
117
+ {{else}}
118
+ <span class="wfTimeAgo">No attempts have been made to sign-in or use the forgot password form since this IP was locked out.</span>
119
+ {{/if}}
120
+ </div>
121
+ </td>
122
+ <td style="color: #999;">
123
+ <ul>
124
+ <li>${blockedHits} attempts have been blocked</li>
125
+ <li>Will be unlocked in ${blockedForAgo}</li>
126
+ </ul>
127
+ </td>
128
+ </tr>
129
+ {{/each}}
130
+ </script>
131
+
132
+ <script type="text/x-jquery-template" id="wfBlockedIPsWrapperTmpl">
133
<div>
134
+ <p><a class="button" href="#" onclick="WFAD.permanentlyBlockAllIPs('blocked'); return false;">Permanently block all temporarily blocked IP addresses</a></p>
135
+ <div style="border-top: 1px solid #CCC; padding-top: 10px; margin-top: 10px;">
136
+ <table border="0" style="width: 100%" id="wfBlockedIPsWrapper">
137
+ </table>
138
+ </div>
139
+ <p><a class="button wfLoadMoreButton" href="#">Load More</a></p>
140
</div>
141
</script>
142
143
<script type="text/x-jquery-template" id="wfBlockedIPsTmpl">
144
{{each(idx, elem) results}}
145
+ <tr class="blockedIPsRecord">
146
+ <td>
147
+ <div>
148
+ {{if loc}}
149
+ <img src="<?php echo wfUtils::getBaseURL() . 'images/flags/'; ?>${loc.countryCode.toLowerCase()}.png" width="16" height="11" alt="${loc.countryName}" title="${loc.countryName}" class="wfFlag" />
150
+ <a href="http://maps.google.com/maps?q=${loc.lat},${loc.lon}&z=6" target="_blank">{{if loc.city}}${loc.city}, {{/if}}${loc.countryName}</a>
151
+ {{else}}
152
+ An unknown location at IP <a href="${WFAD.makeIPTrafLink(IP)}" target="_blank">${IP}</a>
153
+ {{/if}}
154
+ </div>
155
+ <div>
156
+ <strong>IP:</strong>&nbsp;<a href="${WFAD.makeIPTrafLink(IP)}" target="_blank">${IP}</a> [<a href="#" onclick="WFAD.unblockIPTwo('${IP}'); return false;">unblock</a>]
157
+ {{if permanent == '1'}}
158
+ [<span style="color: #F00;">permanently blocked</span>]
159
+ {{else}}&nbsp;&nbsp;[<a href="#" onclick="WFAD.permBlockIP('${IP}'); return false;">make permanent</a>]{{/if}}
160
+ </div>
161
+ <div>
162
+ <strong>Reason:</strong>&nbsp;${reason}
163
+ </div>
164
+ <div>
165
+ <span class="wfReverseLookup"><span style="display:none;">${IP}</span></span>
166
+ </div>
167
+ <div>
168
+ {{if lastAttemptAgo}}
169
+ <span class="wfTimeAgo">Last blocked attempt to access the site was <span class="wfTimeAgo-timestamp" data-timestamp="${lastAttempt}">${lastAttemptAgo} ago</span>.</span>
170
+ {{else}}
171
+ <span class="wfTimeAgo">No attempts have been made to access the site since this IP was blocked.</span>
172
+ {{/if}}
173
+ </div>
174
+ <div>
175
+ {{if lastHitAgo}}
176
+ <span class="wfTimeAgo">Last site access before this IP was blocked was <span class="wfTimeAgo-timestamp" data-timestamp="${lastHit}">${lastHitAgo} ago</span></span>
177
+ {{/if}}
178
+ </div>
179
+ </td>
180
+ <td style="color: #999;">
181
+ <ul>
182
+ <li>${totalHits} hits before blocked</li>
183
+ <li>${blockedHits} blocked hits</li>
184
+ <li>
185
+ {{if permanent == '1'}}Permanently blocked{{else}}
186
+ Will be unblocked in ${blockedForAgo}{{/if}}
187
+ </li>
188
+ </ul>
189
+ </td>
190
+ </tr>
191
{{/each}}
192
</script>
193
194
<script type="text/x-jquery-template" id="wfWelcomeContent4">
lib/menu_countryBlocking.php CHANGED
@@ -6,7 +6,6 @@ WFAD.countryMap = <?php echo json_encode($wfBulkCountries); ?>;
6
</script>
7
<div class="wordfenceModeElem" id="wordfenceMode_countryBlocking"></div>
8
<div class="wrap wordfence" id="paidWrap">
9
- <?php require('menuHeader.php'); ?>
10
<?php $pageTitle = "Block Selected Countries from Accessing your Site"; $helpLink="http://docs.wordfence.com/en/Country_blocking"; $helpLabel="Learn more about Country Blocking"; include('pageTitle.php'); ?>
11
<?php
12
$rightRail = new wfView('marketing/rightrail', array('additionalClasses' => 'wordfenceRightRailCountryBlocking'));
@@ -29,18 +28,6 @@ WFAD.countryMap = <?php echo json_encode($wfBulkCountries); ?>;
29
href="https://www.wordfence.com/gnl1countryBlock1/wordfence-signup/" target="_blank">Get Premium</a></p>
30
</div>
31
<?php } ?>
32
- <?php if(wfConfig::get('cacheType') == 'falcon'){ ?>
33
- <div class="wfFalconNotice">
34
- <b>Note regarding country blocking with Falcon Engine enabled:</b><br /><br />
35
- Country blocking will only work on the login page and other dynamic pages with
36
- Wordfence Falcon Engine enabled. We do this to keep your site fast and avoid
37
- a country lookup on every request.
38
- Serving cached pages only uses 2 to 3% of the resources that a non-cached page uses,
39
- so malicious countries won't eat up your server resources when they load cached pages.
40
- If you would like full country blocking, you can enable Basic Caching on the "Site Performance" page.
41
- </div>
42
- <?php } ?>
43
-
44
<div class="wordfenceWrap" style="margin: 20px 20px 20px 30px; max-width: 900px;">
45
<table class="wfConfigForm">
46
<tr><td colspan="2"><h2>Country Blocking Options</h2></td></tr>
6
</script>
7
<div class="wordfenceModeElem" id="wordfenceMode_countryBlocking"></div>
8
<div class="wrap wordfence" id="paidWrap">
9
<?php $pageTitle = "Block Selected Countries from Accessing your Site"; $helpLink="http://docs.wordfence.com/en/Country_blocking"; $helpLabel="Learn more about Country Blocking"; include('pageTitle.php'); ?>
10
<?php
11
$rightRail = new wfView('marketing/rightrail', array('additionalClasses' => 'wordfenceRightRailCountryBlocking'));
28
href="https://www.wordfence.com/gnl1countryBlock1/wordfence-signup/" target="_blank">Get Premium</a></p>
29
</div>
30
<?php } ?>
31
<div class="wordfenceWrap" style="margin: 20px 20px 20px 30px; max-width: 900px;">
32
<table class="wfConfigForm">
33
<tr><td colspan="2"><h2>Country Blocking Options</h2></td></tr>
lib/menu_diagnostic.php CHANGED
@@ -12,7 +12,6 @@ $w = new wfConfig();
12
?>
13
14
<div class="wrap wordfence">
15
- <?php require('menuHeader.php'); ?>
16
<h2 id="wfHeading">
17
Diagnostics
18
</h2>
@@ -491,15 +490,6 @@ $w = new wfConfig();
491
<h3>Debugging Options</h3>
492
<form action="#" id="wfDebuggingConfigForm">
493
<table class="wfConfigForm">
494
- <tr>
495
- <th>Add a debugging comment to HTML source of cached pages.<a
496
- href="http://docs.wordfence.com/en/Wordfence_options#Add_a_debugging_comment_to_HTML_source_of_cached_pages"
497
- target="_blank" class="wfhelp"></a></th>
498
- <td><input type="checkbox" id="addCacheComment" class="wfConfigElem" name="addCacheComment"
499
- value="1" <?php $w->cb('addCacheComment'); ?> />
500
- </td>
501
- </tr>
502
-
503
<tr>
504
<th>Enable debugging mode (increases database load)<a
505
href="http://docs.wordfence.com/en/Wordfence_options#Enable_debugging_mode_.28increases_database_load.29"
12
?>
13
14
<div class="wrap wordfence">
15
<h2 id="wfHeading">
16
Diagnostics
17
</h2>
490
<h3>Debugging Options</h3>
491
<form action="#" id="wfDebuggingConfigForm">
492
<table class="wfConfigForm">
493
<tr>
494
<th>Enable debugging mode (increases database load)<a
495
href="http://docs.wordfence.com/en/Wordfence_options#Enable_debugging_mode_.28increases_database_load.29"
lib/menu_options.php CHANGED
@@ -3,7 +3,6 @@ $w = new wfConfig();
3
?>
4
<div class="wordfenceModeElem" id="wordfenceMode_options"></div>
5
<div class="wrap wordfence">
6
- <?php require( 'menuHeader.php' ); ?>
7
<?php $helpLink = "http://docs.wordfence.com/en/Wordfence_options";
8
$helpLabel = "Learn more about Wordfence Options";
9
$pageTitle = "Wordfence Options";
@@ -456,7 +455,7 @@ $w = new wfConfig();
456
</td>
457
</tr>
458
<tr>
459
- <th>Scan for publically accessible configuration, backup, or log files<a
460
href="http://docs.wordfence.com/en/Wordfence_options#Configuration_Readable"
461
target="_blank" class="wfhelp"></a></th>
462
<td><input type="checkbox" id="scansEnabled_checkReadableConfig" class="wfConfigElem"
@@ -889,7 +888,7 @@ $w = new wfConfig();
889
name="loginSec_blockAdminReg" <?php $w->cb( 'loginSec_blockAdminReg' ); ?> /></td>
890
</tr>
891
<tr>
892
- <th>Prevent discovery of usernames through '/?author=N' scans and the oEmbed API<a
893
href="http://docs.wordfence.com/en/Wordfence_options#Prevent_discovery_of_usernames_through_.27.3F.2Fauthor.3DN.27_scans"
894
target="_blank" class="wfhelp"></a></th>
895
<td><input type="checkbox" id="loginSec_disableAuthorScan" class="wfConfigElem"
3
?>
4
<div class="wordfenceModeElem" id="wordfenceMode_options"></div>
5
<div class="wrap wordfence">
6
<?php $helpLink = "http://docs.wordfence.com/en/Wordfence_options";
7
$helpLabel = "Learn more about Wordfence Options";
8
$pageTitle = "Wordfence Options";
455
</td>
456
</tr>
457
<tr>
458
+ <th>Scan for publicly accessible configuration, backup, or log files<a
459
href="http://docs.wordfence.com/en/Wordfence_options#Configuration_Readable"
460
target="_blank" class="wfhelp"></a></th>
461
<td><input type="checkbox" id="scansEnabled_checkReadableConfig" class="wfConfigElem"
888
name="loginSec_blockAdminReg" <?php $w->cb( 'loginSec_blockAdminReg' ); ?> /></td>
889
</tr>
890
<tr>
891
+ <th>Prevent discovery of usernames through '/?author=N' scans, the oEmbed API, and the WordPress REST API<a
892
href="http://docs.wordfence.com/en/Wordfence_options#Prevent_discovery_of_usernames_through_.27.3F.2Fauthor.3DN.27_scans"
893
target="_blank" class="wfhelp"></a></th>
894
<td><input type="checkbox" id="loginSec_disableAuthorScan" class="wfConfigElem"
lib/menu_passwd.php CHANGED
@@ -1,6 +1,5 @@
1
<div class="wordfenceModeElem" id="wordfenceMode_passwd"></div>
2
<div class="wrap wordfence" id="paidWrap">
3
- <?php require('menuHeader.php'); ?>
4
<?php $pageTitle = "Audit the Strength of your Passwords";
5
$helpLink = "http://docs.wordfence.com/en/Wordfence_Password_Auditing";
6
$helpLabel = "Learn more about Password Auditing";
1
<div class="wordfenceModeElem" id="wordfenceMode_passwd"></div>
2
<div class="wrap wordfence" id="paidWrap">
3
<?php $pageTitle = "Audit the Strength of your Passwords";
4
$helpLink = "http://docs.wordfence.com/en/Wordfence_Password_Auditing";
5
$helpLabel = "Learn more about Password Auditing";
lib/menu_rangeBlocking.php CHANGED
@@ -1,6 +1,5 @@
1
<div class="wordfenceModeElem" id="wordfenceMode_rangeBlocking"></div>
2
<div class="wrap wordfence" id="paidWrap">
3
- <?php require('menuHeader.php'); ?>
4
<?php $helpLink="http://docs.wordfence.com/en/Advanced_Blocking"; $helpLabel="Learn more about Advanced Blocking"; $pageTitle = "Advanced Blocking"; include('pageTitle.php'); ?>
5
<?php
6
$rightRail = new wfView('marketing/rightrail');
@@ -47,7 +46,7 @@
47
<tr><td>
48
{{if patternDisabled}}
49
<div style="width: 500px; margin-top: 20px;">
50
- <span style="color: #F00;">Pattern Below has been DISABLED:</span> Falcon engine does not support advanced blocks that include combinations of IP range, browser pattern and referring website. You can only specify one of the three in patterns when using Falcon.
51
</div>
52
<div style="color: #AAA;">
53
{{/if}}
1
<div class="wordfenceModeElem" id="wordfenceMode_rangeBlocking"></div>
2
<div class="wrap wordfence" id="paidWrap">
3
<?php $helpLink="http://docs.wordfence.com/en/Advanced_Blocking"; $helpLabel="Learn more about Advanced Blocking"; $pageTitle = "Advanced Blocking"; include('pageTitle.php'); ?>
4
<?php
5
$rightRail = new wfView('marketing/rightrail');
46
<tr><td>
47
{{if patternDisabled}}
48
<div style="width: 500px; margin-top: 20px;">
49
+ <span style="color: #F00;">Pattern Below has been DISABLED:</span>
50
</div>
51
<div style="color: #AAA;">
52
{{/if}}
lib/menu_scan.php CHANGED
@@ -30,7 +30,6 @@ $sigUpdateTime = wfConfig::get('signatureUpdateTime');
30
31
<?php else: ?>
32
33
- <?php require('menuHeader.php'); ?>
34
<?php $pageTitle = "Wordfence Scan"; $helpLink="http://docs.wordfence.com/en/Wordfence_scanning"; $helpLabel="Learn more about scanning"; include('pageTitle.php'); ?>
35
<div class="wordfenceWrap">
36
<?php
@@ -411,6 +410,7 @@ $sigUpdateTime = wfConfig::get('signatureUpdateTime');
411
</td></tr>
412
</table>
413
</p>
414
<p>
415
{{html longMsg}}
416
<a href="<?php echo get_admin_url() . 'update-core.php'; ?>">Click here to update now</a>.
30
31
<?php else: ?>
32
33
<?php $pageTitle = "Wordfence Scan"; $helpLink="http://docs.wordfence.com/en/Wordfence_scanning"; $helpLabel="Learn more about scanning"; include('pageTitle.php'); ?>
34
<div class="wordfenceWrap">
35
<?php
410
</td></tr>
411
</table>
412
</p>
413
+ {{if data.vulnerabilityPatched}}<p><strong>Update includes security-related fixes.</strong></p>{{/if}}
414
<p>
415
{{html longMsg}}
416
<a href="<?php echo get_admin_url() . 'update-core.php'; ?>">Click here to update now</a>.
lib/menu_scanSchedule.php CHANGED
@@ -1,6 +1,5 @@
1
<div class="wordfenceModeElem" id="wordfenceMode_scanScheduling"></div>
2
<div class="wrap wordfence" id="paidWrap">
3
- <?php require('menuHeader.php'); ?>
4
<?php $pageTitle = "Schedule when Wordfence Scans Occur"; $helpLink="http://docs.wordfence.com/en/Wordfence_scan_scheduling"; $helpLabel="Learn more about Scheduling Wordfence Scans"; include('pageTitle.php'); ?>
5
<?php
6
$rightRail = new wfView('marketing/rightrail', array('additionalClasses' => 'wordfenceRightRailScanSchedule'));
1
<div class="wordfenceModeElem" id="wordfenceMode_scanScheduling"></div>
2
<div class="wrap wordfence" id="paidWrap">
3
<?php $pageTitle = "Schedule when Wordfence Scans Occur"; $helpLink="http://docs.wordfence.com/en/Wordfence_scan_scheduling"; $helpLabel="Learn more about Scheduling Wordfence Scans"; include('pageTitle.php'); ?>
4
<?php
5
$rightRail = new wfView('marketing/rightrail', array('additionalClasses' => 'wordfenceRightRailScanSchedule'));
lib/menu_twoFactor.php CHANGED
@@ -1,6 +1,5 @@
1
<div class="wordfenceModeElem" id="wordfenceMode_twoFactor"></div>
2
<div class="wrap wordfence" id="paidWrap">
3
- <?php require('menuHeader.php'); ?>
4
<?php $pageTitle = "Cellphone Sign-in"; $helpLink="http://docs.wordfence.com/en/Cellphone_sign-in"; $helpLabel="Learn more about Cellphone Sign-in"; include('pageTitle.php'); ?>
5
<?php
6
$rightRail = new wfView('marketing/rightrail');
1
<div class="wordfenceModeElem" id="wordfenceMode_twoFactor"></div>
2
<div class="wrap wordfence" id="paidWrap">
3
<?php $pageTitle = "Cellphone Sign-in"; $helpLink="http://docs.wordfence.com/en/Cellphone_sign-in"; $helpLabel="Learn more about Cellphone Sign-in"; include('pageTitle.php'); ?>
4
<?php
5
$rightRail = new wfView('marketing/rightrail');
lib/menu_waf.php CHANGED
@@ -6,7 +6,6 @@ $wafRemoveURL = network_admin_url('admin.php?page=WordfenceWAF&wafAction=removeA
6
/** @var array $wafData */
7
?>
8
<div class="wrap wordfence" id="paidWrap">
9
- <?php require('menuHeader.php'); ?>
10
<?php
11
$pageTitle = "Wordfence Web Application Firewall";
12
$helpLink = "http://docs.wordfence.com/en/WAF";
6
/** @var array $wafData */
7
?>
8
<div class="wrap wordfence" id="paidWrap">
9
<?php
10
$pageTitle = "Wordfence Web Application Firewall";
11
$helpLink = "http://docs.wordfence.com/en/WAF";
lib/menu_whois.php CHANGED
@@ -1,6 +1,5 @@
1
<div class="wordfenceModeElem" id="wordfenceMode_whois"></div>
2
<div class="wrap wordfence" id="paidWrap">
3
- <?php require('menuHeader.php'); ?>
4
<?php $pageTitle = "WHOIS Lookup"; $helpLink="http://docs.wordfence.com/en/Whois_Lookup"; $helpLabel="Learn more about Whois Lookups"; include('pageTitle.php'); ?>
5
<?php
6
$rightRail = new wfView('marketing/rightrail');
1
<div class="wordfenceModeElem" id="wordfenceMode_whois"></div>
2
<div class="wrap wordfence" id="paidWrap">
3
<?php $pageTitle = "WHOIS Lookup"; $helpLink="http://docs.wordfence.com/en/Whois_Lookup"; $helpLabel="Learn more about Whois Lookups"; include('pageTitle.php'); ?>
4
<?php
5
$rightRail = new wfView('marketing/rightrail');
lib/wfCache.php CHANGED
@@ -1,345 +1,28 @@
1
<?php
2
class wfCache {
3
- private static $cacheType = false;
4
- private static $fileCache = array();
5
private static $cacheStats = array();
6
private static $cacheClearedThisRequest = false;
7
- private static $clearScheduledThisRequest = false;
8
private static $lastRecursiveDeleteError = false;
9
- public static function setupCaching(){
10
- self::$cacheType = wfConfig::get('cacheType');
11
- if(self::$cacheType != 'php' && self::$cacheType != 'falcon'){
12
- return; //cache is disabled
13
- }
14
- if(wfUtils::hasLoginCookie()){
15
- add_action('publish_post', 'wfCache::action_publishPost');
16
- add_action('publish_page', 'wfCache::action_publishPost');
17
- foreach(array('clean_object_term_cache', 'clean_post_cache', 'clean_term_cache', 'clean_page_cache', 'after_switch_theme', 'customize_save_after', 'activated_plugin', 'deactivated_plugin', 'update_option_sidebars_widgets') as $action){
18
- add_action($action, 'wfCache::action_clearPageCache'); //Schedules a cache clear for immediately so it won't lag current request.
19
- }
20
- if($_SERVER['REQUEST_METHOD'] == 'POST'){
21
- foreach(array(
22
- '/\/wp\-admin\/options\.php#x2F;',
23
- '/\/wp\-admin\/options\-permalink\.php#x2F;'
24
- ) as $pattern){
25
- if(preg_match($pattern, $_SERVER['REQUEST_URI'])){
26
- self::scheduleCacheClear();
27
- break;
28
- }
29
- }
30
- }
31
- }
32
- add_action('wordfence_cache_clear', 'wfCache::scheduledCacheClear');
33
- add_action('wordfence_update_blocked_IPs', 'wfCache::scheduleUpdateBlockedIPs');
34
- add_action('comment_post', 'wfCache::action_commentPost'); //Might not be logged in
35
- add_filter('wp_redirect', 'wfCache::redirectFilter');
36
-
37
- //Routines to clear cache run even if cache is disabled
38
- $file = self::fileFromRequest( ($_SERVER['HTTP_HOST'] ? $_SERVER['HTTP_HOST'] : $_SERVER['SERVER_NAME']), $_SERVER['REQUEST_URI']);
39
- $fileDeleted = false;
40
- $doDelete = false;
41
- if($_SERVER['REQUEST_METHOD'] != 'GET'){ //If our URL is hit with a POST, PUT, DELETE or any other non 'GET' request, then clear cache.
42
- $doDelete = true;
43
- }
44
-
45
- if($doDelete){
46
- @unlink($file);
47
- $fileDeleted = true;
48
- }
49
-
50
-
51
- add_action('wp_logout', 'wfCache::logout');
52
- if(self::isCachable()){
53
- if( (! $fileDeleted) && self::$cacheType == 'php'){ //Then serve the file if it's still valid
54
- $stat = @stat($file);
55
- if($stat){
56
- $age = time() - $stat[9];
57
- if($age < 10000){
58
- readfile($file); //sends file to stdout
59
- die();
60
- }
61
- }
62
- }
63
- ob_start('wfCache::obComplete'); //Setup routine to store the file
64
- }
65
- }
66
- public static function redirectFilter($status){
67
- if(! defined('WFDONOTCACHE')){
68
- define('WFDONOTCACHE', true);
69
- }
70
- return $status;
71
- }
72
- public static function isCachable(){
73
- if(defined('WFDONOTCACHE') || defined('DONOTCACHEPAGE') || defined('DONOTCACHEDB') || defined('DONOTCACHEOBJECT')){ //If you want to tell Wordfence not to cache something in another plugin, simply define one of these.
74
- return false;
75
- }
76
- if(! wfConfig::get('allowHTTPSCaching')){
77
- if(self::isHTTPSPage()){
78
- return false;
79
- }
80
- }
81
-
82
- if(is_admin()){ return false; } //dont cache any admin pages.
83
- $uri = $_SERVER['REQUEST_URI'];
84
-
85
- if(strrpos($uri, '/') !== strlen($uri) - 1){ //must end with a '/' char.
86
- return false;
87
- }
88
- if($_SERVER['REQUEST_METHOD'] != 'GET'){ return false; } //Only cache GET's
89
- if(isset($_SERVER['QUERY_STRING']) && strlen($_SERVER['QUERY_STRING']) > 0 && (! preg_match('/^\d+=\d+#x2F;', $_SERVER['QUERY_STRING'])) ){ //Don't cache query strings unless they are /?123132423=123123234 DDoS style.
90
- return false;
91
- }
92
- //wordpress_logged_in_[hash] cookies indicates logged in
93
- if(is_array($_COOKIE)){
94
- foreach(array_keys($_COOKIE) as $c){
95
- foreach(array('comment_author','wp-postpass','wf_logout','wordpress_logged_in','wptouch_switch_toggle','wpmp_switcher') as $b){
96
- if(strpos($c, $b) !== false){ return false; } //contains a cookie which indicates user must not be cached
97
- }
98
- }
99
- }
100
- $ex = wfConfig::get('cacheExclusions', false);
101
- if($ex){
102
- $ex = unserialize($ex);
103
- foreach($ex as $v){
104
- if($v['pt'] == 'eq'){ if(strtolower($uri) == strtolower($v['p'])){ return false; } }
105
- if($v['pt'] == 's'){ if(stripos($uri, $v['p']) === 0){ return false; } }
106
- if($v['pt'] == 'e'){ if(stripos($uri, $v['p']) === (strlen($uri) - strlen($v['p'])) ){ return false; } }
107
- if($v['pt'] == 'c'){ if(stripos($uri, $v['p']) !== false){ return false; } }
108
- if($v['pt'] == 'uac'){ if(stripos($_SERVER['HTTP_USER_AGENT'], $v['p']) !== false){ return false; } } //User-agent contains
109
- if($v['pt'] == 'uaeq'){ if(strtolower($_SERVER['HTTP_USER_AGENT']) == strtolower($v['p'])){ return false; } } //user-agent equals
110
- if($v['pt'] == 'cc'){
111
- foreach($_COOKIE as $cookieName){
112
- if(stripos($cookieName, $v['p']) !== false){ //Cookie name contains pattern
113
- return false;
114
- }
115
- }
116
- }
117
- }
118
- }
119
- return true;
120
- }
121
- public static function isHTTPSPage(){
122
- if( isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] && $_SERVER['HTTPS'] != 'off'){
123
- return true;
124
- }
125
- if( !empty( $_SERVER['HTTP_X_FORWARDED_PROTO'] ) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https' ){ //In case we're behind a proxy and user used HTTPS.
126
- return true;
127
- }
128
- return false;
129
- }
130
- public static function obComplete($buffer = ''){
131
- if(function_exists('is_404') && is_404()){
132
- return false;
133
- }
134
-
135
- if(defined('WFDONOTCACHE') || defined('DONOTCACHEPAGE') || defined('DONOTCACHEDB') || defined('DONOTCACHEOBJECT')){
136
- //These constants may have been set after we did the initial isCachable check by e.g. wp_redirect filter. If they're set then just return the buffer and don't cache.
137
- return $buffer;
138
- }
139
- if(strlen($buffer) < 1000){ //The average web page size is 1246,000 bytes. If web page is less than 1000 bytes, don't cache it.
140
- return $buffer;
141
- }
142
-
143
- $file = self::fileFromRequest( ($_SERVER['HTTP_HOST'] ? $_SERVER['HTTP_HOST'] : $_SERVER['SERVER_NAME']), $_SERVER['REQUEST_URI']);
144
- self::makeDirIfNeeded($file);
145
- // self::writeCacheDirectoryHtaccess();
146
- $append = "";
147
- $appendGzip = "";
148
- if(wfConfig::get('addCacheComment', false)){
149
- $append = "\n<!-- Cached by Wordfence ";
150
- if(wfConfig::get('cacheType', false) == 'falcon'){
151
- $append .= "Falcon Engine. ";
152
- } else {
153
- $append .= "PHP Caching Engine. ";
154
- }
155
- $append .= "Time created on server: " . date('Y-m-d H:i:s T') . ". ";
156
- $append .= "Is HTTPS page: " . (self::isHTTPSPage() ? 'HTTPS' : 'no') . ". ";
157
- $append .= "Page size: " . strlen($buffer) . " bytes. ";
158
- $append .= "Host: " . ($_SERVER['HTTP_HOST'] ? wp_kses($_SERVER['HTTP_HOST'], array()) : wp_kses($_SERVER['SERVER_NAME'], array())) . ". ";
159
- $append .= "Request URI: " . wp_kses($_SERVER['REQUEST_URI'], array()) . " ";
160
- $appendGzip = $append . " Encoding: GZEncode -->\n";
161
- $append .= " Encoding: Uncompressed -->\n";
162
- }
163
-
164
- @file_put_contents($file, $buffer . $append, LOCK_EX);
165
- chmod($file, 0644);
166
- if(self::$cacheType == 'falcon'){ //create gzipped files so we can send precompressed files
167
- $file .= '_gzip';
168
- @file_put_contents($file, gzencode($buffer . $appendGzip, 9), LOCK_EX);
169
- chmod($file, 0644);
170
- }
171
- return $buffer;
172
- }
173
- public static function fileFromRequest($host, $URI){
174
- return self::fileFromURI($host, $URI, self::isHTTPSPage());
175
- }
176
- public static function fileFromURI($host, $URI, $isHTTPS){
177
- $key = $host . $URI . ($isHTTPS ? '_HTTPS' : '');
178
- if(isset(self::$fileCache[$key])){ return self::$fileCache[$key]; }
179
- $host = preg_replace('/[^a-zA-Z0-9\-\.]+/', '', $host);
180
- $URI = preg_replace('/(?:[^a-zA-Z0-9\-\_\.\~\/]+|\.{2,})/', '', $URI); //Strip out bad chars and multiple dots
181
- if(preg_match('/\/*([^\/]*)\/*([^\/]*)\/*([^\/]*)\/*([^\/]*)\/*([^\/]*)(.*)#x2F;', $URI, $matches)){
182
- $URI = $matches[1] . '/';
183
- for($i = 2; $i <= 6; $i++){
184
- $URI .= strlen($matches[$i]) > 0 ? $matches[$i] : '';
185
- $URI .= $i < 6 ? '~' : '';
186
- }
187
- }
188
- $ext = '';
189
- if($isHTTPS){ $ext = '_https'; }
190
- $file = WP_CONTENT_DIR . '/wfcache/' . $host . '_' . $URI . '_wfcache' . $ext . '.html';
191
- self::$fileCache[$key] = $file;
192
- return $file;
193
- }
194
- public static function makeDirIfNeeded($file){
195
- $file = preg_replace('/\/[^\/]*#x2F;', '', $file);
196
- if(! is_dir($file)){
197
- @mkdir($file, 0755, true);
198
- }
199
- }
200
- public static function logout(){
201
- wfUtils::setcookie('wf_logout', '1', 0, null, null, null, true);
202
- }
203
- public static function cacheDirectoryTest(){
204
- $cacheDir = WP_CONTENT_DIR . '/wfcache/';
205
- if(! is_dir($cacheDir)){
206
- if(! @mkdir($cacheDir, 0755, true)){
207
- $err = error_get_last();
208
- $msg = "The directory $cacheDir does not exist and we could not create it.";
209
- if($err){
210
- $msg .= ' The error we received was: ' . $err['message'];
211
- }
212
- return $msg;
213
- }
214
- }
215
- if(! @file_put_contents($cacheDir . 'test.php', 'test')){
216
- $err = error_get_last();
217
- $msg = "We could not write to the file $cacheDir" . "test.php when testing if the cache directory is writable.";
218
- if($err){
219
- $msg .= " The error was: " . $err['message'];
220
- }
221
- return $msg;
222
- }
223
- self::removeCacheDirectoryHtaccess();
224
- return false;
225
- // return self::writeCacheDirectoryHtaccess(); //Everything is OK
226
- }
227
-
228
- /**
229
- * Returns false on success to match wfCache::cacheDirectoryTest
230
- *
231
- * @see wfCache::cacheDirectoryTest
232
- *
233
- * @return bool|string
234
- */
235
- public static function writeCacheDirectoryHtaccess() {
236
- $cacheDir = WP_CONTENT_DIR . '/wfcache/';
237
- if (!file_exists($cacheDir . '.htaccess') && !@file_put_contents($cacheDir . '.htaccess', 'Deny from all', LOCK_EX)) {
238
- $err = error_get_last();
239
- $msg = "We could not write to the file $cacheDir" . ".htaccess.";
240
- if($err){
241
- $msg .= " The error was: " . $err['message'];
242
- }
243
- return $msg;
244
- }
245
- return false;
246
- }
247
-
248
- public static function removeCacheDirectoryHtaccess() {
249
$cacheDir = WP_CONTENT_DIR . '/wfcache/';
250
if (file_exists($cacheDir . '.htaccess')) {
251
unlink($cacheDir . '.htaccess');
252
}
253
- }
254
-
255
- public static function action_publishPost($id){
256
- $perm = get_permalink($id);
257
- self::deleteFileFromPermalink($perm);
258
- self::scheduleCacheClear();
259
- }
260
- public static function action_commentPost($commentID){
261
- $c = get_comment($commentID, ARRAY_A);
262
- $perm = get_permalink($c['comment_post_ID']);
263
- self::deleteFileFromPermalink($perm);
264
- self::scheduleCacheClear();
265
- }
266
- public static function action_clearPageCache(){ //Can safely call this as many times as we like because it'll only schedule one clear
267
- self::scheduleCacheClear();
268
- }
269
- public static function scheduleCacheClear(){
270
- if(self::$clearScheduledThisRequest){ return; }
271
- self::$clearScheduledThisRequest = true;
272
- wp_schedule_single_event(time() - 15, 'wordfence_cache_clear', array( rand(0,999999999) )); //rand makes sure this is called every time and isn't subject to the 10 minute window where the same event won't be run twice with wp_schedule_single_event
273
- $url = admin_url('admin-ajax.php');
274
- wp_remote_get($url);
275
- }
276
- public static function scheduledCacheClear($random){
277
- self::clearPageCacheSafe(); //Will only run if clearPageCache() has not run this request
278
- }
279
- public static function deleteFileFromPermalink($perm){
280
- if(preg_match('/\/\/([^\/]+)(\/.*)#x2F;', $perm, $matches)){
281
- $host = $matches[1];
282
- $uri = $matches[2];
283
- $file = self::fileFromRequest($host, $uri);
284
- if(is_file($file)){
285
- @unlink($file);
286
- }
287
- }
288
- }
289
- public static function getCacheStats(){
290
- self::$cacheStats = array(
291
- 'files' => 0,
292
- 'dirs' => 0,
293
- 'data' => 0,
294
- 'compressedFiles' => 0,
295
- 'compressedKBytes' => 0,
296
- 'uncompressedFiles' => 0,
297
- 'uncompressedKBytes' => 0,
298
- 'oldestFile' => false,
299
- 'newestFile' => false,
300
- 'largestFile' => 0,
301
- );
302
- self::recursiveStats(WP_CONTENT_DIR . '/wfcache/');
303
- return self::$cacheStats;
304
- }
305
- private static function recursiveStats($dir){
306
- $files = array_diff(scandir($dir), array('.','..'));
307
- foreach($files as $file){
308
- $fullPath = $dir . '/' . $file;
309
- if(is_dir($fullPath)){
310
- self::$cacheStats['dirs']++;
311
- self::recursiveStats($fullPath);
312
- } else {
313
- if($file == 'clear.lock'){ continue; }
314
- self::$cacheStats['files']++;
315
- $stat = stat($fullPath);
316
- if(is_array($stat)){
317
- $size = $stat[7];
318
- if($size){
319
- $size = round($size / 1024);
320
- self::$cacheStats['data'] += $size;
321
- if(strrpos($file, '_gzip') == strlen($file) - 6){
322
- self::$cacheStats['compressedFiles']++;
323
- self::$cacheStats['compressedKBytes'] += $size;
324
- } else {
325
- self::$cacheStats['uncompressedFiles']++;
326
- self::$cacheStats['uncompressedKBytes'] += $size;
327
- }
328
- if(self::$cacheStats['largestFile'] < $size){
329
- self::$cacheStats['largestFile'] = $size;
330
- }
331
- }
332
-
333
- $ctime = $stat[10];
334
- if(self::$cacheStats['oldestFile'] > $ctime || self::$cacheStats['oldestFile'] === false){
335
- self::$cacheStats['oldestFile'] = $ctime;
336
- }
337
- if(self::$cacheStats['newestFile'] === false || self::$cacheStats['newestFile'] < $ctime){
338
- self::$cacheStats['newestFile'] = $ctime;
339
- }
340
- }
341
- }
342
- }
343
}
344
public static function clearPageCacheSafe(){
345
if(self::$cacheClearedThisRequest){ return; }
@@ -354,6 +37,12 @@ class wfCache {
354
'totalErrors' => 0,
355
'error' => '',
356
);
357
$cacheClearLock = WP_CONTENT_DIR . '/wfcache/clear.lock';
358
if(! is_file($cacheClearLock)){
359
if(! touch($cacheClearLock)){
@@ -378,12 +67,14 @@ class wfCache {
378
self::$cacheStats['totalErrors']++;
379
}
380
flock($fp, LOCK_UN);
381
}
382
fclose($fp);
383
384
return self::$cacheStats;
385
}
386
- public static function recursiveDelete($dir){
387
$files = array_diff(scandir($dir), array('.','..'));
388
foreach ($files as $file) {
389
if(is_dir($dir . '/' . $file)){
@@ -429,8 +120,8 @@ class wfCache {
429
}
430
}
431
public static function addHtaccessCode($action){
432
- if($action != 'add' && $action != 'remove'){
433
- die("Error: addHtaccessCode must be called with 'add' or 'remove' as param");
434
}
435
$htaccessPath = self::getHtaccessPath();
436
if(! $htaccessPath){
@@ -450,10 +141,6 @@ class wfCache {
450
return "Could not read from $htaccessPath";
451
}
452
$contents = preg_replace('/#WFCACHECODE.*WFCACHECODE[\r\s\n\t]*/s', '', $contents);
453
- if($action == 'add'){
454
- $code = self::getHtaccessCode();
455
- $contents = $code . "\n" . $contents;
456
- }
457
ftruncate($fh, 0);
458
fflush($fh);
459
fseek($fh, 0, SEEK_SET);
@@ -462,131 +149,12 @@ class wfCache {
462
fclose($fh);
463
return false;
464
}
465
- public static function getHtaccessCode(){
466
- $siteURL = site_url();
467
- $homeURL = home_url();
468
- $pathPrefix = "";
469
- if(preg_match('/^https?:\/\/[^\/]+\/(.+)#x2F;i', $siteURL, $matches)){
470
- $path = $matches[1];
471
- $path = preg_replace('/^\//', '', $path);
472
- $path = preg_replace('/\/#x2F;', '', $path);
473
- $pathPrefix = '/' . $path; // Which is: /my/path
474
- }
475
- $matchCaps = '$1/$2~$3~$4~$5~$6';
476
- if(preg_match('/^https?:\/\/[^\/]+\/(.+)#x2F;i', $homeURL, $matches)){
477
- $path = $matches[1];
478
- $path = preg_replace('/^\//', '', $path);
479
- $path = preg_replace('/\/#x2F;', '', $path);
480
- $pieces = explode('/', $path);
481
- if(count($pieces) == 1){
482
- # No path: "/wp-content/wfcache/%{HTTP_HOST}_$1/$2~$3~$4~$5~$6_wfcache%{ENV:WRDFNC_HTTPS}.html%{ENV:WRDFNC_ENC}" [L]
483
- # One path: "/mdm/wp-content/wfcache/%{HTTP_HOST}_mdm/$1~$2~$3~$4~$5_wfcache%{ENV:WRDFNC_HTTPS}.html%{ENV:WRDFNC_ENC}" [L]
484
- $matchCaps = $pieces[0] . '/$1~$2~$3~$4~$5';
485
- } else if(count($pieces) == 2){
486
- $matchCaps = $pieces[0] . '/' . $pieces[1] . '/$1~$2~$3~$4';
487
- } else {
488
- $matchCaps = '$1/$2~$3~$4~$5~$6'; #defaults to the regular setting but this won't work. However user should already have gotten a warning that we don't support sites more than 2 dirs deep with falcon.
489
- }
490
- }
491
- $sslString = "RewriteCond %{HTTPS} off";
492
- if(wfConfig::get('allowHTTPSCaching')){
493
- $sslString = "";
494
- }
495
- $otherRewriteConds = "";
496
- $ex = wfConfig::get('cacheExclusions', false);
497
- if($ex){
498
- $ex = unserialize($ex);
499
- foreach($ex as $v){
500
- if($v['pt'] == 'uac'){
501
- $otherRewriteConds .= "\n\tRewriteCond %{HTTP_USER_AGENT} !" . self::regexSpaceFix(preg_quote($v['p'])) . " [NC]";
502
- }
503
- if($v['pt'] == 'uaeq'){
504
- $otherRewriteConds .= "\n\tRewriteCond %{HTTP_USER_AGENT} !^" . self::regexSpaceFix(preg_quote($v['p'])) . "$ [NC]";
505
- }
506
- if($v['pt'] == 'cc'){
507
- $otherRewriteConds .= "\n\tRewriteCond %{HTTP_COOKIE} !" . self::regexSpaceFix(preg_quote($v['p'])) . " [NC]";
508
- }
509
- }
510
- }
511
-
512
- //We exclude URLs that are banned so that Wordfence PHP code can catch the IP address, then ban that IP and the ban is added to .htaccess.
513
- $excludedURLs = "";
514
- if(wfConfig::get('bannedURLs', false)){
515
- foreach(explode(',', wfConfig::get('bannedURLs', false)) as $URL){
516
- $excludedURLs .= "RewriteCond %{REQUEST_URI} !" . wfUtils::patternToRegex($URL, '', '') . "\n\t";
517
- }
518
- }
519
-
520
- $code = <<<EOT
521
- #WFCACHECODE - Do not remove this line. Disable Web Caching in Wordfence to remove this data.
522
- <IfModule mod_deflate.c>
523
- AddOutputFilterByType DEFLATE text/css text/x-component application/x-javascript application/javascript text/javascript text/x-js text/html text/richtext image/svg+xml text/plain text/xsd text/xsl text/xml image/x-icon application/json
524
- <IfModule mod_headers.c>
525
- Header append Vary User-Agent env=!dont-vary
526
- </IfModule>
527
- <IfModule mod_mime.c>
528
- AddOutputFilter DEFLATE js css htm html xml
529
- </IfModule>
530
- </IfModule>
531
- <IfModule mod_mime.c>
532
- AddType text/html .html_gzip
533
- AddEncoding gzip .html_gzip
534
- AddType text/xml .xml_gzip
535
- AddEncoding gzip .xml_gzip
536
- </IfModule>
537
- <IfModule mod_setenvif.c>
538
- SetEnvIfNoCase Request_URI \.html_gzip$ no-gzip
539
- SetEnvIfNoCase Request_URI \.xml_gzip$ no-gzip
540
- </IfModule>
541
- <IfModule mod_headers.c>
542
- Header set Vary "Accept-Encoding, Cookie"
543
- </IfModule>
544
- <IfModule mod_rewrite.c>
545
- #Prevents garbled chars in cached files if there is no default charset.
546
- AddDefaultCharset utf-8
547
-
548
- #Cache rules:
549
- RewriteEngine On
550
- RewriteBase /
551
- RewriteCond %{HTTPS} on
552
- RewriteRule .* - [E=WRDFNC_HTTPS:_https]
553
- RewriteCond %{HTTP:Accept-Encoding} gzip
554
- RewriteRule .* - [E=WRDFNC_ENC:_gzip]
555
- RewriteCond %{REQUEST_METHOD} !=POST
556
- {$sslString}
557
- RewriteCond %{QUERY_STRING} ^(?:\d+=\d+)?$
558
- RewriteCond %{REQUEST_URI} (?:\/|\.html)$ [NC]
559
- {$excludedURLs}
560
- RewriteCond %{HTTP_COOKIE} !(comment_author|wp\-postpass|wf_logout|wordpress_logged_in|wptouch_switch_toggle|wpmp_switcher) [NC]
561
- {$otherRewriteConds}
562
- RewriteCond %{REQUEST_URI} \/*([^\/]*)\/*([^\/]*)\/*([^\/]*)\/*([^\/]*)\/*([^\/]*)(.*)$
563
- RewriteCond "%{DOCUMENT_ROOT}{$pathPrefix}/wp-content/wfcache/%{HTTP_HOST}_%1/%2~%3~%4~%5~%6_wfcache%{ENV:WRDFNC_HTTPS}.html%{ENV:WRDFNC_ENC}" -f
564
- RewriteRule \/*([^\/]*)\/*([^\/]*)\/*([^\/]*)\/*([^\/]*)\/*([^\/]*)(.*)$ "{$pathPrefix}/wp-content/wfcache/%{HTTP_HOST}_{$matchCaps}_wfcache%{ENV:WRDFNC_HTTPS}.html%{ENV:WRDFNC_ENC}" [L]
565
- </IfModule>
566
- #Do not remove this line. Disable Web caching in Wordfence to remove this data - WFCACHECODE
567
- EOT;
568
- return $code;
569
- }
570
- private static function regexSpaceFix($str){
571
- return str_replace(' ', '\\s', $str);
572
- }
573
- public static function scheduleUpdateBlockedIPs(){
574
- wp_clear_scheduled_hook('wordfence_update_blocked_IPs');
575
- if(wfConfig::get('cacheType') != 'falcon'){
576
- self::updateBlockedIPs('remove'); //Fail silently if .htaccess is not readable. Will fall back to old blocking via WP
577
- return;
578
- }
579
- self::updateBlockedIPs('add'); //Fail silently if .htaccess is not readable. Will fall back to old blocking via WP
580
- wp_schedule_single_event(time() + 300, 'wordfence_update_blocked_IPs');
581
- }
582
583
/**
584
* @param $action
585
* @return bool|string|void
586
*/
587
public static function updateBlockedIPs($action){ //'add' or 'remove'
588
- if(wfConfig::get('cacheType') != 'falcon'){ return; }
589
-
590
$htaccessPath = self::getHtaccessPath();
591
if(! $htaccessPath){
592
return "Wordfence could not find your .htaccess file.";
@@ -615,101 +183,7 @@ EOT;
615
flock($fh, LOCK_UN);
616
fclose($fh);
617
return false;
618
- } else if($action == 'add'){
619
- $fh = @fopen($htaccessPath, 'r+');
620
- if(! $fh){
621
- $err = error_get_last();
622
- return $err['message'];
623
- }
624
-
625
- $lines = array();
626
- $wfLog = new wfLog(wfConfig::get('apiKey'), wfUtils::getWPVersion());
627
- $IPs = $wfLog->getBlockedIPsAddrOnly();
628
- if(sizeof($IPs) > 0){
629
- foreach($IPs as $IP){
630
- $lines[] = "Deny from $IP\n";
631
- }
632
- }
633
- $ranges = $wfLog->getRangesBasic();
634
- $browserAdded = false;
635
- $browserLines = array();
636
- if($ranges){
637
- foreach($ranges as $r){
638
- $arr = explode('|', $r);
639
- $range = isset($arr[0]) ? $arr[0] : false;
640
- $browser = isset($arr[1]) ? $arr[1] : false;
641
- $referer = isset($arr[2]) ? $arr[2] : false;
642
-
643
- if($range){
644
- if($browser || $referer){ continue; } //We don't allow combos in falcon
645
-
646
- list($start_range, $end_range) = explode('-', $range);
647
- if (preg_match('/[\.:]/', $start_range)) {
648
- $start_range = wfUtils::inet_pton($start_range);
649
- $end_range = wfUtils::inet_pton($end_range);
650
- } else {
651
- $start_range = wfUtils::inet_pton(long2ip($start_range));
652
- $end_range = wfUtils::inet_pton(long2ip($end_range));
653
- }
654
-
655
- $cidrs = wfUtils::rangeToCIDRs($start_range, $end_range);
656
-
657
- $hIPs = wfUtils::inet_ntop($start_range) . ' - ' . wfUtils::inet_ntop($end_range);
658
- if(sizeof($cidrs) > 0){
659
- $lines[] = '#Start of blocking code for IP range: ' . $hIPs . "\n";
660
- foreach($cidrs as $c){
661
- $lines[] = "Deny from $c\n";
662
- }
663
- $lines[] = '#End of blocking code for IP range: ' . $hIPs . "\n";
664
- }
665
- } else if($browser){
666
- if($range || $referer){ continue; }
667
- $browserLines[] = "\t#Blocking code for browser pattern: $browser\n";
668
- $browser = preg_replace('/([\-\_\.\+\!\@\#\$\%\^\&\(\)\[\]\{\}\/])/', "\\\\$1", $browser);
669
- $browser = preg_replace('/\*/', '.*', $browser);
670
- $browserLines[] = "\tSetEnvIf User-Agent \"" . $browser . "\" WordfenceBadBrowser=1\n";
671
- $browserAdded = true;
672
- } else if($referer){
673
- if($browser || $range){ continue; }
674
- $browserLines[] = "\t#Blocking code for referer pattern: $referer\n";
675
- $referer = preg_replace('/([\-\_\.\+\!\@\#\$\%\^\&\(\)\[\]\{\}\/])/', "\\\\$1", $referer);
676
- $referer = preg_replace('/\*/', '.*', $referer);
677
- $browserLines[] = "\tSetEnvIf Referer \"" . $referer . "\" WordfenceBadBrowser=1\n";
678
- $browserAdded = true;
679
- }
680
- }
681
- }
682
- if($browserAdded){
683
- $lines[] = "<IfModule mod_setenvif.c>\n";
684
- foreach($browserLines as $l){
685
- $lines[] = $l;
686
- }
687
- $lines[] = "\tDeny from env=WordfenceBadBrowser\n";
688
- $lines[] = "</IfModule>\n";
689
- }
690
}
691
- $blockCode = "#WFIPBLOCKS - Do not remove this line. Disable Web Caching in Wordfence to remove this data.\nOrder Deny,Allow\n";
692
- $blockCode .= implode('', $lines);
693
- $blockCode .= "#Do not remove this line. Disable Web Caching in Wordfence to remove this data - WFIPBLOCKS\n";
694
-
695
-
696
- //Minimize time between lock/unlock
697
- flock($fh, LOCK_EX);
698
- fseek($fh, 0, SEEK_SET); //start of file
699
- clearstatcache(); //Or we get the wrong size from a cached entry and corrupt the file
700
- $contents = @fread($fh, filesize($htaccessPath));
701
- if(! $contents){
702
- fclose($fh);
703
- return "Could not read from $htaccessPath";
704
- }
705
- $contents = preg_replace('/#WFIPBLOCKS.*WFIPBLOCKS[\r\s\n\t]*/s', '', $contents);
706
- $contents = $blockCode . $contents;
707
- ftruncate($fh, 0);
708
- fflush($fh);
709
- fseek($fh, 0, SEEK_SET);
710
- @fwrite($fh, $contents);
711
- flock($fh, LOCK_UN);
712
- fclose($fh);
713
return false;
714
}
715
public static function getHtaccessPath(){
1
<?php
2
class wfCache {
3
private static $cacheStats = array();
4
private static $cacheClearedThisRequest = false;
5
private static $lastRecursiveDeleteError = false;
6
+
7
+ public static function removeCaching() {
8
+ $cacheType = wfConfig::get('cacheType', false);
9
+ if ($cacheType === 'disabled') {
10
+ return;
11
+ }
12
+
13
+ if ($cacheType == 'falcon') {
14
+ self::addHtaccessCode('remove');
15
+ self::updateBlockedIPs('remove');
16
+ }
17
+
18
+ wfConfig::set('cacheType', 'disabled');
19
+
20
$cacheDir = WP_CONTENT_DIR . '/wfcache/';
21
if (file_exists($cacheDir . '.htaccess')) {
22
unlink($cacheDir . '.htaccess');
23
}
24
+
25
+ self::clearPageCacheSafe();
26
}
27
public static function clearPageCacheSafe(){
28
if(self::$cacheClearedThisRequest){ return; }
37
'totalErrors' => 0,
38
'error' => '',
39
);
40
+
41
+ $cacheDir = WP_CONTENT_DIR . '/wfcache/';
42
+ if (!file_exists($cacheDir)) {
43
+ return self::$cacheStats;
44
+ }
45
+
46
$cacheClearLock = WP_CONTENT_DIR . '/wfcache/clear.lock';
47
if(! is_file($cacheClearLock)){
48
if(! touch($cacheClearLock)){
67
self::$cacheStats['totalErrors']++;
68
}
69
flock($fp, LOCK_UN);
70
+ @unlink($cacheClearLock);
71
+ @rmdir($cacheDir);
72
}
73
fclose($fp);
74
75
return self::$cacheStats;
76
}
77
+ private static function recursiveDelete($dir) {
78
$files = array_diff(scandir($dir), array('.','..'));
79
foreach ($files as $file) {
80
if(is_dir($dir . '/' . $file)){
120
}
121
}
122
public static function addHtaccessCode($action){
123
+ if($action != 'remove'){
124
+ die("Error: addHtaccessCode must be called with 'remove' as param");
125
}
126
$htaccessPath = self::getHtaccessPath();
127
if(! $htaccessPath){
141
return "Could not read from $htaccessPath";
142
}
143
$contents = preg_replace('/#WFCACHECODE.*WFCACHECODE[\r\s\n\t]*/s', '', $contents);
144
ftruncate($fh, 0);
145
fflush($fh);
146
fseek($fh, 0, SEEK_SET);
149
fclose($fh);
150
return false;
151
}
152
153
/**
154
* @param $action
155
* @return bool|string|void
156
*/
157
public static function updateBlockedIPs($action){ //'add' or 'remove'
158
$htaccessPath = self::getHtaccessPath();
159
if(! $htaccessPath){
160
return "Wordfence could not find your .htaccess file.";
183
flock($fh, LOCK_UN);
184
fclose($fh);
185
return false;
186
}
187
return false;
188
}
189
public static function getHtaccessPath(){
lib/wfConfig.php CHANGED
@@ -115,14 +115,14 @@ class wfConfig {
115
'maxScanHits_action' => "throttle",
116
'blockedTime' => "300",
117
'email_summary_interval' => 'weekly',
118
- 'email_summary_excluded_directories' => 'wp-content/cache,wp-content/wfcache,wp-content/plugins/wordfence/tmp',
119
'allowed404s' => "/favicon.ico\n/apple-touch-icon*.png\n/*@2x.png\n/browserconfig.xml",
120
'wafAlertWhitelist' => '',
121
'wafAlertInterval' => 600,
122
'wafAlertThreshold' => 100,
123
)
124
);
125
- public static $serializedOptions = array('lastAdminLogin', 'scanSched', 'emailedIssuesList', 'wf_summaryItems', 'adminUserList', 'twoFactorUsers', 'alertFreqTrack', 'wfStatusStartMsgs');
126
public static function setDefaults() {
127
foreach (self::$defaultConfig['checkboxes'] as $key => $config) {
128
$val = $config['value'];
@@ -617,8 +617,7 @@ class wfConfig {
617
}
618
}
619
public static function liveTrafficEnabled(){
620
- if( (! self::get('liveTrafficEnabled')) || self::get('cacheType') == 'falcon' || self::get('cacheType') == 'php'){ return false; }
621
- return true;
622
}
623
public static function enableAutoUpdate(){
624
wfConfig::set('autoUpdate', '1');
115
'maxScanHits_action' => "throttle",
116
'blockedTime' => "300",
117
'email_summary_interval' => 'weekly',
118
+ 'email_summary_excluded_directories' => 'wp-content/cache,wp-content/plugins/wordfence/tmp',
119
'allowed404s' => "/favicon.ico\n/apple-touch-icon*.png\n/*@2x.png\n/browserconfig.xml",
120
'wafAlertWhitelist' => '',
121
'wafAlertInterval' => 600,
122
'wafAlertThreshold' => 100,
123
)
124
);
125
+ public static $serializedOptions = array('lastAdminLogin', 'scanSched', 'emailedIssuesList', 'wf_summaryItems', 'adminUserList', 'twoFactorUsers', 'alertFreqTrack', 'wfStatusStartMsgs', 'vulnerabilities_plugin', 'vulnerabilities_theme');
126
public static function setDefaults() {
127
foreach (self::$defaultConfig['checkboxes'] as $key => $config) {
128
$val = $config['value'];
617
}
618
}
619
public static function liveTrafficEnabled(){
620
+ return self::get('liveTrafficEnabled');
621
}
622
public static function enableAutoUpdate(){
623
wfConfig::set('autoUpdate', '1');
lib/wfDiagnostic.php CHANGED
@@ -51,11 +51,15 @@ class wfDiagnostic
51
'Filesystem' => array(
52
'isTmpReadable' => 'Checking if web server can read from <code>~/plugins/wordfence/tmp</code>',
53
'isTmpWritable' => 'Checking if web server can write to <code>~/plugins/wordfence/tmp</code>',
54
- 'testWfCache' => 'Checking if web server can write to <code>~/wp-content/wfcache</code>',
55
),
56
'MySQL' => array(
57
'userCanDelete' => 'Checking if MySQL user has <code>DELETE</code> privilege',
58
'userCanInsert' => 'Checking if MySQL user has <code>INSERT</code> privilege',
59
'userCanSelect' => 'Checking if MySQL user has <code>SELECT</code> privilege',
60
'userCanCreate' => 'Checking if MySQL user has <code>CREATE TABLE</code> privilege',
61
'userCanAlter' => 'Checking if MySQL user has <code>ALTER TABLE</code> privilege',
@@ -116,13 +120,9 @@ class wfDiagnostic
116
public function userCanInsert() {
117
return wfGrant::get()->insert;
118
}
119
-
120
- public function testWfCache() {
121
- $result = wfCache::cacheDirectoryTest();
122
- return array(
123
- 'test' => $result === false,
124
- 'message' => is_string($result) ? $result : 'OK'
125
- );
126
}
127
128
public function userCanDelete() {
@@ -156,6 +156,31 @@ class wfDiagnostic
156
'message' => phpversion(),
157
);
158
}
159
160
public function processOwner() {
161
$disabledFunctions = explode(',', ini_get('disable_functions'));
51
'Filesystem' => array(
52
'isTmpReadable' => 'Checking if web server can read from <code>~/plugins/wordfence/tmp</code>',
53
'isTmpWritable' => 'Checking if web server can write to <code>~/plugins/wordfence/tmp</code>',
54
+ ),
55
+ 'Config' => array(
56
+ 'configWritableSet' => 'Checking basic config reading/writing',
57
+ 'configWritableSetSer' => 'Checking serialized config reading/writing',
58
),
59
'MySQL' => array(
60
'userCanDelete' => 'Checking if MySQL user has <code>DELETE</code> privilege',
61
'userCanInsert' => 'Checking if MySQL user has <code>INSERT</code> privilege',
62
+ 'userCanUpdate' => 'Checking if MySQL user has <code>UPDATE</code> privilege',
63
'userCanSelect' => 'Checking if MySQL user has <code>SELECT</code> privilege',
64
'userCanCreate' => 'Checking if MySQL user has <code>CREATE TABLE</code> privilege',
65
'userCanAlter' => 'Checking if MySQL user has <code>ALTER TABLE</code> privilege',
120
public function userCanInsert() {
121
return wfGrant::get()->insert;
122
}
123
+
124
+ public function userCanUpdate() {
125
+ return wfGrant::get()->update;
126
}
127
128
public function userCanDelete() {
156
'message' => phpversion(),
157
);
158
}
159
+
160
+ public function configWritableSet() {
161
+ global $wpdb;
162
+ $show = $wpdb->hide_errors();
163
+ $val = md5(time());
164
+ wfConfig::set('configWritingTest', $val, wfConfig::DONT_AUTOLOAD);
165
+ $testVal = wfConfig::get('configWritingTest');
166
+ $wpdb->show_errors($show);
167
+ return array(
168
+ 'test' => ($val === $testVal),
169
+ 'message' => 'Basic config writing'
170
+ );
171
+ }
172
+ public function configWritableSetSer() {
173
+ global $wpdb;
174
+ $show = $wpdb->hide_errors();
175
+ $val = md5(time());
176
+ wfConfig::set_ser('configWritingTest_ser', array($val), false, wfConfig::DONT_AUTOLOAD);
177
+ $testVal = @array_shift(wfConfig::get_ser('configWritingTest_ser', array(), false));
178
+ $wpdb->show_errors($show);
179
+ return array(
180
+ 'test' => ($val === $testVal),
181
+ 'message' => 'Serialized config writing'
182
+ );
183
+ }
184
185
public function processOwner() {
186
$disabledFunctions = explode(',', ini_get('disable_functions'));
lib/wfIssues.php CHANGED
@@ -185,7 +185,7 @@ class wfIssues {
185
}
186
foreach($ret as $status => &$issueList){
187
for($i = 0; $i < sizeof($issueList); $i++){
188
- if($issueList[$i]['type'] == 'file'){
189
$localFile = $issueList[$i]['data']['file'];
190
if ($localFile != '.htaccess' && $localFile != $userIni) {
191
$localFile = ABSPATH . '/' . preg_replace('/^[\.\/]+/', '', $localFile);
185
}
186
foreach($ret as $status => &$issueList){
187
for($i = 0; $i < sizeof($issueList); $i++){
188
+ if ($issueList[$i]['type'] == 'file' || $issueList[$i]['type'] == 'knownfile') {
189
$localFile = $issueList[$i]['data']['file'];
190
if ($localFile != '.htaccess' && $localFile != $userIni) {
191
$localFile = ABSPATH . '/' . preg_replace('/^[\.\/]+/', '', $localFile);
lib/wfLog.php CHANGED
@@ -311,7 +311,6 @@ class wfLog {
311
312
public function unblockAllIPs(){
313
$this->getDB()->queryWrite("delete from " . $this->blocksTable);
314
- wfCache::updateBlockedIPs('add');
315
316
if (!WFWAF_SUBDIRECTORY_INSTALL && class_exists('wfWAFIPBlocksController')) {
317
wfWAFIPBlocksController::synchronizeConfigSettings();
@@ -326,7 +325,6 @@ class wfLog {
326
}
327
public function unblockIP($IP){
328
$this->getDB()->queryWrite("delete from " . $this->blocksTable . " where IP=%s", wfUtils::inet_pton($IP));
329
- wfCache::updateBlockedIPs('add');
330
331
if (!WFWAF_SUBDIRECTORY_INSTALL && class_exists('wfWAFIPBlocksController')) {
332
wfWAFIPBlocksController::synchronizeConfigSettings();
@@ -334,7 +332,6 @@ class wfLog {
334
}
335
public function unblockRange($id){
336
$this->getDB()->queryWrite("delete from " . $this->ipRangesTable . " where id=%d", $id);
337
- wfCache::updateBlockedIPs('add');
338
339
if (!WFWAF_SUBDIRECTORY_INSTALL && class_exists('wfWAFIPBlocksController')) {
340
wfWAFIPBlocksController::synchronizeConfigSettings();
@@ -351,7 +348,6 @@ class wfLog {
351
public function blockRange($blockType, $range, $reason){
352
$reason = stripslashes($reason);
353
$this->getDB()->queryWrite("insert IGNORE into " . $this->ipRangesTable . " (blockType, blockString, ctime, reason, totalBlocked, lastBlocked) values ('%s', '%s', unix_timestamp(), '%s', 0, 0)", $blockType, $range, $reason);
354
- wfCache::updateBlockedIPs('add');
355
356
if (!WFWAF_SUBDIRECTORY_INSTALL && class_exists('wfWAFIPBlocksController')) {
357
wfWAFIPBlocksController::synchronizeConfigSettings();
@@ -410,7 +406,7 @@ class wfLog {
410
if (! empty($blockDat[3])) {
411
$elem['hostnamePattern'] = $blockDat[3];
412
}
413
- $elem['patternDisabled'] = (wfConfig::get('cacheType') == 'falcon' && $numBlockElements > 1) ? true : false;
414
}
415
return $results;
416
}
@@ -457,7 +453,6 @@ class wfLog {
457
$this->currentRequest->actionDescription = $reason;
458
}
459
460
- wfCache::updateBlockedIPs('add');
461
wfConfig::inc('totalIPsBlocked');
462
463
if (!WFWAF_SUBDIRECTORY_INSTALL && class_exists('wfWAFIPBlocksController')) {
@@ -506,7 +501,7 @@ class wfLog {
506
return false;
507
}
508
}
509
- public function getThrottledIPs(){
510
$results = $this->getDB()->querySelect("select IP, startTime, endTime, timesThrottled, lastReason, unix_timestamp() - startTime as startTimeAgo, unix_timestamp() - endTime as endTimeAgo from " . $this->throttleTable . " order by endTime desc limit 50");
511
foreach($results as &$elem){
512
$elem['startTimeAgo'] = wfUtils::makeTimeAgo($elem['startTimeAgo']);
@@ -518,9 +513,13 @@ class wfLog {
518
}
519
return $results;
520
}
521
- public function getLockedOutIPs(){
522
$lockoutSecs = wfConfig::get('loginSec_lockoutMins') * 60;
523
- $results = $this->getDB()->querySelect("select IP, unix_timestamp() - blockedTime as createdAgo, reason, unix_timestamp() - lastAttempt as lastAttemptAgo, lastAttempt, blockedHits, (blockedTime + %s) - unix_timestamp() as blockedFor from " . $this->lockOutTable . " where blockedTime + %s > unix_timestamp() order by blockedTime desc", $lockoutSecs, $lockoutSecs);
524
foreach($results as &$elem){
525
$elem['lastAttemptAgo'] = $elem['lastAttempt'] ? wfUtils::makeTimeAgo($elem['lastAttemptAgo']) : '';
526
$elem['blockedForAgo'] = wfUtils::makeTimeAgo($elem['blockedFor']);
@@ -539,8 +538,12 @@ class wfLog {
539
}
540
return $ret;
541
}
542
- public function getBlockedIPs(){
543
- $results = $this->getDB()->querySelect("select IP, unix_timestamp() - blockedTime as createdAgo, reason, unix_timestamp() - lastAttempt as lastAttemptAgo, lastAttempt, blockedHits, (blockedTime + %s) - unix_timestamp() as blockedFor, permanent from " . $this->blocksTable . " where (permanent=1 OR (blockedTime + %s > unix_timestamp())) order by blockedTime desc", wfConfig::get('blockedTime'), wfConfig::get('blockedTime'));
544
foreach($results as &$elem){
545
$lastHitAgo = 0;
546
$totalHits = 0;
@@ -573,7 +576,7 @@ class wfLog {
573
}
574
return $results;
575
}
576
- public function getLeechers($type){
577
if($type == 'topScanners'){
578
$table = $this->scanTable;
579
} else if($type == 'topLeechers'){
311
312
public function unblockAllIPs(){
313
$this->getDB()->queryWrite("delete from " . $this->blocksTable);
314
315
if (!WFWAF_SUBDIRECTORY_INSTALL && class_exists('wfWAFIPBlocksController')) {
316
wfWAFIPBlocksController::synchronizeConfigSettings();
325
}
326
public function unblockIP($IP){
327
$this->getDB()->queryWrite("delete from " . $this->blocksTable . " where IP=%s", wfUtils::inet_pton($IP));
328
329
if (!WFWAF_SUBDIRECTORY_INSTALL && class_exists('wfWAFIPBlocksController')) {
330
wfWAFIPBlocksController::synchronizeConfigSettings();
332
}
333
public function unblockRange($id){
334
$this->getDB()->queryWrite("delete from " . $this->ipRangesTable . " where id=%d", $id);
335
336
if (!WFWAF_SUBDIRECTORY_INSTALL && class_exists('wfWAFIPBlocksController')) {
337
wfWAFIPBlocksController::synchronizeConfigSettings();
348
public function blockRange($blockType, $range, $reason){
349
$reason = stripslashes($reason);
350
$this->getDB()->queryWrite("insert IGNORE into " . $this->ipRangesTable . " (blockType, blockString, ctime, reason, totalBlocked, lastBlocked) values ('%s', '%s', unix_timestamp(), '%s', 0, 0)", $blockType, $range, $reason);
351
352
if (!WFWAF_SUBDIRECTORY_INSTALL && class_exists('wfWAFIPBlocksController')) {
353
wfWAFIPBlocksController::synchronizeConfigSettings();
406
if (! empty($blockDat[3])) {
407
$elem['hostnamePattern'] = $blockDat[3];
408
}
409
+ $elem['patternDisabled'] = false;
410
}
411
return $results;
412
}
453
$this->currentRequest->actionDescription = $reason;
454
}
455
456
wfConfig::inc('totalIPsBlocked');
457
458
if (!WFWAF_SUBDIRECTORY_INSTALL && class_exists('wfWAFIPBlocksController')) {
501
return false;
502
}
503
}
504
+ public function getThrottledIPs($offset = 0){
505
$results = $this->getDB()->querySelect("select IP, startTime, endTime, timesThrottled, lastReason, unix_timestamp() - startTime as startTimeAgo, unix_timestamp() - endTime as endTimeAgo from " . $this->throttleTable . " order by endTime desc limit 50");
506
foreach($results as &$elem){
507
$elem['startTimeAgo'] = wfUtils::makeTimeAgo($elem['startTimeAgo']);
513
}
514
return $results;
515
}
516
+ public function getLockedOutIPs($offset = 0, &$total = null){
517
$lockoutSecs = wfConfig::get('loginSec_lockoutMins') * 60;
518
+ $results = $this->getDB()->querySelect("select SQL_CALC_FOUND_ROWS IP, unix_timestamp() - blockedTime as createdAgo, reason, unix_timestamp() - lastAttempt as lastAttemptAgo, lastAttempt, blockedHits, (blockedTime + %s) - unix_timestamp() as blockedFor from " . $this->lockOutTable . " where blockedTime + %s > unix_timestamp() order by blockedTime desc, IP desc LIMIT %d, %d", $lockoutSecs, $lockoutSecs, $offset, WORDFENCE_BLOCKED_IPS_PER_PAGE);
519
+ if ($total !== null) {
520
+ $total = $this->getDB()->querySingle('SELECT FOUND_ROWS()');
521
+ }
522
+
523
foreach($results as &$elem){
524
$elem['lastAttemptAgo'] = $elem['lastAttempt'] ? wfUtils::makeTimeAgo($elem['lastAttemptAgo']) : '';
525
$elem['blockedForAgo'] = wfUtils::makeTimeAgo($elem['blockedFor']);
538
}
539
return $ret;
540
}
541
+ public function getBlockedIPs($offset = 0, &$total = null){
542
+ $results = $this->getDB()->querySelect("select SQL_CALC_FOUND_ROWS IP, unix_timestamp() - blockedTime as createdAgo, reason, unix_timestamp() - lastAttempt as lastAttemptAgo, lastAttempt, blockedHits, (blockedTime + %s) - unix_timestamp() as blockedFor, permanent from " . $this->blocksTable . " where (permanent=1 OR (blockedTime + %s > unix_timestamp())) order by blockedTime desc, IP desc LIMIT %d, %d", wfConfig::get('blockedTime'), wfConfig::get('blockedTime'), $offset, WORDFENCE_BLOCKED_IPS_PER_PAGE);
543
+ if ($total !== null) {
544
+ $total = $this->getDB()->querySingle('SELECT FOUND_ROWS()');
545
+ }
546
+
547
foreach($results as &$elem){
548
$lastHitAgo = 0;
549
$totalHits = 0;
576
}
577
return $results;
578
}
579
+ public function getLeechers($type, $offset = 0){
580
if($type == 'topScanners'){
581
$table = $this->scanTable;
582
} else if($type == 'topLeechers'){
lib/wfRESTAPI.php ADDED
@@ -0,0 +1,13 @@
1
+ <?php
2
+
3
+ class wfWP_REST_Users_Controller extends WP_REST_Users_Controller
4
+ {
5
+ public static function wfGetURLBase() {
6
+ $controller = new wfWP_REST_Users_Controller();
7
+ return rtrim($controller->namespace . '/' . $controller->rest_base, '/');
8
+ }
9
+
10
+ public function _wfGetURLBase() {
11
+ return rtrim($this->namespace, '/' . $this->rest_base, '/');
12
+ }
13
+ }
lib/wfScanEngine.php CHANGED
@@ -369,7 +369,10 @@ class wfScanEngine {
369
$recommendation = wfConfig::get('detectProxyRecommendation', '');
370
}
371
372
- if ($recommendation == 'UNKNOWN' || empty($recommendation)) {
373
$this->addIssue('checkHowGetIPs', 2, 'checkHowGetIPs', 'checkHowGetIPs' . $recommendation . WORDFENCE_VERSION, "Unable to accurately detect IPs", 'Wordfence was unable to validate a test request to your website. This can happen if your website is behind a proxy that does not use one of the standard ways to convey the IP of the request or it is unreachable publicly. IP blocking and live traffic information may not be accurate. <a href="https://docs.wordfence.com/en/Misconfigured_how_get_IPs_notice " target="_blank">Get More Information</a>', array());
374
$haveIssues = true;
375
}
@@ -763,42 +766,47 @@ class wfScanEngine {
763
private function scan_comments_init(){
764
$this->statusIDX['comments'] = wordfence::statusStart('Scanning comments for URLs in Google\'s Safe Browsing List');
765
$this->scanData = array();
766
- $this->scanQueue = array();
767
$this->hoover = new wordfenceURLHoover($this->apiKey, $this->wp_version);
768
$blogsToScan = self::getBlogsToScan('comments');
769
$wfdb = new wfDB();
770
foreach($blogsToScan as $blog){
771
$q1 = $wfdb->querySelect("select comment_ID from " . $blog['table'] . " where comment_approved=1");
772
foreach($q1 as $idRow){
773
- $this->scanQueue[] = array($blog, $idRow['comment_ID']);
774
}
775
}
776
}
777
private function scan_comments_main(){
778
$wfdb = new wfDB();
779
- while($elem = array_shift($this->scanQueue)){
780
- $queueSize = sizeof($this->scanQueue);
781
- if($queueSize > 0 && $queueSize % 1000 == 0){
782
- wordfence::status(2, 'info', "Scanning comments with $queueSize left to scan.");
783
}
784
- $blog = $elem[0];
785
- $commentID = $elem[1];
786
- $row = $wfdb->querySingleRec("select comment_ID, comment_date, comment_type, comment_author, comment_author_url, comment_content from " . $blog['table'] . " where comment_ID=%d", $commentID);
787
- $this->hoover->hoover($blog['blog_id'] . '-' . $row['comment_ID'], $row['comment_author_url'] . ' ' . $row['comment_author'] . ' ' . $row['comment_content']);
788
- $this->scanData[$blog['blog_id'] . '-' . $row['comment_ID']] = array(
789
- 'contentMD5' => md5($row['comment_content'] . $row['comment_author'] . $row['comment_author_url']),
790
- 'author' => $row['comment_author'],
791
- 'type' => ($row['comment_type'] ? $row['comment_type'] : 'comment'),
792
- 'date' => $row['comment_date'],
793
- 'isMultisite' => $blog['isMultisite'],
794
- 'domain' => $blog['domain'],
795