Version Description
- Improvement: Now performing scanning for PHP code in all uploaded files in real-time.
- Improvement: Improved handling of bad characters and IPv6 ranges in Advanced Blocking.
- Improvement: Live traffic and scanning activity now display a paused notice when real-time updates are suspended while in the background.
- Improvement: The file system scan alerts for files flagged by antivirus software with a '.suspected' extension.
- Improvement: New alert option to get notified only when logins are from a new location/device.
- Change: First phase for removing the Falcon cache in place, which will add a notice of its pending removal.
- Fix: Included country flags for Kosovo and Curaao.
- Fix: Fixed the .htaccess directives used to hide files found by the scanner.
- Fix: Dashboard widget shows correct status for failed logins by deleted users.
- Fix: Removed duplicate issues for modified files in the scan results.
- Fix: Suppressed warning from reverse lookup on IPv6 addresses without valid DNS records.
- Fix: Fixed file inclusion error with themes lacking a 404 page.
- Fix: CSS fixes for activity report email.
Download this release
Release Info
Developer | wfryan |
Plugin | Wordfence Security – Firewall & Malware Scan |
Version | 6.2.1 |
Comparing to | |
See all releases |
Code changes from version 6.2.0 to 6.2.1
- css/main.css +113 -0
- images/flags/cw.png +0 -0
- images/flags/xk.png +0 -0
- js/admin.js +103 -28
- js/tourTip.js +8 -0
- lib/menu_activity.php +12 -1
- lib/menu_blockedIPs.php +10 -2
- lib/menu_options.php +25 -1
- lib/menu_scan.php +53 -0
- lib/menu_sitePerf.php +5 -0
- lib/menu_waf.php +3 -2
- lib/wfActivityReport.php +8 -7
- lib/wfCache.php +1 -4
- lib/wfConfig.php +4 -1
- lib/wfLog.php +15 -4
- lib/wfMD5BloomFilter.php +134 -0
- lib/wfScanEngine.php +42 -4
- lib/wfUtils.php +21 -4
- lib/wordfenceClass.php +139 -21
- lib/wordfenceHash.php +30 -6
- readme.txt +22 -14
- vendor/wordfence/wf-waf/src/init.php +1 -1
- vendor/wordfence/wf-waf/src/lib/rules.php +118 -1
- views/reports/activity-report-email-inline.php +2 -2
- views/waf/debug.php +1 -1
- waf/wfWAFUserIPRange.php +6 -4
- wordfence.php +3 -3
css/main.css
CHANGED
@@ -5,6 +5,7 @@
|
|
5 |
margin: 20px 0 0 20px;
|
6 |
}
|
7 |
div.wordfenceLive {
|
|
|
8 |
height: 29px;
|
9 |
white-space: nowrap;
|
10 |
overflow: hidden;
|
@@ -37,6 +38,118 @@ div.wordfenceLive p {
|
|
37 |
font-weight: normal;
|
38 |
display: inline;
|
39 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
40 |
.wordfence-icon32 {
|
41 |
width: 32px;
|
42 |
height: 32px;
|
5 |
margin: 20px 0 0 20px;
|
6 |
}
|
7 |
div.wordfenceLive {
|
8 |
+
position: relative;
|
9 |
height: 29px;
|
10 |
white-space: nowrap;
|
11 |
overflow: hidden;
|
38 |
font-weight: normal;
|
39 |
display: inline;
|
40 |
}
|
41 |
+
div.wordfenceLive .wordfenceLiveActivity::after {
|
42 |
+
position: absolute;
|
43 |
+
z-index: 3000;
|
44 |
+
top: 0;
|
45 |
+
right: 0;
|
46 |
+
width: 0;
|
47 |
+
height: 0;
|
48 |
+
background: rgba(255, 252, 239, 0.9);
|
49 |
+
content: '';
|
50 |
+
opacity: 0;
|
51 |
+
-webkit-transition: opacity 0.5s, width 0.1s, height 0.1s;
|
52 |
+
-webkit-transition-delay: 0s, 0.5s, 0.5s;
|
53 |
+
-moz-transition: opacity 0.5s, width 0.1s 0.5s, height 0.1s 0.5s;
|
54 |
+
-o-transition: opacity 0.5s, width 0.1s 0.5s, height 0.1s 0.5s;
|
55 |
+
transition: opacity 0.5s, width 0.1s 0.5s, height 0.1s 0.5s;
|
56 |
+
}
|
57 |
+
.wordfenceLiveActivityPaused div.wordfenceLive .wordfenceLiveActivity::after {
|
58 |
+
width: 100%;
|
59 |
+
height: 100%;
|
60 |
+
opacity: 1;
|
61 |
+
-webkit-transition: opacity 0.5s;
|
62 |
+
transition: opacity 0.5s;
|
63 |
+
}
|
64 |
+
div.wordfenceLive .wordfenceLiveStateMessage {
|
65 |
+
display: none;
|
66 |
+
position: absolute;
|
67 |
+
z-index: 3001;
|
68 |
+
top: 0;
|
69 |
+
left: 0;
|
70 |
+
width: 100%;
|
71 |
+
height: 100%;
|
72 |
+
text-align: center;
|
73 |
+
padding: 3px;
|
74 |
+
font-weight: normal;
|
75 |
+
line-height: 29px;
|
76 |
+
color: #666666;
|
77 |
+
opacity: 0;
|
78 |
+
-webkit-transition: opacity 0.5s, width 0.1s, height 0.1s;
|
79 |
+
-webkit-transition-delay: 0s, 0.5s, 0.5s;
|
80 |
+
-moz-transition: opacity 0.5s, width 0.1s 0.5s, height 0.1s 0.5s;
|
81 |
+
-o-transition: opacity 0.5s, width 0.1s 0.5s, height 0.1s 0.5s;
|
82 |
+
transition: opacity 0.5s, width 0.1s 0.5s, height 0.1s 0.5s;
|
83 |
+
}
|
84 |
+
div.wordfenceLive .wordfenceLiveStateMessage td {
|
85 |
+
padding: 0px;
|
86 |
+
}
|
87 |
+
.wordfenceLiveActivityPaused div.wordfenceLive .wordfenceLiveStateMessage {
|
88 |
+
opacity: 1;
|
89 |
+
-webkit-transition: opacity 0.5s;
|
90 |
+
transition: opacity 0.5s;
|
91 |
+
display: table;
|
92 |
+
}
|
93 |
+
#wfLiveTrafficOverlayAnchor::after {
|
94 |
+
position: absolute;
|
95 |
+
z-index: 3002;
|
96 |
+
top: 0;
|
97 |
+
right: 0;
|
98 |
+
width: 0;
|
99 |
+
height: 0;
|
100 |
+
background: rgba(241, 241, 241, 0.6);
|
101 |
+
content: '';
|
102 |
+
opacity: 0;
|
103 |
+
-webkit-transition: opacity 0.5s, width 0.1s, height 0.1s;
|
104 |
+
-webkit-transition-delay: 0s, 0.5s, 0.5s;
|
105 |
+
-moz-transition: opacity 0.5s, width 0.1s 0.5s, height 0.1s 0.5s;
|
106 |
+
-o-transition: opacity 0.5s, width 0.1s 0.5s, height 0.1s 0.5s;
|
107 |
+
transition: opacity 0.5s, width 0.1s 0.5s, height 0.1s 0.5s;
|
108 |
+
}
|
109 |
+
.wordfenceLiveActivityPaused #wfLiveTrafficOverlayAnchor::after {
|
110 |
+
width: 100%;
|
111 |
+
height: 100%;
|
112 |
+
opacity: 1;
|
113 |
+
-webkit-transition: opacity 0.5s;
|
114 |
+
transition: opacity 0.5s;
|
115 |
+
}
|
116 |
+
#wfLiveTrafficDisabledMessage {
|
117 |
+
display: none;
|
118 |
+
position: fixed;
|
119 |
+
z-index: 3003;
|
120 |
+
left: 0;
|
121 |
+
width: 100%;
|
122 |
+
top: 50%;
|
123 |
+
transform: translateY(-50%);
|
124 |
+
text-align: center;
|
125 |
+
color: #666666;
|
126 |
+
opacity: 0;
|
127 |
+
-webkit-transition: opacity 0.5s, width 0.1s, height 0.1s;
|
128 |
+
-webkit-transition-delay: 0s, 0.5s, 0.5s;
|
129 |
+
-moz-transition: opacity 0.5s, width 0.1s 0.5s, height 0.1s 0.5s;
|
130 |
+
-o-transition: opacity 0.5s, width 0.1s 0.5s, height 0.1s 0.5s;
|
131 |
+
transition: opacity 0.5s, width 0.1s 0.5s, height 0.1s 0.5s;
|
132 |
+
}
|
133 |
+
#wfLiveTrafficDisabledMessage h2 {
|
134 |
+
background-color: #FFF;
|
135 |
+
overflow: hidden;
|
136 |
+
border: 1px solid #CCC;
|
137 |
+
max-width: 350px;
|
138 |
+
margin: 0 auto;
|
139 |
+
padding: 15px;
|
140 |
+
font-size: 2.0em;
|
141 |
+
}
|
142 |
+
#wfLiveTrafficDisabledMessage h2 small {
|
143 |
+
font-size: 0.5em;
|
144 |
+
font-weight: normal;
|
145 |
+
margin-top: 20px;
|
146 |
+
}
|
147 |
+
.wordfenceLiveActivityPaused #wfLiveTrafficDisabledMessage {
|
148 |
+
display: block;
|
149 |
+
opacity: 1;
|
150 |
+
-webkit-transition: opacity 0.5s;
|
151 |
+
transition: opacity 0.5s;
|
152 |
+
}
|
153 |
.wordfence-icon32 {
|
154 |
width: 32px;
|
155 |
height: 32px;
|
images/flags/cw.png
ADDED
Binary file
|
images/flags/xk.png
ADDED
Binary file
|
js/admin.js
CHANGED
@@ -399,8 +399,14 @@
|
|
399 |
},
|
400 |
updateActivityLog: function() {
|
401 |
if (this.activityLogUpdatePending || !this.windowHasFocus()) {
|
|
|
|
|
|
|
402 |
return;
|
403 |
}
|
|
|
|
|
|
|
404 |
this.activityLogUpdatePending = true;
|
405 |
var self = this;
|
406 |
this.ajax('wordfence_activityLogUpdate', {
|
@@ -578,8 +584,14 @@
|
|
578 |
},
|
579 |
updateTicker: function(forceUpdate) {
|
580 |
if ((!forceUpdate) && (this.tickerUpdatePending || !this.windowHasFocus())) {
|
|
|
|
|
|
|
581 |
return;
|
582 |
}
|
|
|
|
|
|
|
583 |
this.tickerUpdatePending = true;
|
584 |
var self = this;
|
585 |
var alsoGet = '';
|
@@ -875,7 +887,8 @@
|
|
875 |
"sWidth": '400px',
|
876 |
"sType": 'html',
|
877 |
fnRender: function(obj) {
|
878 |
-
var
|
|
|
879 |
return jQuery('#' + tmplName).tmpl(obj.aData).html();
|
880 |
}
|
881 |
}
|
@@ -1543,15 +1556,62 @@
|
|
1543 |
return;
|
1544 |
}
|
1545 |
range = range.replace(/ /g, '');
|
1546 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
1547 |
var ips = range.split('-');
|
1548 |
-
var
|
1549 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1550 |
jQuery('#wfShowRangeTotal').html("<span style=\"color: #F00;\">Invalid. Starting IP is greater than ending IP.</span>");
|
1551 |
return;
|
1552 |
}
|
1553 |
-
|
1554 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
1555 |
jQuery('#wfShowRangeTotal').empty();
|
1556 |
}
|
1557 |
},
|
@@ -1649,6 +1709,7 @@
|
|
1649 |
return;
|
1650 |
}
|
1651 |
ipRange = ipRange.replace(/ /g, '').toLowerCase();
|
|
|
1652 |
if (ipRange) {
|
1653 |
var range = ipRange.split('-'),
|
1654 |
validRange;
|
@@ -2255,33 +2316,42 @@
|
|
2255 |
// Return if 4 bytes, otherwise false.
|
2256 |
return m.length === 4 ? m : false;
|
2257 |
}
|
2258 |
-
r = /^((?:[\da-f]{1,4}(?::|)){0,8})(::)?((?:[\da-f]{1,4}(?::|)){0,8})
|
2259 |
m = a.match(r); // IPv6
|
2260 |
if (m) {
|
2261 |
-
|
2262 |
-
|
2263 |
-
|
2264 |
-
|
2265 |
-
|
2266 |
-
|
2267 |
-
|
2268 |
-
|
2269 |
-
|
2270 |
-
|
2271 |
-
|
2272 |
-
return false; // Invalid IP.
|
2273 |
-
}
|
2274 |
-
m[j][i] = f(m[j][i] >> 8) + f(m[j][i] & 0xFF);
|
2275 |
}
|
2276 |
-
|
|
|
2277 |
}
|
2278 |
-
|
2279 |
-
|
2280 |
-
|
2281 |
-
|
2282 |
-
|
2283 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2284 |
}
|
|
|
|
|
2285 |
}
|
2286 |
return false; // Invalid IP.
|
2287 |
},
|
@@ -2668,6 +2738,11 @@
|
|
2668 |
}
|
2669 |
jQuery(function() {
|
2670 |
wordfenceAdmin.init();
|
|
|
|
|
|
|
|
|
|
|
2671 |
});
|
2672 |
})(jQuery);
|
2673 |
|
399 |
},
|
400 |
updateActivityLog: function() {
|
401 |
if (this.activityLogUpdatePending || !this.windowHasFocus()) {
|
402 |
+
if (!jQuery('body').hasClass('wordfenceLiveActivityPaused') && !this.activityLogUpdatePending) {
|
403 |
+
jQuery('body').addClass('wordfenceLiveActivityPaused');
|
404 |
+
}
|
405 |
return;
|
406 |
}
|
407 |
+
if (jQuery('body').hasClass('wordfenceLiveActivityPaused')) {
|
408 |
+
jQuery('body').removeClass('wordfenceLiveActivityPaused');
|
409 |
+
}
|
410 |
this.activityLogUpdatePending = true;
|
411 |
var self = this;
|
412 |
this.ajax('wordfence_activityLogUpdate', {
|
584 |
},
|
585 |
updateTicker: function(forceUpdate) {
|
586 |
if ((!forceUpdate) && (this.tickerUpdatePending || !this.windowHasFocus())) {
|
587 |
+
if (!jQuery('body').hasClass('wordfenceLiveActivityPaused') && !this.tickerUpdatePending) {
|
588 |
+
jQuery('body').addClass('wordfenceLiveActivityPaused');
|
589 |
+
}
|
590 |
return;
|
591 |
}
|
592 |
+
if (jQuery('body').hasClass('wordfenceLiveActivityPaused')) {
|
593 |
+
jQuery('body').removeClass('wordfenceLiveActivityPaused');
|
594 |
+
}
|
595 |
this.tickerUpdatePending = true;
|
596 |
var self = this;
|
597 |
var alsoGet = '';
|
887 |
"sWidth": '400px',
|
888 |
"sType": 'html',
|
889 |
fnRender: function(obj) {
|
890 |
+
var issueType = (obj.aData.type == 'knownfile' ? 'file' : obj.aData.type);
|
891 |
+
var tmplName = 'issueTmpl_' + issueType;
|
892 |
return jQuery('#' + tmplName).tmpl(obj.aData).html();
|
893 |
}
|
894 |
}
|
1556 |
return;
|
1557 |
}
|
1558 |
range = range.replace(/ /g, '');
|
1559 |
+
range = range.replace(/[\u2013-\u2015]/g, '-'); //Non-hyphen dashes to hyphen
|
1560 |
+
if (range && /^[^\-]+\-[^\-]+$/.test(range)) {
|
1561 |
+
var count = 1;
|
1562 |
+
var countOverflow = false;
|
1563 |
+
var badRange = false;
|
1564 |
+
var badIP = false;
|
1565 |
+
|
1566 |
var ips = range.split('-');
|
1567 |
+
var ip1 = this.inet_pton(ips[0]);
|
1568 |
+
var ip2 = this.inet_pton(ips[1]);
|
1569 |
+
|
1570 |
+
if (ip1 === false || ip2 === false) {
|
1571 |
+
badIP = true;
|
1572 |
+
}
|
1573 |
+
else {
|
1574 |
+
//Both to 16-byte binary strings
|
1575 |
+
var binStart = ("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff" + ip1).slice(-16);
|
1576 |
+
var binEnd = ("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff" + ip2).slice(-16);
|
1577 |
+
|
1578 |
+
for (var i = 0; i < binStart.length; i++) {
|
1579 |
+
var n0 = binStart.charCodeAt(i);
|
1580 |
+
var n1 = binEnd.charCodeAt(i);
|
1581 |
+
|
1582 |
+
if (i < 11 && n1 - n0 > 0) { //Based on Number.MAX_SAFE_INTEGER, which equals 2 ^ 53 - 1. Any of the first 9 bytes and part of the 10th that add to the range will put us over that
|
1583 |
+
countOverflow = true;
|
1584 |
+
break;
|
1585 |
+
}
|
1586 |
+
else if (i < 11 && n1 - n0 < 0) {
|
1587 |
+
badRange = true;
|
1588 |
+
break;
|
1589 |
+
}
|
1590 |
+
|
1591 |
+
count += (n1 - n0) << (8 * (15 - i));
|
1592 |
+
if (count < 1) {
|
1593 |
+
badRange = true;
|
1594 |
+
break;
|
1595 |
+
}
|
1596 |
+
}
|
1597 |
+
}
|
1598 |
+
|
1599 |
+
if (badIP) {
|
1600 |
+
jQuery('#wfShowRangeTotal').html("<span style=\"color: #F00;\">Invalid IP entered.</span>");
|
1601 |
+
return;
|
1602 |
+
}
|
1603 |
+
else if (badRange) {
|
1604 |
jQuery('#wfShowRangeTotal').html("<span style=\"color: #F00;\">Invalid. Starting IP is greater than ending IP.</span>");
|
1605 |
return;
|
1606 |
}
|
1607 |
+
else if (countOverflow) {
|
1608 |
+
jQuery('#wfShowRangeTotal').html("<span style=\"color: #0A0;\">Valid: >281474976710656 addresses in range.</span>");
|
1609 |
+
return;
|
1610 |
+
}
|
1611 |
+
|
1612 |
+
jQuery('#wfShowRangeTotal').html("<span style=\"color: #0A0;\">Valid: " + count + " addresses in range.</span>");
|
1613 |
+
}
|
1614 |
+
else {
|
1615 |
jQuery('#wfShowRangeTotal').empty();
|
1616 |
}
|
1617 |
},
|
1709 |
return;
|
1710 |
}
|
1711 |
ipRange = ipRange.replace(/ /g, '').toLowerCase();
|
1712 |
+
ipRange = ipRange.replace(/[\u2013-\u2015]/g, '-'); //Non-hyphen dashes to hyphen
|
1713 |
if (ipRange) {
|
1714 |
var range = ipRange.split('-'),
|
1715 |
validRange;
|
2316 |
// Return if 4 bytes, otherwise false.
|
2317 |
return m.length === 4 ? m : false;
|
2318 |
}
|
2319 |
+
r = /^((?:[\da-f]{1,4}(?::|)){0,8})(::)?((?:[\da-f]{1,4}(?::|)){0,8})$/i;
|
2320 |
m = a.match(r); // IPv6
|
2321 |
if (m) {
|
2322 |
+
if (a == '::') {
|
2323 |
+
return "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00";
|
2324 |
+
}
|
2325 |
+
|
2326 |
+
var colonCount = a.split(':').length - 1;
|
2327 |
+
var doubleColonPos = a.indexOf('::');
|
2328 |
+
if (doubleColonPos > -1) {
|
2329 |
+
var expansionLength = ((doubleColonPos == 0 || doubleColonPos == a.length - 2) ? 9 : 8) - colonCount;
|
2330 |
+
var expansion = '';
|
2331 |
+
for (i = 0; i < expansionLength; i++) {
|
2332 |
+
expansion += ':0000';
|
|
|
|
|
|
|
2333 |
}
|
2334 |
+
a = a.replace('::', expansion + ':');
|
2335 |
+
a = a.replace(/(?:^\:|\:$)/, '', a);
|
2336 |
}
|
2337 |
+
|
2338 |
+
var ipGroups = a.split(':');
|
2339 |
+
var ipBin = '';
|
2340 |
+
for (i = 0; i < ipGroups.length; i++) {
|
2341 |
+
var group = ipGroups[i];
|
2342 |
+
if (group.length > 4) {
|
2343 |
+
return false;
|
2344 |
+
}
|
2345 |
+
group = ("0000" + group).slice(-4);
|
2346 |
+
var b1 = parseInt(group.slice(0, 2), 16);
|
2347 |
+
var b2 = parseInt(group.slice(-2), 16);
|
2348 |
+
if (isNaN(b1) || isNaN(b2)) {
|
2349 |
+
return false;
|
2350 |
+
}
|
2351 |
+
ipBin += f(b1) + f(b2);
|
2352 |
}
|
2353 |
+
|
2354 |
+
return ipBin.length == 16 ? ipBin : false;
|
2355 |
}
|
2356 |
return false; // Invalid IP.
|
2357 |
},
|
2738 |
}
|
2739 |
jQuery(function() {
|
2740 |
wordfenceAdmin.init();
|
2741 |
+
jQuery(window).on('focus', function() {
|
2742 |
+
if (jQuery('body').hasClass('wordfenceLiveActivityPaused')) {
|
2743 |
+
jQuery('body').removeClass('wordfenceLiveActivityPaused');
|
2744 |
+
}
|
2745 |
+
});
|
2746 |
});
|
2747 |
})(jQuery);
|
2748 |
|
js/tourTip.js
CHANGED
@@ -41,6 +41,14 @@ window['wordfenceExt'] = {
|
|
41 |
function(){ jQuery('#wordfenceSuPHPUpdateWarning').fadeOut(); }
|
42 |
);
|
43 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
44 |
removeFromCache: function(postID){
|
45 |
this.ajax('wordfence_removeFromCache', {
|
46 |
id: postID
|
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 |
removeFromCache: function(postID){
|
53 |
this.ajax('wordfence_removeFromCache', {
|
54 |
id: postID
|
lib/menu_activity.php
CHANGED
@@ -1,3 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
<div class="wrap wordfence">
|
2 |
<?php require('menuHeader.php'); ?>
|
3 |
|
@@ -23,12 +29,17 @@
|
|
23 |
|
24 |
<div class="wordfenceModeElem" id="wordfenceMode_activity"></div>
|
25 |
<div class="wordfenceLive">
|
26 |
-
<table border="0" cellpadding="0" cellspacing="0">
|
27 |
<tr>
|
28 |
<td><h2>Wordfence Live Activity:</h2></td>
|
29 |
<td id="wfLiveStatus"></td>
|
30 |
</tr>
|
31 |
</table>
|
|
|
|
|
|
|
|
|
|
|
32 |
</div>
|
33 |
<div class="wordfenceWrap<?php if (!wfConfig::get('isPaid')) { echo " wordfence-community"; }?>">
|
34 |
<?php
|
1 |
+
<?php if (wfConfig::liveTrafficEnabled()): ?>
|
2 |
+
<div id="wfLiveTrafficOverlayAnchor"></div>
|
3 |
+
<div id="wfLiveTrafficDisabledMessage">
|
4 |
+
<h2>Live Updates Paused<br /><small>Click inside window to resume</small></h2>
|
5 |
+
</div>
|
6 |
+
<?php endif ?>
|
7 |
<div class="wrap wordfence">
|
8 |
<?php require('menuHeader.php'); ?>
|
9 |
|
29 |
|
30 |
<div class="wordfenceModeElem" id="wordfenceMode_activity"></div>
|
31 |
<div class="wordfenceLive">
|
32 |
+
<table border="0" cellpadding="0" cellspacing="0" class="wordfenceLiveActivity">
|
33 |
<tr>
|
34 |
<td><h2>Wordfence Live Activity:</h2></td>
|
35 |
<td id="wfLiveStatus"></td>
|
36 |
</tr>
|
37 |
</table>
|
38 |
+
<table border="0" cellpadding="0" cellspacing="0" class="wordfenceLiveStateMessage">
|
39 |
+
<tr>
|
40 |
+
<td>Live Updates Paused — Click inside window to resume</td>
|
41 |
+
</tr>
|
42 |
+
</table>
|
43 |
</div>
|
44 |
<div class="wordfenceWrap<?php if (!wfConfig::get('isPaid')) { echo " wordfence-community"; }?>">
|
45 |
<?php
|
lib/menu_blockedIPs.php
CHANGED
@@ -3,8 +3,16 @@
|
|
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">
|
7 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
8 |
</table>
|
9 |
</div>
|
10 |
<?php if(! wfConfig::get('firewallEnabled')){ ?><div style="color: #F00; font-weight: bold;">Rate limiting rules and advanced blocking are disabled. You can enable it on the <a href="admin.php?page=WordfenceSecOpt">Wordfence Options page</a> at the top.</div><?php } ?>
|
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">
|
7 |
+
<tr>
|
8 |
+
<td><h2>Wordfence Live Activity:</h2></td>
|
9 |
+
<td id="wfLiveStatus"></td>
|
10 |
+
</tr>
|
11 |
+
</table>
|
12 |
+
<table border="0" cellpadding="0" cellspacing="0" class="wordfenceLiveStateMessage">
|
13 |
+
<tr>
|
14 |
+
<td>Live Updates Paused — Click inside window to resume</td>
|
15 |
+
</tr>
|
16 |
</table>
|
17 |
</div>
|
18 |
<?php if(! wfConfig::get('firewallEnabled')){ ?><div style="color: #F00; font-weight: bold;">Rate limiting rules and advanced blocking are disabled. You can enable it on the <a href="admin.php?page=WordfenceSecOpt">Wordfence Options page</a> at the top.</div><?php } ?>
|
lib/menu_options.php
CHANGED
@@ -9,12 +9,17 @@ $w = new wfConfig();
|
|
9 |
$pageTitle = "Wordfence Options";
|
10 |
include( 'pageTitle.php' ); ?>
|
11 |
<div class="wordfenceLive">
|
12 |
-
<table border="0" cellpadding="0" cellspacing="0">
|
13 |
<tr>
|
14 |
<td><h2>Wordfence Live Activity:</h2></td>
|
15 |
<td id="wfLiveStatus"></td>
|
16 |
</tr>
|
17 |
</table>
|
|
|
|
|
|
|
|
|
|
|
18 |
</div>
|
19 |
<?php
|
20 |
$rightRail = new wfView('marketing/rightrail', array('additionalClasses' => 'wordfenceRightRailOptions'));
|
@@ -297,11 +302,21 @@ $w = new wfConfig();
|
|
297 |
<td><input type="checkbox" id="alertOn_adminLogin" class="wfConfigElem" name="alertOn_adminLogin"
|
298 |
value="1" <?php $w->cb( 'alertOn_adminLogin' ); ?>/></td>
|
299 |
</tr>
|
|
|
|
|
|
|
|
|
|
|
300 |
<tr>
|
301 |
<th>Alert me when a non-admin user signs in</th>
|
302 |
<td><input type="checkbox" id="alertOn_nonAdminLogin" class="wfConfigElem"
|
303 |
name="alertOn_nonAdminLogin" value="1" <?php $w->cb( 'alertOn_nonAdminLogin' ); ?>/></td>
|
304 |
</tr>
|
|
|
|
|
|
|
|
|
|
|
305 |
<tr>
|
306 |
<th>Alert me when there's a large increase in attacks detected on my site</th>
|
307 |
<td><input type="checkbox" id="wafAlertOnAttacks" class="wfConfigElem"
|
@@ -434,6 +449,15 @@ $w = new wfConfig();
|
|
434 |
name="scansEnabled_checkReadableConfig" value="1" <?php $w->cb( 'scansEnabled_checkReadableConfig' ); ?> />
|
435 |
</td>
|
436 |
</tr>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
437 |
<!-- <tr>-->
|
438 |
<!-- <th>Scan for Full Path Disclosure?<a-->
|
439 |
<!-- href="http://docs.wordfence.com/en/Wordfence_options#Scan_for_Full_Path_Disclosure"-->
|
9 |
$pageTitle = "Wordfence Options";
|
10 |
include( 'pageTitle.php' ); ?>
|
11 |
<div class="wordfenceLive">
|
12 |
+
<table border="0" cellpadding="0" cellspacing="0" class="wordfenceLiveActivity">
|
13 |
<tr>
|
14 |
<td><h2>Wordfence Live Activity:</h2></td>
|
15 |
<td id="wfLiveStatus"></td>
|
16 |
</tr>
|
17 |
</table>
|
18 |
+
<table border="0" cellpadding="0" cellspacing="0" class="wordfenceLiveStateMessage">
|
19 |
+
<tr>
|
20 |
+
<td>Live Updates Paused — Click inside window to resume</td>
|
21 |
+
</tr>
|
22 |
+
</table>
|
23 |
</div>
|
24 |
<?php
|
25 |
$rightRail = new wfView('marketing/rightrail', array('additionalClasses' => 'wordfenceRightRailOptions'));
|
302 |
<td><input type="checkbox" id="alertOn_adminLogin" class="wfConfigElem" name="alertOn_adminLogin"
|
303 |
value="1" <?php $w->cb( 'alertOn_adminLogin' ); ?>/></td>
|
304 |
</tr>
|
305 |
+
<tr>
|
306 |
+
<th style="color: #666666;padding-left: 20px;">Only alert me when that administrator signs in from a new device or location</th>
|
307 |
+
<td><input type="checkbox" id="alertOn_firstAdminLoginOnly" class="wfConfigElem" name="alertOn_firstAdminLoginOnly"
|
308 |
+
value="1" <?php $w->cb( 'alertOn_firstAdminLoginOnly' ); ?>/></td>
|
309 |
+
</tr>
|
310 |
<tr>
|
311 |
<th>Alert me when a non-admin user signs in</th>
|
312 |
<td><input type="checkbox" id="alertOn_nonAdminLogin" class="wfConfigElem"
|
313 |
name="alertOn_nonAdminLogin" value="1" <?php $w->cb( 'alertOn_nonAdminLogin' ); ?>/></td>
|
314 |
</tr>
|
315 |
+
<tr>
|
316 |
+
<th style="color: #666666;padding-left: 20px;">Only alert me when that user signs in from a new device or location</th>
|
317 |
+
<td><input type="checkbox" id="alertOn_firstNonAdminLoginOnly" class="wfConfigElem" name="alertOn_firstNonAdminLoginOnly"
|
318 |
+
value="1" <?php $w->cb( 'alertOn_firstNonAdminLoginOnly' ); ?>/></td>
|
319 |
+
</tr>
|
320 |
<tr>
|
321 |
<th>Alert me when there's a large increase in attacks detected on my site</th>
|
322 |
<td><input type="checkbox" id="wafAlertOnAttacks" class="wfConfigElem"
|
449 |
name="scansEnabled_checkReadableConfig" value="1" <?php $w->cb( 'scansEnabled_checkReadableConfig' ); ?> />
|
450 |
</td>
|
451 |
</tr>
|
452 |
+
<tr>
|
453 |
+
<th>Scan for publicly accessible quarantined files<a
|
454 |
+
href="http://docs.wordfence.com/en/Wordfence_options#Scan_for_publicly_accessible_quarantined_files"
|
455 |
+
target="_blank" class="wfhelp"></a></th>
|
456 |
+
<td><input type="checkbox" id="scansEnabled_suspectedFiles" class="wfConfigElem"
|
457 |
+
name="scansEnabled_suspectedFiles"
|
458 |
+
value="1" <?php $w->cb( 'scansEnabled_suspectedFiles' ); ?>/>
|
459 |
+
</td>
|
460 |
+
</tr>
|
461 |
<!-- <tr>-->
|
462 |
<!-- <th>Scan for Full Path Disclosure?<a-->
|
463 |
<!-- href="http://docs.wordfence.com/en/Wordfence_options#Scan_for_Full_Path_Disclosure"-->
|
lib/menu_scan.php
CHANGED
@@ -2,6 +2,10 @@
|
|
2 |
$sigUpdateTime = wfConfig::get('signatureUpdateTime');
|
3 |
?>
|
4 |
<div class="wordfenceModeElem" id="wordfenceMode_scan"></div>
|
|
|
|
|
|
|
|
|
5 |
<div class="wrap wordfence">
|
6 |
|
7 |
<?php
|
@@ -256,6 +260,55 @@ $sigUpdateTime = wfConfig::get('signatureUpdateTime');
|
|
256 |
</div>
|
257 |
</div>
|
258 |
</script>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
259 |
<script type="text/x-jquery-template" id="issueTmpl_wpscan_fullPathDiscl">
|
260 |
<div>
|
261 |
<div class="wfIssue">
|
2 |
$sigUpdateTime = wfConfig::get('signatureUpdateTime');
|
3 |
?>
|
4 |
<div class="wordfenceModeElem" id="wordfenceMode_scan"></div>
|
5 |
+
<div id="wfLiveTrafficOverlayAnchor"></div>
|
6 |
+
<div id="wfLiveTrafficDisabledMessage">
|
7 |
+
<h2>Live Updates Paused<br /><small>Click inside window to resume</small></h2>
|
8 |
+
</div>
|
9 |
<div class="wrap wordfence">
|
10 |
|
11 |
<?php
|
260 |
</div>
|
261 |
</div>
|
262 |
</script>
|
263 |
+
<script type="text/x-jquery-template" id="issueTmpl_publiclyAccessible">
|
264 |
+
<div>
|
265 |
+
<div class="wfIssue">
|
266 |
+
<h2>${shortMsg}</h2>
|
267 |
+
<table border="0" class="wfIssue" cellspacing="0" cellpadding="0">
|
268 |
+
<tr>
|
269 |
+
<th>URL:</th>
|
270 |
+
<td><a href="${data.url}" target="_blank">${data.url}</a></td>
|
271 |
+
<tr>
|
272 |
+
<th>Severity:</th>
|
273 |
+
<td>{{if severity == '1'}}Critical{{else}}Warning{{/if}}</td>
|
274 |
+
</tr>
|
275 |
+
<tr>
|
276 |
+
<th>Status</th>
|
277 |
+
<td>
|
278 |
+
{{if status == 'new' }}New{{/if}}
|
279 |
+
{{if status == 'ignoreP' || status == 'ignoreC' }}Ignored{{/if}}
|
280 |
+
</td>
|
281 |
+
</tr>
|
282 |
+
</table>
|
283 |
+
<p>
|
284 |
+
{{html longMsg}}
|
285 |
+
</p>
|
286 |
+
<div class="wfIssueOptions">
|
287 |
+
<strong>Tools:</strong>
|
288 |
+
{{if data.fileExists}}
|
289 |
+
<a target="_blank" href="${WFAD.makeViewFileLink(data.file)}">View the file</a>
|
290 |
+
{{/if}}
|
291 |
+
<a href="#" onclick="WFAD.hideFile('${id}', 'delete'); return false;">Hide this file in <em>.htaccess</em></a>
|
292 |
+
{{if data.canDelete}}
|
293 |
+
<a href="#" onclick="WFAD.deleteFile('${id}'); return false;">Delete this file (can't be undone).</a>
|
294 |
+
<p>
|
295 |
+
<label><input type="checkbox" class="wfdelCheckbox" value="${id}" /> Select for bulk delete</label>
|
296 |
+
</p>
|
297 |
+
{{/if}}
|
298 |
+
</div>
|
299 |
+
<div class="wfIssueOptions">
|
300 |
+
{{if status == 'new'}}
|
301 |
+
<strong>Resolve:</strong>
|
302 |
+
<a href="#" onclick="WFAD.updateIssueStatus('${id}', 'delete'); return false;">I have fixed this issue</a>
|
303 |
+
<a href="#" onclick="WFAD.updateIssueStatus('${id}', 'ignoreC'); return false;">Ignore this issue</a>
|
304 |
+
{{/if}}
|
305 |
+
{{if status == 'ignoreC' || status == 'ignoreP'}}
|
306 |
+
<a href="#" onclick="WFAD.updateIssueStatus('${id}', 'delete'); return false;">Stop ignoring this issue</a>
|
307 |
+
{{/if}}
|
308 |
+
</div>
|
309 |
+
</div>
|
310 |
+
</div>
|
311 |
+
</script>
|
312 |
<script type="text/x-jquery-template" id="issueTmpl_wpscan_fullPathDiscl">
|
313 |
<div>
|
314 |
<div class="wfIssue">
|
lib/menu_sitePerf.php
CHANGED
@@ -10,6 +10,11 @@ $w = new wfConfig();
|
|
10 |
echo $rightRail;
|
11 |
?>
|
12 |
<div class="wordfenceWrap" style="margin: 20px 20px 20px 30px; max-width: 800px;">
|
|
|
|
|
|
|
|
|
|
|
13 |
<h2>Caching</h2>
|
14 |
<table border="0">
|
15 |
<tr><td>Disable all performance enhancements:</td><td><input type="radio" name="cacheType" id="cacheType_disable" value="disable" <?php if(! wfConfig::get('cacheType')){ echo 'checked="checked"'; } ?> /></td><td>No performance improvement</td></tr>
|
10 |
echo $rightRail;
|
11 |
?>
|
12 |
<div class="wordfenceWrap" style="margin: 20px 20px 20px 30px; max-width: 800px;">
|
13 |
+
<?php if (wfConfig::get('cacheType') == 'php' || wfConfig::get('cacheType') == 'falcon') { ?>
|
14 |
+
<div id="wordfenceFalconDeprecationWarning" class="wf-notice"><p><strong>Support for the Falcon and Basic cache will be removed.</strong> This site currently has the <?php echo (wfConfig::get('cacheType') == 'php' ? 'Basic' : 'Falcon'); ?> cache enabled, and it is scheduled to be removed in an upcoming release. Please investigate other caching options and then manually disable it below. It will be disabled automatically when support is removed. <a href="http://docs.wordfence.com/en/Falcon_Cache" target="_blank">More information.</a></p></div>
|
15 |
+
<?php } else { ?>
|
16 |
+
<div id="wordfenceFalconDeprecationWarning" class="wf-notice"><p><strong>Support for the Falcon and Basic cache will be removed.</strong> It is scheduled to be removed in an upcoming release and should not be enabled. If enabled, it will be disabled automatically when support is removed. <a href="http://docs.wordfence.com/en/Falcon_Cache" target="_blank">More information.</a></p></div>
|
17 |
+
<?php } ?>
|
18 |
<h2>Caching</h2>
|
19 |
<table border="0">
|
20 |
<tr><td>Disable all performance enhancements:</td><td><input type="radio" name="cacheType" id="cacheType_disable" value="disable" <?php if(! wfConfig::get('cacheType')){ echo 'checked="checked"'; } ?> /></td><td>No performance improvement</td></tr>
|
lib/menu_waf.php
CHANGED
@@ -51,6 +51,7 @@ $wafRemoveURL = network_admin_url('admin.php?page=WordfenceWAF&wafAction=removeA
|
|
51 |
<?php echo wp_kses($storageExceptionMessage, 'post') ?>
|
52 |
</div>
|
53 |
<?php elseif (!empty($wafActionContent)): ?>
|
|
|
54 |
<?php echo $wafActionContent ?>
|
55 |
|
56 |
<?php if (!empty($_REQUEST['wafAction']) && $_REQUEST['wafAction'] == 'removeAutoPrepend') { ?>
|
@@ -66,11 +67,11 @@ $wafRemoveURL = network_admin_url('admin.php?page=WordfenceWAF&wafAction=removeA
|
|
66 |
<a target="_blank" href="https://docs.wordfence.com/en/Web_Application_Firewall_Setup">click here for
|
67 |
help</a>.</em></p>
|
68 |
<?php } ?>
|
69 |
-
|
70 |
<?php else: ?>
|
71 |
|
72 |
<?php if (!empty($configExceptionMessage)): ?>
|
73 |
-
<div style="font-weight: bold; margin: 20px 0px
|
74 |
<?php echo wp_kses($configExceptionMessage, 'post') ?>
|
75 |
</div>
|
76 |
<?php endif ?>
|
51 |
<?php echo wp_kses($storageExceptionMessage, 'post') ?>
|
52 |
</div>
|
53 |
<?php elseif (!empty($wafActionContent)): ?>
|
54 |
+
<div style="max-width: 900px;">
|
55 |
<?php echo $wafActionContent ?>
|
56 |
|
57 |
<?php if (!empty($_REQUEST['wafAction']) && $_REQUEST['wafAction'] == 'removeAutoPrepend') { ?>
|
67 |
<a target="_blank" href="https://docs.wordfence.com/en/Web_Application_Firewall_Setup">click here for
|
68 |
help</a>.</em></p>
|
69 |
<?php } ?>
|
70 |
+
</div>
|
71 |
<?php else: ?>
|
72 |
|
73 |
<?php if (!empty($configExceptionMessage)): ?>
|
74 |
+
<div style="font-weight: bold; margin: 20px 0px; max-width: 700px;">
|
75 |
<?php echo wp_kses($configExceptionMessage, 'post') ?>
|
76 |
</div>
|
77 |
<?php endif ?>
|
lib/wfActivityReport.php
CHANGED
@@ -256,13 +256,14 @@ SQL
|
|
256 |
}
|
257 |
|
258 |
$results = $this->db->get_results($this->db->prepare(<<<SQL
|
259 |
-
SELECT
|
260 |
-
sum(fail) as fail_count,
|
261 |
-
|
262 |
-
FROM {$this->db->base_prefix}wfLogins
|
263 |
-
|
264 |
-
|
265 |
-
|
|
|
266 |
ORDER BY fail_count DESC
|
267 |
LIMIT %d
|
268 |
SQL
|
256 |
}
|
257 |
|
258 |
$results = $this->db->get_results($this->db->prepare(<<<SQL
|
259 |
+
SELECT wfl.*,
|
260 |
+
sum(wfl.fail) as fail_count,
|
261 |
+
!ISNULL(wpu.ID) as is_valid_user
|
262 |
+
FROM {$this->db->base_prefix}wfLogins wfl
|
263 |
+
LEFT JOIN {$this->db->base_prefix}users wpu ON wfl.username = wpu.user_login OR wfl.username = wpu.user_email
|
264 |
+
WHERE wfl.fail = 1
|
265 |
+
AND wfl.ctime > $interval
|
266 |
+
GROUP BY wfl.username
|
267 |
ORDER BY fail_count DESC
|
268 |
LIMIT %d
|
269 |
SQL
|
lib/wfCache.php
CHANGED
@@ -719,10 +719,7 @@ EOT;
|
|
719 |
|
720 |
$homePath = get_home_path();
|
721 |
$htaccessFile = $homePath.'.htaccess';
|
722 |
-
|
723 |
-
return $htaccessFile;
|
724 |
-
}
|
725 |
-
return false;
|
726 |
}
|
727 |
public static function doNotCache(){
|
728 |
if(! defined('WFDONOTCACHE')){
|
719 |
|
720 |
$homePath = get_home_path();
|
721 |
$htaccessFile = $homePath.'.htaccess';
|
722 |
+
return $htaccessFile;
|
|
|
|
|
|
|
723 |
}
|
724 |
public static function doNotCache(){
|
725 |
if(! defined('WFDONOTCACHE')){
|
lib/wfConfig.php
CHANGED
@@ -22,7 +22,9 @@ class wfConfig {
|
|
22 |
"alertOn_loginLockout" => array('value' => true, 'autoload' => self::AUTOLOAD),
|
23 |
"alertOn_lostPasswdForm" => array('value' => true, 'autoload' => self::AUTOLOAD),
|
24 |
"alertOn_adminLogin" => array('value' => true, 'autoload' => self::AUTOLOAD),
|
|
|
25 |
"alertOn_nonAdminLogin" => array('value' => false, 'autoload' => self::AUTOLOAD),
|
|
|
26 |
"liveTrafficEnabled" => array('value' => true, 'autoload' => self::AUTOLOAD),
|
27 |
"scansEnabled_checkReadableConfig" => array('value' => true, 'autoload' => self::AUTOLOAD),
|
28 |
"advancedCommentScanning" => array('value' => false, 'autoload' => self::AUTOLOAD),
|
@@ -40,6 +42,7 @@ class wfConfig {
|
|
40 |
"scansEnabled_coreUnknown" => array('value' => true, 'autoload' => self::AUTOLOAD),
|
41 |
"scansEnabled_malware" => array('value' => true, 'autoload' => self::AUTOLOAD),
|
42 |
"scansEnabled_fileContents" => array('value' => true, 'autoload' => self::AUTOLOAD),
|
|
|
43 |
"scansEnabled_posts" => array('value' => true, 'autoload' => self::AUTOLOAD),
|
44 |
"scansEnabled_comments" => array('value' => true, 'autoload' => self::AUTOLOAD),
|
45 |
"scansEnabled_passwds" => array('value' => true, 'autoload' => self::AUTOLOAD),
|
@@ -61,7 +64,7 @@ class wfConfig {
|
|
61 |
"loginSec_blockAdminReg" => array('value' => true, 'autoload' => self::AUTOLOAD),
|
62 |
"loginSec_disableAuthorScan" => array('value' => true, 'autoload' => self::AUTOLOAD),
|
63 |
"loginSec_disableOEmbedAuthor" => array('value' => false, 'autoload' => self::AUTOLOAD),
|
64 |
-
"other_hideWPVersion" => array('value' =>
|
65 |
"other_noAnonMemberComments" => array('value' => true, 'autoload' => self::AUTOLOAD),
|
66 |
"other_blockBadPOST" => array('value' => false, 'autoload' => self::AUTOLOAD),
|
67 |
"other_scanComments" => array('value' => true, 'autoload' => self::AUTOLOAD),
|
22 |
"alertOn_loginLockout" => array('value' => true, 'autoload' => self::AUTOLOAD),
|
23 |
"alertOn_lostPasswdForm" => array('value' => true, 'autoload' => self::AUTOLOAD),
|
24 |
"alertOn_adminLogin" => array('value' => true, 'autoload' => self::AUTOLOAD),
|
25 |
+
"alertOn_firstAdminLoginOnly" => array('value' => false, 'autoload' => self::AUTOLOAD),
|
26 |
"alertOn_nonAdminLogin" => array('value' => false, 'autoload' => self::AUTOLOAD),
|
27 |
+
"alertOn_firstNonAdminLoginOnly" => array('value' => false, 'autoload' => self::AUTOLOAD),
|
28 |
"liveTrafficEnabled" => array('value' => true, 'autoload' => self::AUTOLOAD),
|
29 |
"scansEnabled_checkReadableConfig" => array('value' => true, 'autoload' => self::AUTOLOAD),
|
30 |
"advancedCommentScanning" => array('value' => false, 'autoload' => self::AUTOLOAD),
|
42 |
"scansEnabled_coreUnknown" => array('value' => true, 'autoload' => self::AUTOLOAD),
|
43 |
"scansEnabled_malware" => array('value' => true, 'autoload' => self::AUTOLOAD),
|
44 |
"scansEnabled_fileContents" => array('value' => true, 'autoload' => self::AUTOLOAD),
|
45 |
+
"scansEnabled_suspectedFiles" => array('value' => true, 'autoload' => self::AUTOLOAD),
|
46 |
"scansEnabled_posts" => array('value' => true, 'autoload' => self::AUTOLOAD),
|
47 |
"scansEnabled_comments" => array('value' => true, 'autoload' => self::AUTOLOAD),
|
48 |
"scansEnabled_passwds" => array('value' => true, 'autoload' => self::AUTOLOAD),
|
64 |
"loginSec_blockAdminReg" => array('value' => true, 'autoload' => self::AUTOLOAD),
|
65 |
"loginSec_disableAuthorScan" => array('value' => true, 'autoload' => self::AUTOLOAD),
|
66 |
"loginSec_disableOEmbedAuthor" => array('value' => false, 'autoload' => self::AUTOLOAD),
|
67 |
+
"other_hideWPVersion" => array('value' => false, 'autoload' => self::AUTOLOAD),
|
68 |
"other_noAnonMemberComments" => array('value' => true, 'autoload' => self::AUTOLOAD),
|
69 |
"other_blockBadPOST" => array('value' => false, 'autoload' => self::AUTOLOAD),
|
70 |
"other_scanComments" => array('value' => true, 'autoload' => self::AUTOLOAD),
|
lib/wfLog.php
CHANGED
@@ -153,6 +153,15 @@ class wfLog {
|
|
153 |
return;
|
154 |
}
|
155 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
156 |
// change the action flag here if the user does not exist.
|
157 |
if ($action == 'loginFailValidUsername' && $userID == 0) {
|
158 |
$action = 'loginFailInvalidUsername';
|
@@ -1246,9 +1255,11 @@ class wfUserIPRange {
|
|
1246 |
|
1247 |
// IPv6 range
|
1248 |
} else if (strpos($ip_string, ':') !== false && strpos($ip, ':') !== false) {
|
1249 |
-
|
1250 |
-
|
1251 |
-
|
|
|
|
|
1252 |
$mismatch = false;
|
1253 |
for ($i = 0; $i <= 7; $i++) {
|
1254 |
if (preg_match('/^\[([a-f0-9]+)\-([a-f0-9]+)\]$/i', $whiteParts[$i], $m)) {
|
@@ -1416,7 +1427,7 @@ class wfUserIPRange {
|
|
1416 |
* @param string|null $ip_string
|
1417 |
*/
|
1418 |
public function setIPString($ip_string) {
|
1419 |
-
$this->ip_string = $ip_string;
|
1420 |
}
|
1421 |
}
|
1422 |
|
153 |
return;
|
154 |
}
|
155 |
}
|
156 |
+
else {
|
157 |
+
$user = get_user_by('email', $username);
|
158 |
+
if ($user) {
|
159 |
+
$userID = $user->ID;
|
160 |
+
if (!$userID) {
|
161 |
+
return;
|
162 |
+
}
|
163 |
+
}
|
164 |
+
}
|
165 |
// change the action flag here if the user does not exist.
|
166 |
if ($action == 'loginFailValidUsername' && $userID == 0) {
|
167 |
$action = 'loginFailInvalidUsername';
|
1255 |
|
1256 |
// IPv6 range
|
1257 |
} else if (strpos($ip_string, ':') !== false && strpos($ip, ':') !== false) {
|
1258 |
+
$ip = strtolower(wfUtils::expandIPv6Address($ip));
|
1259 |
+
$ip_string = strtolower(self::expandIPv6Range($ip_string));
|
1260 |
+
if (preg_match('/\[[a-f0-9]+\-[a-f0-9]+\]/i', $ip_string)) {
|
1261 |
+
$IPparts = explode(':', $ip);
|
1262 |
+
$whiteParts = explode(':', $ip_string);
|
1263 |
$mismatch = false;
|
1264 |
for ($i = 0; $i <= 7; $i++) {
|
1265 |
if (preg_match('/^\[([a-f0-9]+)\-([a-f0-9]+)\]$/i', $whiteParts[$i], $m)) {
|
1427 |
* @param string|null $ip_string
|
1428 |
*/
|
1429 |
public function setIPString($ip_string) {
|
1430 |
+
$this->ip_string = preg_replace('/[\x{2013}-\x{2015}]/u', '-', $ip_string); //Replace em-dash, en-dash, and horizontal bar with a regular dash
|
1431 |
}
|
1432 |
}
|
1433 |
|
lib/wfMD5BloomFilter.php
ADDED
@@ -0,0 +1,134 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/*
|
3 |
+
Copyright (c) 2012, Da Xue
|
4 |
+
All rights reserved.
|
5 |
+
|
6 |
+
Redistribution and use in source and binary forms, with or without
|
7 |
+
modification, are permitted provided that the following conditions are met:
|
8 |
+
1. Redistributions of source code must retain the above copyright
|
9 |
+
notice, this list of conditions and the following disclaimer.
|
10 |
+
2. Redistributions in binary form must reproduce the above copyright
|
11 |
+
notice, this list of conditions and the following disclaimer in the
|
12 |
+
documentation and/or other materials provided with the distribution.
|
13 |
+
3. The name of the author nor the names of its contributors may be used
|
14 |
+
to endorse or promote products derived from this software without
|
15 |
+
specific prior written permission.
|
16 |
+
|
17 |
+
THIS SOFTWARE IS PROVIDED BY DA XUE ''AS IS'' AND ANY
|
18 |
+
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
19 |
+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
20 |
+
DISCLAIMED. IN NO EVENT SHALL DA XUE BE LIABLE FOR ANY
|
21 |
+
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
22 |
+
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
23 |
+
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
24 |
+
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
25 |
+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
26 |
+
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
27 |
+
*/
|
28 |
+
|
29 |
+
/* https://github.com/dsx724/php-bloom-filter */
|
30 |
+
|
31 |
+
// Modified for PHP 5.2 compatibility and to support serialization.
|
32 |
+
|
33 |
+
class wfMD5BloomFilter {
|
34 |
+
private static function merge($bf1,$bf2,$bfout,$union = false){
|
35 |
+
if ($bf1->m != $bf2->m) throw new Exception('Unable to merge due to vector difference.');
|
36 |
+
if ($bf1->k != $bf2->k) throw new Exception('Unable to merge due to hash count difference.');
|
37 |
+
$length = strlen($bfout->bit_array);
|
38 |
+
if ($union){
|
39 |
+
$bfout->bit_array = $bf1->bit_array | $bf2->bit_array;
|
40 |
+
$bfout->n = $bf1->n + $bf2->n;
|
41 |
+
} else {
|
42 |
+
$bfout->bit_array = $bf1->bit_array & $bf2->bit_array;
|
43 |
+
$bfout->n = abs($bf1->n - $bf2->n);
|
44 |
+
}
|
45 |
+
}
|
46 |
+
public static function createFromProbability($n, $p){
|
47 |
+
if ($p <= 0 || $p >= 1) throw new Exception('Invalid false positive rate requested.');
|
48 |
+
if ($n <= 0) throw new Exception('Invalid capacity requested.');
|
49 |
+
$k = floor(log(1/$p,2));
|
50 |
+
$m = pow(2,ceil(log(-$n*log($p)/pow(log(2),2),2))); //approximate estimator method
|
51 |
+
return new self($m,$k);
|
52 |
+
}
|
53 |
+
public static function getUnion($bf1,$bf2){
|
54 |
+
$bf = new self($bf1->m,$bf1->k,$bf1->hash);
|
55 |
+
self::merge($bf1,$bf2,$bf,true);
|
56 |
+
return $bf;
|
57 |
+
}
|
58 |
+
public static function getIntersection($bf1,$bf2){
|
59 |
+
$bf = new self($bf1->m,$bf1->k,$bf1->hash);
|
60 |
+
self::merge($bf1,$bf2,$bf,false);
|
61 |
+
return $bf;
|
62 |
+
}
|
63 |
+
private $n = 0; // # of entries
|
64 |
+
private $m; // # of bits in array
|
65 |
+
private $k; // # of hash functions
|
66 |
+
private $k2;
|
67 |
+
private $mask;
|
68 |
+
private $bit_array; // data structure
|
69 |
+
public function __construct($m, $k){
|
70 |
+
if ($m < 8) throw new Exception('The bit array length must be at least 8 bits.');
|
71 |
+
if (($m & ($m - 1)) !== 0) throw new Exception('The bit array length must be power of 2.');
|
72 |
+
if ($m > 65536) throw new Exception('The maximum data structure size is 8KB.');
|
73 |
+
if ($k > 8) throw new Exception('The maximum bits to set is 8.');
|
74 |
+
$this->m = $m;
|
75 |
+
$this->k = $k;
|
76 |
+
$this->k2 = $k * 2;
|
77 |
+
$address_bits = (int)log($m,2);
|
78 |
+
$this->mask = (1 << $address_bits) - 8;
|
79 |
+
$this->bit_array = (binary)(str_repeat("\0",$this->getArraySize(true)));
|
80 |
+
}
|
81 |
+
public function __sleep() {
|
82 |
+
return array('n', 'm', 'k', 'k2', 'mask', 'bit_array');
|
83 |
+
}
|
84 |
+
public function calculateProbability($n = 0){
|
85 |
+
return pow(1-pow(1-1/$this->m,$this->k*($n ? $n : $this->n)),$this->k);
|
86 |
+
}
|
87 |
+
public function calculateCapacity($p){
|
88 |
+
return floor($this->m*log(2)/log($p,1-pow(1-1/$this->m,$this->m*log(2))));
|
89 |
+
}
|
90 |
+
public function getElementCount(){
|
91 |
+
return $this->n;
|
92 |
+
}
|
93 |
+
public function getArraySize($bytes = false){
|
94 |
+
return $this->m >> ($bytes ? 3 : 0);
|
95 |
+
}
|
96 |
+
public function getHashCount(){
|
97 |
+
return $this->k;
|
98 |
+
}
|
99 |
+
public function getInfo($p = null){
|
100 |
+
$units = array('','K','M','G','T','P','E','Z','Y');
|
101 |
+
$M = $this->getArraySize(true);
|
102 |
+
$magnitude = intval(floor(log($M,1024)));
|
103 |
+
$unit = $units[$magnitude];
|
104 |
+
$M /= pow(1024,$magnitude);
|
105 |
+
return 'Allocated '.$this->getArraySize().' bits ('.$M.' '.$unit.'Bytes)'.PHP_EOL.
|
106 |
+
'Using '.$this->getHashCount(). ' (16b) hashes'.PHP_EOL.
|
107 |
+
'Contains '.$this->getElementCount().' elements'.PHP_EOL.
|
108 |
+
(isset($p) ? 'Capacity of '.number_format($this->calculateCapacity($p)).' (p='.$p.')'.PHP_EOL : '');
|
109 |
+
}
|
110 |
+
public function add($key){
|
111 |
+
$hash = md5($key,true);
|
112 |
+
for ($index = 0; $index < $this->k2; $index++){
|
113 |
+
$hash_sub = (ord($hash[$index++]) << 8) | ord($hash[$index]);
|
114 |
+
$word = ($hash_sub & $this->mask) >> 3;
|
115 |
+
$this->bit_array[$word] = $this->bit_array[$word] | chr(1 << ($hash_sub & 7));
|
116 |
+
}
|
117 |
+
$this->n++;
|
118 |
+
}
|
119 |
+
public function contains($key){
|
120 |
+
$hash = md5($key,true);
|
121 |
+
for ($index = 0; $index < $this->k2; $index++){
|
122 |
+
$hash_sub = (ord($hash[$index++]) << 8) | ord($hash[$index]);
|
123 |
+
if ((ord($this->bit_array[($hash_sub & $this->mask) >> 3]) & (1 << ($hash_sub & 7))) === 0) return false;
|
124 |
+
}
|
125 |
+
return true;
|
126 |
+
}
|
127 |
+
public function unionWith($bf){
|
128 |
+
self::merge($this,$bf,$this,true);
|
129 |
+
}
|
130 |
+
public function intersectWith($bf){
|
131 |
+
self::merge($this,$bf,$this,false);
|
132 |
+
}
|
133 |
+
}
|
134 |
+
?>
|
lib/wfScanEngine.php
CHANGED
@@ -36,7 +36,7 @@ class wfScanEngine {
|
|
36 |
);
|
37 |
private $userPasswdQueue = "";
|
38 |
private $passwdHasIssues = false;
|
39 |
-
|
40 |
|
41 |
/**
|
42 |
* @var wordfenceDBScanner
|
@@ -73,7 +73,7 @@ class wfScanEngine {
|
|
73 |
}
|
74 |
|
75 |
public function __sleep(){ //Same order here as above for properties that are included in serialization
|
76 |
-
return array('hasher', 'jobList', 'i', 'wp_version', 'apiKey', 'startTime', 'maxExecTime', 'publicScanEnabled', 'fileContentsResults', 'scanner', 'scanQueue', 'hoover', 'scanData', 'statusIDX', 'userPasswdQueue', 'passwdHasIssues', 'dbScanner', 'knownFilesLoader', 'metrics');
|
77 |
}
|
78 |
public function __construct(){
|
79 |
$this->startTime = time();
|
@@ -94,7 +94,7 @@ class wfScanEngine {
|
|
94 |
$this->jobList[] = 'knownFiles_init';
|
95 |
$this->jobList[] = 'knownFiles_main';
|
96 |
$this->jobList[] = 'knownFiles_finish';
|
97 |
-
foreach (array('knownFiles', 'checkReadableConfig', 'fileContents',
|
98 |
// 'wpscan_fullPathDisclosure', 'wpscan_directoryListingEnabled',
|
99 |
'posts', 'comments', 'passwds', 'dns', 'diskSpace', 'oldVersions', 'suspiciousAdminUsers') as $scanType) {
|
100 |
if (wfConfig::get('scansEnabled_' . $scanType)) {
|
@@ -493,6 +493,7 @@ class wfScanEngine {
|
|
493 |
$this->i->updateSummaryItem('totalData', wfUtils::formatBytes($this->hasher->totalData));
|
494 |
$this->i->updateSummaryItem('totalFiles', $this->hasher->totalFiles);
|
495 |
$this->i->updateSummaryItem('totalDirs', $this->hasher->totalDirs);
|
|
|
496 |
$this->hasher = false;
|
497 |
}
|
498 |
private function scan_knownFiles_finish(){
|
@@ -529,6 +530,39 @@ class wfScanEngine {
|
|
529 |
wordfence::statusEnd($this->statusIDX['GSB'], $haveIssuesGSB);
|
530 |
}
|
531 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
532 |
|
533 |
private function scan_posts_init(){
|
534 |
$this->statusIDX['posts'] = wordfence::statusStart('Scanning posts for URLs in Google\'s Safe Browsing List');
|
@@ -1488,7 +1522,7 @@ class wfCommonBackupFileTest {
|
|
1488 |
* @return wfCommonBackupFileTest
|
1489 |
*/
|
1490 |
public static function createFromRootPath($path) {
|
1491 |
-
return new self(
|
1492 |
}
|
1493 |
|
1494 |
private $url;
|
@@ -1584,3 +1618,7 @@ class wfCommonBackupFileTest {
|
|
1584 |
return $this->response;
|
1585 |
}
|
1586 |
}
|
|
|
|
|
|
|
|
36 |
);
|
37 |
private $userPasswdQueue = "";
|
38 |
private $passwdHasIssues = false;
|
39 |
+
private $suspectedFiles = false; //Files found with the ".suspected" extension
|
40 |
|
41 |
/**
|
42 |
* @var wordfenceDBScanner
|
73 |
}
|
74 |
|
75 |
public function __sleep(){ //Same order here as above for properties that are included in serialization
|
76 |
+
return array('hasher', 'jobList', 'i', 'wp_version', 'apiKey', 'startTime', 'maxExecTime', 'publicScanEnabled', 'fileContentsResults', 'scanner', 'scanQueue', 'hoover', 'scanData', 'statusIDX', 'userPasswdQueue', 'passwdHasIssues', 'suspectedFiles', 'dbScanner', 'knownFilesLoader', 'metrics');
|
77 |
}
|
78 |
public function __construct(){
|
79 |
$this->startTime = time();
|
94 |
$this->jobList[] = 'knownFiles_init';
|
95 |
$this->jobList[] = 'knownFiles_main';
|
96 |
$this->jobList[] = 'knownFiles_finish';
|
97 |
+
foreach (array('knownFiles', 'checkReadableConfig', 'fileContents', 'suspectedFiles',
|
98 |
// 'wpscan_fullPathDisclosure', 'wpscan_directoryListingEnabled',
|
99 |
'posts', 'comments', 'passwds', 'dns', 'diskSpace', 'oldVersions', 'suspiciousAdminUsers') as $scanType) {
|
100 |
if (wfConfig::get('scansEnabled_' . $scanType)) {
|
493 |
$this->i->updateSummaryItem('totalData', wfUtils::formatBytes($this->hasher->totalData));
|
494 |
$this->i->updateSummaryItem('totalFiles', $this->hasher->totalFiles);
|
495 |
$this->i->updateSummaryItem('totalDirs', $this->hasher->totalDirs);
|
496 |
+
$this->suspectedFiles = $this->hasher->getSuspectedFiles();
|
497 |
$this->hasher = false;
|
498 |
}
|
499 |
private function scan_knownFiles_finish(){
|
530 |
wordfence::statusEnd($this->statusIDX['GSB'], $haveIssuesGSB);
|
531 |
}
|
532 |
|
533 |
+
private function scan_suspectedFiles() {
|
534 |
+
$haveIssues = false;
|
535 |
+
$status = wordfence::statusStart("Scanning for publicly accessible quarantined files");
|
536 |
+
|
537 |
+
if (is_array($this->suspectedFiles) && count($this->suspectedFiles) > 0) {
|
538 |
+
foreach ($this->suspectedFiles as $file) {
|
539 |
+
wordfence::status(4, 'info', "Testing accessibility of: $file");
|
540 |
+
$test = wfPubliclyAccessibleFileTest::createFromRootPath($file);
|
541 |
+
if ($test->fileExists() && $test->isPubliclyAccessible()) {
|
542 |
+
$key = "publiclyAccessible" . bin2hex($test->getUrl());
|
543 |
+
if ($this->addIssue(
|
544 |
+
'publiclyAccessible',
|
545 |
+
2,
|
546 |
+
$key,
|
547 |
+
$key,
|
548 |
+
'Publicly accessible quarantined file found: ' . esc_html($file),
|
549 |
+
'<a href="' . $test->getUrl() . '" target="_blank">' . $test->getUrl() . '</a> is publicly
|
550 |
+
accessible and may expose source code or sensitive information about your site. Files such as this one are commonly
|
551 |
+
checked for by scanners and should be removed or made inaccessible.',
|
552 |
+
array(
|
553 |
+
'url' => $test->getUrl(),
|
554 |
+
'file' => $file,
|
555 |
+
'canDelete' => true,
|
556 |
+
)
|
557 |
+
)) {
|
558 |
+
$haveIssues = true;
|
559 |
+
}
|
560 |
+
}
|
561 |
+
}
|
562 |
+
}
|
563 |
+
|
564 |
+
wordfence::statusEnd($status, $haveIssues);
|
565 |
+
}
|
566 |
|
567 |
private function scan_posts_init(){
|
568 |
$this->statusIDX['posts'] = wordfence::statusStart('Scanning posts for URLs in Google\'s Safe Browsing List');
|
1522 |
* @return wfCommonBackupFileTest
|
1523 |
*/
|
1524 |
public static function createFromRootPath($path) {
|
1525 |
+
return new self(site_url($path), ABSPATH . $path);
|
1526 |
}
|
1527 |
|
1528 |
private $url;
|
1618 |
return $this->response;
|
1619 |
}
|
1620 |
}
|
1621 |
+
|
1622 |
+
class wfPubliclyAccessibleFileTest extends wfCommonBackupFileTest {
|
1623 |
+
|
1624 |
+
}
|
lib/wfUtils.php
CHANGED
@@ -960,7 +960,7 @@ class wfUtils {
|
|
960 |
if (!$host) {
|
961 |
// This function works for IPv4 or IPv6
|
962 |
if (function_exists('gethostbyaddr')) {
|
963 |
-
$host = gethostbyaddr($IP);
|
964 |
}
|
965 |
if (!$host) {
|
966 |
$ptr = false;
|
@@ -1277,7 +1277,7 @@ class wfUtils {
|
|
1277 |
|
1278 |
public static function htaccessAppend($code)
|
1279 |
{
|
1280 |
-
$htaccess =
|
1281 |
$content = self::htaccess();
|
1282 |
if (wfUtils::isNginx() || !is_writable($htaccess)) {
|
1283 |
return false;
|
@@ -1290,10 +1290,27 @@ class wfUtils {
|
|
1290 |
|
1291 |
return true;
|
1292 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1293 |
|
1294 |
public static function htaccess() {
|
1295 |
-
|
1296 |
-
|
|
|
1297 |
}
|
1298 |
return "";
|
1299 |
}
|
960 |
if (!$host) {
|
961 |
// This function works for IPv4 or IPv6
|
962 |
if (function_exists('gethostbyaddr')) {
|
963 |
+
$host = @gethostbyaddr($IP);
|
964 |
}
|
965 |
if (!$host) {
|
966 |
$ptr = false;
|
1277 |
|
1278 |
public static function htaccessAppend($code)
|
1279 |
{
|
1280 |
+
$htaccess = wfCache::getHtaccessPath();
|
1281 |
$content = self::htaccess();
|
1282 |
if (wfUtils::isNginx() || !is_writable($htaccess)) {
|
1283 |
return false;
|
1290 |
|
1291 |
return true;
|
1292 |
}
|
1293 |
+
|
1294 |
+
public static function htaccessPrepend($code)
|
1295 |
+
{
|
1296 |
+
$htaccess = wfCache::getHtaccessPath();
|
1297 |
+
$content = self::htaccess();
|
1298 |
+
if (wfUtils::isNginx() || !is_writable($htaccess)) {
|
1299 |
+
return false;
|
1300 |
+
}
|
1301 |
+
|
1302 |
+
if (strpos($content, $code) === false) {
|
1303 |
+
// make sure we write this once
|
1304 |
+
file_put_contents($htaccess, trim($code) . "\n" . $content, LOCK_EX);
|
1305 |
+
}
|
1306 |
+
|
1307 |
+
return true;
|
1308 |
+
}
|
1309 |
|
1310 |
public static function htaccess() {
|
1311 |
+
$htaccess = wfCache::getHtaccessPath();
|
1312 |
+
if (is_readable($htaccess) && !wfUtils::isNginx()) {
|
1313 |
+
return file_get_contents($htaccess);
|
1314 |
}
|
1315 |
return "";
|
1316 |
}
|
lib/wordfenceClass.php
CHANGED
@@ -13,6 +13,7 @@ require_once('wfConfig.php');
|
|
13 |
require_once('wfSchema.php');
|
14 |
require_once('wfCache.php');
|
15 |
require_once('wfCrypt.php');
|
|
|
16 |
require_once 'wfView.php';
|
17 |
require_once 'wfHelperString.php';
|
18 |
require_once 'wfDirectoryIterator.php';
|
@@ -544,6 +545,13 @@ SQL
|
|
544 |
|
545 |
//6.2.0
|
546 |
wfConfig::migrateCodeExecutionForUploadsPHP7();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
547 |
|
548 |
//Must be the final line
|
549 |
}
|
@@ -585,6 +593,9 @@ SQL
|
|
585 |
}
|
586 |
|
587 |
self::initProtection();
|
|
|
|
|
|
|
588 |
|
589 |
//These access wfConfig::get('apiKey') and will fail if runInstall hasn't executed.
|
590 |
wfCache::setupCaching();
|
@@ -737,6 +748,8 @@ SQL
|
|
737 |
|
738 |
add_action('wordfence_batchReportBlockedAttempts', 'wordfence::wfsnBatchReportBlockedAttempts');
|
739 |
add_action('wordfence_batchReportFailedAttempts', 'wordfence::wfsnBatchReportFailedAttempts');
|
|
|
|
|
740 |
|
741 |
if (wfConfig::get('other_hideWPVersion')) {
|
742 |
add_filter('update_feedback', 'wordfence::restoreReadmeForUpgrade');
|
@@ -745,10 +758,37 @@ SQL
|
|
745 |
}
|
746 |
public static function _pluginPageActionLinks($links) {
|
747 |
if (!wfConfig::get('isPaid')) {
|
748 |
-
$links = array_merge(array('aWordfencePluginCallout' => '<a href="https://www.wordfence.com/zz12/wordfence-signup/" target="_blank"><strong style="color: #
|
749 |
-
}
|
750 |
return $links;
|
751 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
752 |
/*
|
753 |
public static function cronAddSchedules($schedules){
|
754 |
$schedules['wfEachMinute'] = array(
|
@@ -1201,16 +1241,37 @@ SQL
|
|
1201 |
'IP' => wfUtils::getIP()
|
1202 |
));
|
1203 |
}
|
1204 |
-
|
|
|
|
|
|
|
1205 |
if(user_can($userID, 'update_core')){
|
1206 |
if(wfConfig::get('alertOn_adminLogin')){
|
1207 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1208 |
}
|
1209 |
} else {
|
1210 |
if(wfConfig::get('alertOn_nonAdminLogin')){
|
1211 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1212 |
}
|
1213 |
}
|
|
|
|
|
|
|
|
|
1214 |
}
|
1215 |
public static function registrationFilter($errors, $santizedLogin, $userEmail){
|
1216 |
if(wfConfig::get('loginSec_blockAdminReg') && $santizedLogin == 'admin'){
|
@@ -2429,6 +2490,10 @@ SQL
|
|
2429 |
wfConfig::set('suPHPWAFUpdateChoice', '1');
|
2430 |
return array('ok' => 1);
|
2431 |
}
|
|
|
|
|
|
|
|
|
2432 |
public static function ajax_removeFromCache_callback(){
|
2433 |
$id = $_POST['id'];
|
2434 |
$link = get_permalink($id);
|
@@ -2916,24 +2981,54 @@ SQL
|
|
2916 |
if (!$issue) {
|
2917 |
return array('cerrorMsg' => "We could not find that issue in our database.");
|
2918 |
}
|
2919 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2920 |
$file = $issue['data']['file'];
|
2921 |
-
$localFile = ABSPATH . '/' . $file;
|
2922 |
$localFile = realpath($localFile);
|
2923 |
-
if (strpos($localFile,
|
2924 |
-
return array('cerrorMsg' => "An invalid file was requested for
|
2925 |
}
|
2926 |
-
$localFile = substr($localFile, strlen(
|
2927 |
-
|
2928 |
-
|
2929 |
-
|
2930 |
-
|
|
|
|
|
|
|
|
|
|
|
2931 |
</IfModule>
|
2932 |
-
<IfModule !
|
2933 |
-
|
2934 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2935 |
</IfModule>
|
2936 |
-
|
|
|
|
|
2937 |
return array('cerrorMsg' => "You don't have permission to repair .htaccess. You need to either fix the file manually using FTP or change the file permissions and ownership so that your web server has write access to repair the file.");
|
2938 |
}
|
2939 |
$issues->updateIssue($_POST['issueID'], 'delete');
|
@@ -4159,7 +4254,7 @@ HTML;
|
|
4159 |
'activityLogUpdate', 'ticker', 'loadIssues', 'updateIssueStatus', 'deleteIssue', 'updateAllIssues',
|
4160 |
'reverseLookup', 'unlockOutIP', 'loadBlockRanges', 'unblockRange', 'blockIPUARange', 'whois', 'unblockIP',
|
4161 |
'blockIP', 'permBlockIP', 'loadStaticPanel', 'saveConfig', 'downloadHtaccess', 'checkFalconHtaccess',
|
4162 |
-
'updateConfig', 'saveCacheConfig', 'removeFromCache', 'autoUpdateChoice', 'adminEmailChoice', 'suPHPWAFUpdateChoice', 'saveCacheOptions', 'clearPageCache',
|
4163 |
'getCacheStats', 'clearAllBlocked', 'killScan', 'saveCountryBlocking', 'saveScanSchedule', 'tourClosed',
|
4164 |
'welcomeClosed', 'startTourAgain', 'downgradeLicense', 'addTwoFactor', 'twoFacActivate', 'twoFacDel',
|
4165 |
'loadTwoFactor', 'loadAvgSitePerf', 'sendTestEmail', 'addCacheExclusion', 'removeCacheExclusion',
|
@@ -4318,6 +4413,12 @@ HTML;
|
|
4318 |
echo '<div id="wordfenceAdminEmailWarning" class="fade error"><p><strong>You have not set an administrator email address to receive alerts for Wordfence.</strong> Please <a href="' . self::getMyOptionsURL() . '">click here to go to the Wordfence Options Page</a> and set an email address where you will receive security alerts from this site.</p><p><a class="button button-small" href="#" onclick="wordfenceExt.adminEmailChoice(\'mine\'); return false;"">Use My Email Address</a>
|
4319 |
<a class="button button-small wf-dismiss-link" href="#" onclick="wordfenceExt.adminEmailChoice(\'no\'); return false;">Dismiss</a></p></div>';
|
4320 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
4321 |
public static function autoUpdateNotice(){
|
4322 |
echo '<div id="wordfenceAutoUpdateChoice" class="fade error"><p><strong>Do you want Wordfence to stay up-to-date automatically?</strong> <a href="#" onclick="wordfenceExt.autoUpdateChoice(\'yes\'); return false;">Yes, enable auto-update.</a> | <a href="#" onclick="wordfenceExt.autoUpdateChoice(\'no\'); return false;">No thanks.</a></p></div>';
|
4323 |
}
|
@@ -4340,6 +4441,16 @@ HTML;
|
|
4340 |
}
|
4341 |
$warningAdded = true;
|
4342 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4343 |
if(! $warningAdded){
|
4344 |
if(wfConfig::get('tourClosed') == '1' && (! wfConfig::get('autoUpdate')) && (! wfConfig::get('autoUpdateChoice'))){
|
4345 |
$warningAdded = true;
|
@@ -4384,7 +4495,9 @@ HTML;
|
|
4384 |
add_submenu_page("Wordfence", "Firewall", "Firewall", "activate_plugins", "WordfenceWAF", 'wordfence::menu_waf');
|
4385 |
add_submenu_page("Wordfence", "Live Traffic", "Live Traffic", "activate_plugins", "WordfenceActivity", 'wordfence::menu_activity');
|
4386 |
/* add_submenu_page('Wordfence', 'Site Performance', 'Site Performance', 'activate_plugins', 'WordfenceSitePerfStats', 'wordfence::menu_sitePerfStats'); */
|
4387 |
-
|
|
|
|
|
4388 |
add_submenu_page('Wordfence', 'Blocked IPs', 'Blocked IPs', 'activate_plugins', 'WordfenceBlockedIPs', 'wordfence::menu_blockedIPs');
|
4389 |
add_submenu_page('Wordfence', 'Password Audit', 'Password Audit', 'activate_plugins', 'WordfencePasswdAudit', 'wordfence::menu_passwd');
|
4390 |
|
@@ -5661,7 +5774,12 @@ to your httpd.conf if using Apache, or find documentation on how to disable dire
|
|
5661 |
) {
|
5662 |
status_header(404);
|
5663 |
nocache_headers();
|
5664 |
-
|
|
|
|
|
|
|
|
|
|
|
5665 |
exit;
|
5666 |
}
|
5667 |
return $query_vars;
|
13 |
require_once('wfSchema.php');
|
14 |
require_once('wfCache.php');
|
15 |
require_once('wfCrypt.php');
|
16 |
+
require_once('wfMD5BloomFilter.php');
|
17 |
require_once 'wfView.php';
|
18 |
require_once 'wfHelperString.php';
|
19 |
require_once 'wfDirectoryIterator.php';
|
545 |
|
546 |
//6.2.0
|
547 |
wfConfig::migrateCodeExecutionForUploadsPHP7();
|
548 |
+
|
549 |
+
//6.2.1
|
550 |
+
if ((wfConfig::get('cacheType') == 'php' || wfConfig::get('cacheType') == 'falcon') && !wfConfig::get('wf621HadFalconEnabled')) {
|
551 |
+
wfConfig::set('wf621HadFalconEnabled', true);
|
552 |
+
|
553 |
+
wp_schedule_single_event(time(), 'wordfence_sendFalconDeprecationNotice');
|
554 |
+
}
|
555 |
|
556 |
//Must be the final line
|
557 |
}
|
593 |
}
|
594 |
|
595 |
self::initProtection();
|
596 |
+
|
597 |
+
//Fix wp_mail bug when $_SERVER['SERVER_NAME'] is undefined
|
598 |
+
add_filter('wp_mail_from', 'wordfence::fixWPMailFromAddress');
|
599 |
|
600 |
//These access wfConfig::get('apiKey') and will fail if runInstall hasn't executed.
|
601 |
wfCache::setupCaching();
|
748 |
|
749 |
add_action('wordfence_batchReportBlockedAttempts', 'wordfence::wfsnBatchReportBlockedAttempts');
|
750 |
add_action('wordfence_batchReportFailedAttempts', 'wordfence::wfsnBatchReportFailedAttempts');
|
751 |
+
|
752 |
+
add_action('wordfence_sendFalconDeprecationNotice', 'wordfence::sendFalconDeprecationNotice');
|
753 |
|
754 |
if (wfConfig::get('other_hideWPVersion')) {
|
755 |
add_filter('update_feedback', 'wordfence::restoreReadmeForUpgrade');
|
758 |
}
|
759 |
public static function _pluginPageActionLinks($links) {
|
760 |
if (!wfConfig::get('isPaid')) {
|
761 |
+
$links = array_merge(array('aWordfencePluginCallout' => '<a href="https://www.wordfence.com/zz12/wordfence-signup/" target="_blank"><strong style="color: #11967A; display: inline;">Upgrade To Premium</strong></a>'), $links);
|
762 |
+
}
|
763 |
return $links;
|
764 |
}
|
765 |
+
public static function sendFalconDeprecationNotice() {
|
766 |
+
$url = network_admin_url('admin.php?page=WordfenceSitePerf');
|
767 |
+
$cacheName = (wfConfig::get('cacheType') == 'php' ? 'Basic' : 'Falcon');
|
768 |
+
wordfence::alert("Support for the Falcon and Basic cache will be removed", "This site currently has the {$cacheName} cache enabled, and it is scheduled to be removed in an upcoming release. Please investigate other caching options and then visit the cache settings page to manually disable the {$cacheName} cache. It will be disabled automatically when support is removed.\n\nCache Settings Page: {$url}\n", wfUtils::getIP());
|
769 |
+
}
|
770 |
+
public static function fixWPMailFromAddress($from_email) {
|
771 |
+
if ($from_email == 'wordpress@') { //$_SERVER['SERVER_NAME'] is undefined so we get an incomplete email address
|
772 |
+
wordfence::status(4, 'info', "wp_mail from address is incomplete, attempting to fix");
|
773 |
+
$urls = array(get_site_url(), get_home_url());
|
774 |
+
foreach ($urls as $u) {
|
775 |
+
if (!empty($u)) {
|
776 |
+
$u = preg_replace('#^[^/]*//+([^/]+).*$#', '\1', $u);
|
777 |
+
if (substr($u, 0, 4) == 'www.') {
|
778 |
+
$u = substr($u, 4);
|
779 |
+
}
|
780 |
+
|
781 |
+
if (!empty($u)) {
|
782 |
+
wordfence::status(4, 'info', "Fixing wp_mail from address: " . $from_email . $u);
|
783 |
+
return $from_email . $u;
|
784 |
+
}
|
785 |
+
}
|
786 |
+
}
|
787 |
+
|
788 |
+
//Can't fix it, return it as it was
|
789 |
+
}
|
790 |
+
return $from_email;
|
791 |
+
}
|
792 |
/*
|
793 |
public static function cronAddSchedules($schedules){
|
794 |
$schedules['wfEachMinute'] = array(
|
1241 |
'IP' => wfUtils::getIP()
|
1242 |
));
|
1243 |
}
|
1244 |
+
|
1245 |
+
$salt = wp_salt('logged_in');
|
1246 |
+
$cookiename = 'wf_loginalerted_' . hash_hmac('sha256', wfUtils::getIP() . '|' . $user->ID, $salt);
|
1247 |
+
$cookievalue = hash_hmac('sha256', $user->user_login, $salt);
|
1248 |
if(user_can($userID, 'update_core')){
|
1249 |
if(wfConfig::get('alertOn_adminLogin')){
|
1250 |
+
$shouldAlert = true;
|
1251 |
+
if (wfConfig::get('alertOn_firstAdminLoginOnly') && isset($_COOKIE[$cookiename])) {
|
1252 |
+
$shouldAlert = !hash_equals($cookievalue, $_COOKIE[$cookiename]);
|
1253 |
+
}
|
1254 |
+
|
1255 |
+
if ($shouldAlert) {
|
1256 |
+
wordfence::alert("Admin Login", "A user with username \"$username\" who has administrator access signed in to your WordPress site.", wfUtils::getIP());
|
1257 |
+
}
|
1258 |
}
|
1259 |
} else {
|
1260 |
if(wfConfig::get('alertOn_nonAdminLogin')){
|
1261 |
+
$shouldAlert = true;
|
1262 |
+
if (wfConfig::get('alertOn_firstNonAdminLoginOnly') && isset($_COOKIE[$cookiename])) {
|
1263 |
+
$shouldAlert = !hash_equals($cookievalue, $_COOKIE[$cookiename]);
|
1264 |
+
}
|
1265 |
+
|
1266 |
+
if ($shouldAlert) {
|
1267 |
+
wordfence::alert("User login", "A non-admin user with username \"$username\" signed in to your WordPress site.", wfUtils::getIP());
|
1268 |
+
}
|
1269 |
}
|
1270 |
}
|
1271 |
+
|
1272 |
+
if (wfConfig::get('alertOn_firstAdminLoginOnly') || wfConfig::get('alertOn_firstNonAdminLoginOnly')) {
|
1273 |
+
wfUtils::setcookie($cookiename, $cookievalue, time() + (86400 * 365), '/', null, null, true);
|
1274 |
+
}
|
1275 |
}
|
1276 |
public static function registrationFilter($errors, $santizedLogin, $userEmail){
|
1277 |
if(wfConfig::get('loginSec_blockAdminReg') && $santizedLogin == 'admin'){
|
2490 |
wfConfig::set('suPHPWAFUpdateChoice', '1');
|
2491 |
return array('ok' => 1);
|
2492 |
}
|
2493 |
+
public static function ajax_falconDeprecationChoice_callback() {
|
2494 |
+
wfConfig::set('falconDeprecationChoice', '1');
|
2495 |
+
return array('ok' => 1);
|
2496 |
+
}
|
2497 |
public static function ajax_removeFromCache_callback(){
|
2498 |
$id = $_POST['id'];
|
2499 |
$link = get_permalink($id);
|
2981 |
if (!$issue) {
|
2982 |
return array('cerrorMsg' => "We could not find that issue in our database.");
|
2983 |
}
|
2984 |
+
|
2985 |
+
if (!function_exists('get_home_path')) {
|
2986 |
+
include_once ABSPATH . 'wp-admin/includes/file.php';
|
2987 |
+
}
|
2988 |
+
|
2989 |
+
$homeURL = get_home_url();
|
2990 |
+
$components = parse_url($homeURL);
|
2991 |
+
if ($components === false) {
|
2992 |
+
return array('cerrorMsg' => "An error occurred while trying to hide the file.");
|
2993 |
+
}
|
2994 |
+
|
2995 |
+
$sitePath = '';
|
2996 |
+
if (isset($components['path'])) {
|
2997 |
+
$sitePath = trim($components['path'], '/');
|
2998 |
+
}
|
2999 |
+
|
3000 |
+
$homePath = get_home_path();
|
3001 |
$file = $issue['data']['file'];
|
3002 |
+
$localFile = ABSPATH . '/' . $file; //The scanner uses ABSPATH as its base rather than get_home_path()
|
3003 |
$localFile = realpath($localFile);
|
3004 |
+
if (strpos($localFile, $homePath) !== 0) {
|
3005 |
+
return array('cerrorMsg' => "An invalid file was requested for hiding.");
|
3006 |
}
|
3007 |
+
$localFile = substr($localFile, strlen($homePath));
|
3008 |
+
$absoluteURIPath = trim($sitePath . '/' . $localFile, '/');
|
3009 |
+
$regexLocalFile = preg_replace('#/#', '/+', preg_quote($absoluteURIPath));
|
3010 |
+
$filename = basename($localFile);
|
3011 |
+
|
3012 |
+
$htaccessContent = <<<HTACCESS
|
3013 |
+
<IfModule mod_rewrite.c>
|
3014 |
+
RewriteEngine On
|
3015 |
+
RewriteCond %{REQUEST_URI} ^/?{$regexLocalFile}$
|
3016 |
+
RewriteRule .* - [F,L,NC]
|
3017 |
</IfModule>
|
3018 |
+
<IfModule !mod_rewrite.c>
|
3019 |
+
<Files "{$filename}">
|
3020 |
+
<IfModule mod_authz_core.c>
|
3021 |
+
Require all denied
|
3022 |
+
</IfModule>
|
3023 |
+
<IfModule !mod_authz_core.c>
|
3024 |
+
Order deny,allow
|
3025 |
+
Deny from all
|
3026 |
+
</IfModule>
|
3027 |
+
</Files>
|
3028 |
</IfModule>
|
3029 |
+
HTACCESS;
|
3030 |
+
|
3031 |
+
if (!wfUtils::htaccessPrepend($htaccessContent)) {
|
3032 |
return array('cerrorMsg' => "You don't have permission to repair .htaccess. You need to either fix the file manually using FTP or change the file permissions and ownership so that your web server has write access to repair the file.");
|
3033 |
}
|
3034 |
$issues->updateIssue($_POST['issueID'], 'delete');
|
4254 |
'activityLogUpdate', 'ticker', 'loadIssues', 'updateIssueStatus', 'deleteIssue', 'updateAllIssues',
|
4255 |
'reverseLookup', 'unlockOutIP', 'loadBlockRanges', 'unblockRange', 'blockIPUARange', 'whois', 'unblockIP',
|
4256 |
'blockIP', 'permBlockIP', 'loadStaticPanel', 'saveConfig', 'downloadHtaccess', 'checkFalconHtaccess',
|
4257 |
+
'updateConfig', 'saveCacheConfig', 'removeFromCache', 'autoUpdateChoice', 'adminEmailChoice', 'suPHPWAFUpdateChoice', 'falconDeprecationChoice', 'saveCacheOptions', 'clearPageCache',
|
4258 |
'getCacheStats', 'clearAllBlocked', 'killScan', 'saveCountryBlocking', 'saveScanSchedule', 'tourClosed',
|
4259 |
'welcomeClosed', 'startTourAgain', 'downgradeLicense', 'addTwoFactor', 'twoFacActivate', 'twoFacDel',
|
4260 |
'loadTwoFactor', 'loadAvgSitePerf', 'sendTestEmail', 'addCacheExclusion', 'removeCacheExclusion',
|
4413 |
echo '<div id="wordfenceAdminEmailWarning" class="fade error"><p><strong>You have not set an administrator email address to receive alerts for Wordfence.</strong> Please <a href="' . self::getMyOptionsURL() . '">click here to go to the Wordfence Options Page</a> and set an email address where you will receive security alerts from this site.</p><p><a class="button button-small" href="#" onclick="wordfenceExt.adminEmailChoice(\'mine\'); return false;"">Use My Email Address</a>
|
4414 |
<a class="button button-small wf-dismiss-link" href="#" onclick="wordfenceExt.adminEmailChoice(\'no\'); return false;">Dismiss</a></p></div>';
|
4415 |
}
|
4416 |
+
public static function falconDeprecationWarning() {
|
4417 |
+
$url = network_admin_url('admin.php?page=WordfenceSitePerf');
|
4418 |
+
$cacheName = (wfConfig::get('cacheType') == 'php' ? 'Basic' : 'Falcon');
|
4419 |
+
echo '<div id="wordfenceFalconDeprecationWarning" class="fade error"><p><strong>Support for the Falcon and Basic cache will be removed.</strong> This site currently has the ' . $cacheName . ' cache enabled, and it is scheduled to be removed in an upcoming release. Please investigate other caching options and then <a href="' . $url . '">click here to visit the cache settings page</a> to manually disable the cache. It will be disabled automatically when support is removed.</p><p>
|
4420 |
+
<a class="button button-small wf-dismiss-link" href="#" onclick="wordfenceExt.falconDeprecationChoice(\'no\'); return false;">Dismiss</a></p></div>';
|
4421 |
+
}
|
4422 |
public static function autoUpdateNotice(){
|
4423 |
echo '<div id="wordfenceAutoUpdateChoice" class="fade error"><p><strong>Do you want Wordfence to stay up-to-date automatically?</strong> <a href="#" onclick="wordfenceExt.autoUpdateChoice(\'yes\'); return false;">Yes, enable auto-update.</a> | <a href="#" onclick="wordfenceExt.autoUpdateChoice(\'no\'); return false;">No thanks.</a></p></div>';
|
4424 |
}
|
4441 |
}
|
4442 |
$warningAdded = true;
|
4443 |
}
|
4444 |
+
|
4445 |
+
$page = (isset($_GET['page']) ? $_GET['page'] : '');
|
4446 |
+
if ((wfConfig::get('cacheType') == 'php' || wfConfig::get('cacheType') == 'falcon') && !wfConfig::get('falconDeprecationChoice') && $page != 'WordfenceSitePerf') {
|
4447 |
+
$warningAdded = true;
|
4448 |
+
if(wfUtils::isAdminPageMU()){
|
4449 |
+
add_action('network_admin_notices', 'wordfence::falconDeprecationWarning');
|
4450 |
+
} else {
|
4451 |
+
add_action('admin_notices', 'wordfence::falconDeprecationWarning');
|
4452 |
+
}
|
4453 |
+
}
|
4454 |
if(! $warningAdded){
|
4455 |
if(wfConfig::get('tourClosed') == '1' && (! wfConfig::get('autoUpdate')) && (! wfConfig::get('autoUpdateChoice'))){
|
4456 |
$warningAdded = true;
|
4495 |
add_submenu_page("Wordfence", "Firewall", "Firewall", "activate_plugins", "WordfenceWAF", 'wordfence::menu_waf');
|
4496 |
add_submenu_page("Wordfence", "Live Traffic", "Live Traffic", "activate_plugins", "WordfenceActivity", 'wordfence::menu_activity');
|
4497 |
/* add_submenu_page('Wordfence', 'Site Performance', 'Site Performance', 'activate_plugins', 'WordfenceSitePerfStats', 'wordfence::menu_sitePerfStats'); */
|
4498 |
+
if (wfConfig::get('wf621HadFalconEnabled') || (defined('WF_ENABLE_FALCON') && WF_ENABLE_FALCON)) {
|
4499 |
+
add_submenu_page('Wordfence', 'Performance Setup', 'Performance Setup', 'activate_plugins', 'WordfenceSitePerf', 'wordfence::menu_sitePerf');
|
4500 |
+
}
|
4501 |
add_submenu_page('Wordfence', 'Blocked IPs', 'Blocked IPs', 'activate_plugins', 'WordfenceBlockedIPs', 'wordfence::menu_blockedIPs');
|
4502 |
add_submenu_page('Wordfence', 'Password Audit', 'Password Audit', 'activate_plugins', 'WordfencePasswdAudit', 'wordfence::menu_passwd');
|
4503 |
|
5774 |
) {
|
5775 |
status_header(404);
|
5776 |
nocache_headers();
|
5777 |
+
|
5778 |
+
$template = get_404_template();
|
5779 |
+
if ($template && file_exists($template)) {
|
5780 |
+
include($template);
|
5781 |
+
}
|
5782 |
+
|
5783 |
exit;
|
5784 |
}
|
5785 |
return $query_vars;
|
lib/wordfenceHash.php
CHANGED
@@ -26,6 +26,8 @@ class wordfenceHash {
|
|
26 |
private $totalForks = 0;
|
27 |
private $alertedOnUnknownWordPressVersion = false;
|
28 |
private $foldersProcessed = array();
|
|
|
|
|
29 |
|
30 |
/**
|
31 |
* @param string $striplen
|
@@ -59,6 +61,8 @@ class wordfenceHash {
|
|
59 |
if(wfConfig::get('scansEnabled_coreUnknown')){
|
60 |
$this->coreUnknownEnabled = true;
|
61 |
}
|
|
|
|
|
62 |
|
63 |
$this->db = new wfDB();
|
64 |
|
@@ -112,13 +116,16 @@ class wordfenceHash {
|
|
112 |
if($this->coreUnknownEnabled){ $this->status['coreUnknown'] = wordfence::statusStart("Scanning for unknown files in wp-admin and wp-includes"); } else { wordfence::statusDisabled("Skipping unknown core file scan"); }
|
113 |
}
|
114 |
public function __sleep(){
|
115 |
-
return array('striplen', 'totalFiles', 'totalDirs', 'totalData', 'stoppedOnFile', 'coreEnabled', 'pluginsEnabled', 'themesEnabled', 'malwareEnabled', 'coreUnknownEnabled', 'knownFiles', 'malwareData', 'haveIssues', 'status', 'possibleMalware', 'path', 'only', 'totalForks', 'alertedOnUnknownWordPressVersion', 'foldersProcessed');
|
116 |
}
|
117 |
public function __wakeup(){
|
118 |
$this->db = new wfDB();
|
119 |
$this->startTime = microtime(true);
|
120 |
$this->totalForks++;
|
121 |
}
|
|
|
|
|
|
|
122 |
public function run($engine){ //base path and 'only' is a list of files and dirs in the bast that are the only ones that should be processed. Everything else in base is ignored. If only is empty then everything is processed.
|
123 |
if($this->totalForks > 1000){
|
124 |
throw new Exception("Wordfence file scanner detected a possible infinite loop. Exiting on file: " . $this->stoppedOnFile);
|
@@ -237,6 +244,12 @@ class wordfenceHash {
|
|
237 |
}
|
238 |
private function processFile($realFile){
|
239 |
$file = substr($realFile, $this->striplen);
|
|
|
|
|
|
|
|
|
|
|
|
|
240 |
if (!$this->_shouldHashFile($realFile)) {
|
241 |
wordfence::status(4, 'info', "Skipping unneeded hash: {$realFile}");
|
242 |
return;
|
@@ -303,7 +316,7 @@ class wordfenceHash {
|
|
303 |
|
304 |
$this->haveIssues['core'] = true;
|
305 |
$this->engine->addIssue(
|
306 |
-
'
|
307 |
1,
|
308 |
'coreModified' . $file . $md5,
|
309 |
'coreModified' . $file,
|
@@ -337,7 +350,7 @@ class wordfenceHash {
|
|
337 |
$cKey = $this->knownFiles['plugins'][$file][2];
|
338 |
$this->haveIssues['plugins'] = true;
|
339 |
$this->engine->addIssue(
|
340 |
-
'
|
341 |
2,
|
342 |
'modifiedplugin' . $file . $md5,
|
343 |
'modifiedplugin' . $file,
|
@@ -374,7 +387,7 @@ class wordfenceHash {
|
|
374 |
$cKey = $this->knownFiles['themes'][$file][2];
|
375 |
$this->haveIssues['themes'] = true;
|
376 |
$this->engine->addIssue(
|
377 |
-
'
|
378 |
2,
|
379 |
'modifiedtheme' . $file . $md5,
|
380 |
'modifiedtheme' . $file,
|
@@ -402,7 +415,7 @@ class wordfenceHash {
|
|
402 |
if (strpos($realFile, $path) === 0) {
|
403 |
$this->haveIssues['coreUnknown'] = true;
|
404 |
$this->engine->addIssue(
|
405 |
-
'
|
406 |
2,
|
407 |
'coreUnknown' . $file . $md5,
|
408 |
'coreUnknown' . $file,
|
@@ -424,6 +437,8 @@ class wordfenceHash {
|
|
424 |
// we could split this into files who's path we recognize and file's who's path we recognize AND who have a valid sig.
|
425 |
// But because we want to scan files who's sig we don't recognize, regardless of known path or not, we only need one "knownFile" field.
|
426 |
$this->db->queryWrite("insert into " . $this->db->prefix() . "wfFileMods (filename, filenameMD5, knownFile, oldMD5, newMD5) values ('%s', unhex(md5('%s')), %d, '', unhex('%s')) ON DUPLICATE KEY UPDATE newMD5=unhex('%s'), knownFile=%d", $file, $file, $knownFile, $md5, $md5, $knownFile);
|
|
|
|
|
427 |
|
428 |
$this->totalFiles++;
|
429 |
$this->totalData += filesize($realFile); //We already checked if file overflows int in the fileTooBig routine above
|
@@ -455,7 +470,16 @@ class wordfenceHash {
|
|
455 |
return array($md5, $shac);
|
456 |
}
|
457 |
private function _shouldHashFile($fullPath) {
|
458 |
-
$file = substr($fullPath, $this->striplen);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
459 |
|
460 |
//Core File, return true
|
461 |
if ((isset($this->knownFiles['core']) && isset($this->knownFiles['core'][$file])) ||
|
26 |
private $totalForks = 0;
|
27 |
private $alertedOnUnknownWordPressVersion = false;
|
28 |
private $foldersProcessed = array();
|
29 |
+
private $filesProcessedBloomFilter = false;
|
30 |
+
private $suspectedFiles = array();
|
31 |
|
32 |
/**
|
33 |
* @param string $striplen
|
61 |
if(wfConfig::get('scansEnabled_coreUnknown')){
|
62 |
$this->coreUnknownEnabled = true;
|
63 |
}
|
64 |
+
|
65 |
+
$this->filesProcessedBloomFilter = new wfMD5BloomFilter(65536, 8); //65536,8 produces the lowest miss probability. Uses approximately 8 KB of memory + PHP object overhead
|
66 |
|
67 |
$this->db = new wfDB();
|
68 |
|
116 |
if($this->coreUnknownEnabled){ $this->status['coreUnknown'] = wordfence::statusStart("Scanning for unknown files in wp-admin and wp-includes"); } else { wordfence::statusDisabled("Skipping unknown core file scan"); }
|
117 |
}
|
118 |
public function __sleep(){
|
119 |
+
return array('striplen', 'totalFiles', 'totalDirs', 'totalData', 'stoppedOnFile', 'coreEnabled', 'pluginsEnabled', 'themesEnabled', 'malwareEnabled', 'coreUnknownEnabled', 'knownFiles', 'malwareData', 'haveIssues', 'status', 'possibleMalware', 'path', 'only', 'totalForks', 'alertedOnUnknownWordPressVersion', 'foldersProcessed', 'filesProcessedBloomFilter', 'suspectedFiles');
|
120 |
}
|
121 |
public function __wakeup(){
|
122 |
$this->db = new wfDB();
|
123 |
$this->startTime = microtime(true);
|
124 |
$this->totalForks++;
|
125 |
}
|
126 |
+
public function getSuspectedFiles() {
|
127 |
+
return array_keys($this->suspectedFiles);
|
128 |
+
}
|
129 |
public function run($engine){ //base path and 'only' is a list of files and dirs in the bast that are the only ones that should be processed. Everything else in base is ignored. If only is empty then everything is processed.
|
130 |
if($this->totalForks > 1000){
|
131 |
throw new Exception("Wordfence file scanner detected a possible infinite loop. Exiting on file: " . $this->stoppedOnFile);
|
244 |
}
|
245 |
private function processFile($realFile){
|
246 |
$file = substr($realFile, $this->striplen);
|
247 |
+
|
248 |
+
if (preg_match('/\.suspected$/i', $file)) { //Already iterating over all files in the search areas so generate this list here
|
249 |
+
wordfence::status(4, 'info', "Found .suspected file: $file");
|
250 |
+
$this->suspectedFiles[$file] = 1;
|
251 |
+
}
|
252 |
+
|
253 |
if (!$this->_shouldHashFile($realFile)) {
|
254 |
wordfence::status(4, 'info', "Skipping unneeded hash: {$realFile}");
|
255 |
return;
|
316 |
|
317 |
$this->haveIssues['core'] = true;
|
318 |
$this->engine->addIssue(
|
319 |
+
'knownfile',
|
320 |
1,
|
321 |
'coreModified' . $file . $md5,
|
322 |
'coreModified' . $file,
|
350 |
$cKey = $this->knownFiles['plugins'][$file][2];
|
351 |
$this->haveIssues['plugins'] = true;
|
352 |
$this->engine->addIssue(
|
353 |
+
'knownfile',
|
354 |
2,
|
355 |
'modifiedplugin' . $file . $md5,
|
356 |
'modifiedplugin' . $file,
|
387 |
$cKey = $this->knownFiles['themes'][$file][2];
|
388 |
$this->haveIssues['themes'] = true;
|
389 |
$this->engine->addIssue(
|
390 |
+
'knownfile',
|
391 |
2,
|
392 |
'modifiedtheme' . $file . $md5,
|
393 |
'modifiedtheme' . $file,
|
415 |
if (strpos($realFile, $path) === 0) {
|
416 |
$this->haveIssues['coreUnknown'] = true;
|
417 |
$this->engine->addIssue(
|
418 |
+
'knownfile',
|
419 |
2,
|
420 |
'coreUnknown' . $file . $md5,
|
421 |
'coreUnknown' . $file,
|
437 |
// we could split this into files who's path we recognize and file's who's path we recognize AND who have a valid sig.
|
438 |
// But because we want to scan files who's sig we don't recognize, regardless of known path or not, we only need one "knownFile" field.
|
439 |
$this->db->queryWrite("insert into " . $this->db->prefix() . "wfFileMods (filename, filenameMD5, knownFile, oldMD5, newMD5) values ('%s', unhex(md5('%s')), %d, '', unhex('%s')) ON DUPLICATE KEY UPDATE newMD5=unhex('%s'), knownFile=%d", $file, $file, $knownFile, $md5, $md5, $knownFile);
|
440 |
+
|
441 |
+
$this->filesProcessedBloomFilter->add($file);
|
442 |
|
443 |
$this->totalFiles++;
|
444 |
$this->totalData += filesize($realFile); //We already checked if file overflows int in the fileTooBig routine above
|
470 |
return array($md5, $shac);
|
471 |
}
|
472 |
private function _shouldHashFile($fullPath) {
|
473 |
+
$file = substr($fullPath, $this->striplen);
|
474 |
+
|
475 |
+
//Already hashed and processed, return false
|
476 |
+
if ($this->filesProcessedBloomFilter->contains($file)) { //Might have hashed it, verify
|
477 |
+
$rec = $this->db->querySingleRec("SELECT * FROM " . $this->db->prefix() . "wfFileMods WHERE filename = '%s'", $file);
|
478 |
+
if ($rec !== null) {
|
479 |
+
wordfence::status(4, 'info', "Already hashed: {$file}");
|
480 |
+
return false;
|
481 |
+
}
|
482 |
+
}
|
483 |
|
484 |
//Core File, return true
|
485 |
if ((isset($this->knownFiles['core']) && isset($this->knownFiles['core'][$file])) ||
|
readme.txt
CHANGED
@@ -1,11 +1,11 @@
|
|
1 |
=== Wordfence Security ===
|
2 |
Contributors: mmaunder
|
3 |
-
Tags: security, secure, security plugin, wordpress security, login security, firewall, malware, antivirus, web application firewall, block hackers, country blocking
|
4 |
Requires at least: 3.9
|
5 |
Tested up to: 4.6.1
|
6 |
-
Stable tag: 6.2.
|
7 |
|
8 |
-
Secure your website with the most comprehensive WordPress security plugin. Firewall, malware
|
9 |
|
10 |
== Description ==
|
11 |
= THE MOST DOWNLOADED WORDPRESS SECURITY PLUGIN =
|
@@ -61,11 +61,7 @@ Wordfence Security is now Multi-Site compatible and includes Cellphone Sign-in w
|
|
61 |
|
62 |
= Multi-Site Security =
|
63 |
* Wordfence Security for multi-site also scans all posts and comments across all blogs from one admin panel.
|
64 |
-
* WordPress Multi-Site (or WordPress MU in the older parlance) compatible.
|
65 |
-
|
66 |
-
= Caching Features =
|
67 |
-
* Includes Falcon Engine, the fastest WordPress caching engine available today. Falcon is faster because it reduces your web server disk and database activity to a minimum.
|
68 |
-
* Wordfence includes two caching modes for compatability and has cache management features like the ability to clear the cache and monitor cache usage.
|
69 |
|
70 |
= IPv6 Compatible =
|
71 |
* Fully IPv6 compatible including all whois lookup, location, blocking and security functions.
|
@@ -107,8 +103,7 @@ Secure your website with Wordfence.
|
|
107 |
[Visit our support website which contains a FAQ and knowledgebase which is more comprehensive and updated frequently.](http://support.wordfence.com/?utm_source=repo&utm_medium=web&utm_campaign=pluginDesc)
|
108 |
|
109 |
= What does Wordfence Security do that other WordPress security plugins don't do? =
|
110 |
-
|
111 |
-
* Wordfence Security is the only WordPress security plugin that is fully integrated with it's own high speed caching engine to avoid security and caching conflicts.
|
112 |
* Wordfence Security actually verifies your website source code integrity against the official WordPress repository and shows you the changes. We are the only plugin to do this.
|
113 |
* Wordfence Security provides two-factor authentication (Cellphone Sign-in) for paid members. We're the first plugin to offer this.
|
114 |
* Wordfence Security fully supports IPv6 including giving you the ability to look up the location of IPv6 addresses, block IPv6 ranges, detect IPv6 country and do a whois lookup on IPv6 addresses and more.
|
@@ -124,10 +119,8 @@ Yes. WordPress MU or Multi-Site as it's called now is fully supported. Using Wor
|
|
124 |
|
125 |
= Will Wordfence Security slow my site down? =
|
126 |
|
127 |
-
No.
|
128 |
-
|
129 |
-
versions of Wordfence did incur a slight performance penalty, but we have not only fixed this issue but knocked it out of the park. Wordfence
|
130 |
-
now makes your site faster than any other caching plugin available!!
|
131 |
|
132 |
= How often is Wordfence Security updated? =
|
133 |
|
@@ -197,6 +190,21 @@ Secure your website with Wordfence.
|
|
197 |
|
198 |
== Changelog ==
|
199 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
200 |
= 6.2.0 =
|
201 |
* Improvement: Massive performance boost in file system scan.
|
202 |
* Improvement: Added low resource usage scan option for shared hosts.
|
1 |
=== Wordfence Security ===
|
2 |
Contributors: mmaunder
|
3 |
+
Tags: security, secure, security plugin, wordpress security, login security, firewall, malware, antivirus, web application firewall, block hackers, country blocking
|
4 |
Requires at least: 3.9
|
5 |
Tested up to: 4.6.1
|
6 |
+
Stable tag: 6.2.1
|
7 |
|
8 |
+
Secure your website with the most comprehensive WordPress security plugin. Firewall, malware scan, blocking, live traffic, login security & more.
|
9 |
|
10 |
== Description ==
|
11 |
= THE MOST DOWNLOADED WORDPRESS SECURITY PLUGIN =
|
61 |
|
62 |
= Multi-Site Security =
|
63 |
* Wordfence Security for multi-site also scans all posts and comments across all blogs from one admin panel.
|
64 |
+
* WordPress Multi-Site (or WordPress MU in the older parlance) compatible.
|
|
|
|
|
|
|
|
|
65 |
|
66 |
= IPv6 Compatible =
|
67 |
* Fully IPv6 compatible including all whois lookup, location, blocking and security functions.
|
103 |
[Visit our support website which contains a FAQ and knowledgebase which is more comprehensive and updated frequently.](http://support.wordfence.com/?utm_source=repo&utm_medium=web&utm_campaign=pluginDesc)
|
104 |
|
105 |
= What does Wordfence Security do that other WordPress security plugins don't do? =
|
106 |
+
|
|
|
107 |
* Wordfence Security actually verifies your website source code integrity against the official WordPress repository and shows you the changes. We are the only plugin to do this.
|
108 |
* Wordfence Security provides two-factor authentication (Cellphone Sign-in) for paid members. We're the first plugin to offer this.
|
109 |
* Wordfence Security fully supports IPv6 including giving you the ability to look up the location of IPv6 addresses, block IPv6 ranges, detect IPv6 country and do a whois lookup on IPv6 addresses and more.
|
119 |
|
120 |
= Will Wordfence Security slow my site down? =
|
121 |
|
122 |
+
No. Wordfence is extremely fast and uses techniques like caching its own configuration data to avoid database lookups and blocking malicious attacks that would slow down your site. Older
|
123 |
+
versions of Wordfence did incur a slight performance penalty, but we have not only fixed this issue but knocked it out of the park.
|
|
|
|
|
124 |
|
125 |
= How often is Wordfence Security updated? =
|
126 |
|
190 |
|
191 |
== Changelog ==
|
192 |
|
193 |
+
= 6.2.1 =
|
194 |
+
* Improvement: Now performing scanning for PHP code in all uploaded files in real-time.
|
195 |
+
* Improvement: Improved handling of bad characters and IPv6 ranges in Advanced Blocking.
|
196 |
+
* Improvement: Live traffic and scanning activity now display a paused notice when real-time updates are suspended while in the background.
|
197 |
+
* Improvement: The file system scan alerts for files flagged by antivirus software with a '.suspected' extension.
|
198 |
+
* Improvement: New alert option to get notified only when logins are from a new location/device.
|
199 |
+
* Change: First phase for removing the Falcon cache in place, which will add a notice of its pending removal.
|
200 |
+
* Fix: Included country flags for Kosovo and Curaçao.
|
201 |
+
* Fix: Fixed the .htaccess directives used to hide files found by the scanner.
|
202 |
+
* Fix: Dashboard widget shows correct status for failed logins by deleted users.
|
203 |
+
* Fix: Removed duplicate issues for modified files in the scan results.
|
204 |
+
* Fix: Suppressed warning from reverse lookup on IPv6 addresses without valid DNS records.
|
205 |
+
* Fix: Fixed file inclusion error with themes lacking a 404 page.
|
206 |
+
* Fix: CSS fixes for activity report email.
|
207 |
+
|
208 |
= 6.2.0 =
|
209 |
* Improvement: Massive performance boost in file system scan.
|
210 |
* Improvement: Added low resource usage scan option for shared hosts.
|
vendor/wordfence/wf-waf/src/init.php
CHANGED
@@ -4,7 +4,7 @@ define('WFWAF_VERSION', '1.0.2');
|
|
4 |
define('WFWAF_PATH', dirname(__FILE__) . '/');
|
5 |
define('WFWAF_LIB_PATH', WFWAF_PATH . 'lib/');
|
6 |
define('WFWAF_VIEW_PATH', WFWAF_PATH . 'views/');
|
7 |
-
define('WFWAF_API_URL_SEC', 'https://noc4.wordfence.com/v1.
|
8 |
if (!defined('WFWAF_DEBUG')) {
|
9 |
define('WFWAF_DEBUG', false);
|
10 |
}
|
4 |
define('WFWAF_PATH', dirname(__FILE__) . '/');
|
5 |
define('WFWAF_LIB_PATH', WFWAF_PATH . 'lib/');
|
6 |
define('WFWAF_VIEW_PATH', WFWAF_PATH . 'views/');
|
7 |
+
define('WFWAF_API_URL_SEC', 'https://noc4.wordfence.com/v1.5/');
|
8 |
if (!defined('WFWAF_DEBUG')) {
|
9 |
define('WFWAF_DEBUG', false);
|
10 |
}
|
vendor/wordfence/wf-waf/src/lib/rules.php
CHANGED
@@ -457,6 +457,7 @@ class wfWAFRuleComparison implements wfWAFRuleInterface {
|
|
457 |
'currentuserisnot',
|
458 |
'md5equals',
|
459 |
'filepatternsmatch',
|
|
|
460 |
);
|
461 |
|
462 |
/**
|
@@ -711,7 +712,7 @@ class wfWAFRuleComparison implements wfWAFRuleInterface {
|
|
711 |
if ($file['name'] == (string) $subject) {
|
712 |
$fh = @fopen($file['tmp_name'], 'r');
|
713 |
if (!$fh) {
|
714 |
-
|
715 |
}
|
716 |
$totalRead = 0;
|
717 |
|
@@ -734,6 +735,122 @@ class wfWAFRuleComparison implements wfWAFRuleInterface {
|
|
734 |
|
735 |
return false;
|
736 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
737 |
|
738 |
/**
|
739 |
* @return mixed
|
457 |
'currentuserisnot',
|
458 |
'md5equals',
|
459 |
'filepatternsmatch',
|
460 |
+
'filehasphp',
|
461 |
);
|
462 |
|
463 |
/**
|
712 |
if ($file['name'] == (string) $subject) {
|
713 |
$fh = @fopen($file['tmp_name'], 'r');
|
714 |
if (!$fh) {
|
715 |
+
continue;
|
716 |
}
|
717 |
$totalRead = 0;
|
718 |
|
735 |
|
736 |
return false;
|
737 |
}
|
738 |
+
|
739 |
+
public function fileHasPHP($subject) {
|
740 |
+
$request = $this->getWAF()->getRequest();
|
741 |
+
$files = $request->getFiles();
|
742 |
+
if (!is_array($files)) {
|
743 |
+
return false;
|
744 |
+
}
|
745 |
+
|
746 |
+
foreach ($files as $file) {
|
747 |
+
if ($file['name'] == (string) $subject) {
|
748 |
+
$fh = @fopen($file['tmp_name'], 'r');
|
749 |
+
if (!$fh) {
|
750 |
+
continue;
|
751 |
+
}
|
752 |
+
|
753 |
+
$totalRead = 0;
|
754 |
+
$hasExecutablePHP = false;
|
755 |
+
$possiblyHasExecutablePHP = false;
|
756 |
+
$hasOpenParen = false;
|
757 |
+
$hasCloseParen = false;
|
758 |
+
$backtickCount = 0;
|
759 |
+
$wrappedTokenCheckBytes = '';
|
760 |
+
$maxTokenSize = 15; //__halt_compiler
|
761 |
+
$possibleWrappedTokens = array('<?php', '<?=', '<?', '?>', 'exit', 'new', 'clone', 'echo', 'print', 'require', 'include', 'require_once', 'include_once', '__halt_compiler');
|
762 |
+
|
763 |
+
$readsize = 512 * 1024; //512k at a time
|
764 |
+
while (!feof($fh)) {
|
765 |
+
$data = fread($fh, $readsize);
|
766 |
+
$actualReadsize = strlen($data);
|
767 |
+
$totalRead += $actualReadsize;
|
768 |
+
if ($totalRead < 1) {
|
769 |
+
break;
|
770 |
+
}
|
771 |
+
|
772 |
+
//Make sure we didn't miss PHP split over a chunking boundary
|
773 |
+
$wrappedCheckLength = strlen($wrappedTokenCheckBytes);
|
774 |
+
if ($wrappedCheckLength > 0) {
|
775 |
+
$testBytes = $wrappedTokenCheckBytes . substr($data, 0, min($maxTokenSize, $actualReadsize));
|
776 |
+
foreach ($possibleWrappedTokens as $t) {
|
777 |
+
$position = strpos($testBytes, $t);
|
778 |
+
if ($position !== false && $position < $wrappedCheckLength && $position + strlen($t) >= $wrappedCheckLength) { //Found a token that starts before this segment of data and ends within it
|
779 |
+
$data = substr($wrappedTokenCheckBytes, $position) . $data;
|
780 |
+
break;
|
781 |
+
}
|
782 |
+
}
|
783 |
+
}
|
784 |
+
|
785 |
+
//Tokenize the data and check for PHP
|
786 |
+
$tokens = @token_get_all($data);
|
787 |
+
foreach ($tokens as $token) {
|
788 |
+
if (is_array($token)) {
|
789 |
+
switch ($token[0]) {
|
790 |
+
case T_OPEN_TAG:
|
791 |
+
$hasOpenParen = false;
|
792 |
+
$hasCloseParen = false;
|
793 |
+
$backtickCount = 0;
|
794 |
+
$possiblyHasExecutablePHP = false;
|
795 |
+
break;
|
796 |
+
|
797 |
+
case T_OPEN_TAG_WITH_ECHO:
|
798 |
+
$hasOpenParen = false;
|
799 |
+
$hasCloseParen = false;
|
800 |
+
$backtickCount = 0;
|
801 |
+
$possiblyHasExecutablePHP = true;
|
802 |
+
break;
|
803 |
+
|
804 |
+
case T_CLOSE_TAG:
|
805 |
+
if ($possiblyHasExecutablePHP) {
|
806 |
+
$hasExecutablePHP = true; //Assume the echo short tag outputted something useful
|
807 |
+
}
|
808 |
+
break 2;
|
809 |
+
|
810 |
+
case T_NEW:
|
811 |
+
case T_CLONE:
|
812 |
+
case T_ECHO:
|
813 |
+
case T_PRINT:
|
814 |
+
case T_REQUIRE:
|
815 |
+
case T_INCLUDE:
|
816 |
+
case T_REQUIRE_ONCE:
|
817 |
+
case T_INCLUDE_ONCE:
|
818 |
+
case T_HALT_COMPILER:
|
819 |
+
case T_EXIT:
|
820 |
+
$hasExecutablePHP = true;
|
821 |
+
break 2;
|
822 |
+
}
|
823 |
+
}
|
824 |
+
else {
|
825 |
+
switch ($token) {
|
826 |
+
case '(':
|
827 |
+
$hasOpenParen = true;
|
828 |
+
break;
|
829 |
+
case ')':
|
830 |
+
$hasCloseParen = true;
|
831 |
+
break;
|
832 |
+
case '`':
|
833 |
+
$backtickCount++;
|
834 |
+
break;
|
835 |
+
}
|
836 |
+
}
|
837 |
+
if (!$hasExecutablePHP && (($hasOpenParen && $hasCloseParen) || ($backtickCount > 1 && $backtickCount % 2 === 0))) {
|
838 |
+
$hasExecutablePHP = true;
|
839 |
+
break;
|
840 |
+
}
|
841 |
+
}
|
842 |
+
|
843 |
+
if ($hasExecutablePHP) {
|
844 |
+
return true;
|
845 |
+
}
|
846 |
+
|
847 |
+
$wrappedTokenCheckBytes = substr($data, - min($maxTokenSize, $actualReadsize));
|
848 |
+
}
|
849 |
+
}
|
850 |
+
}
|
851 |
+
|
852 |
+
return false;
|
853 |
+
}
|
854 |
|
855 |
/**
|
856 |
* @return mixed
|
views/reports/activity-report-email-inline.php
CHANGED
@@ -89,8 +89,8 @@ a.comment-edit-link:hover { color: #21759b !important; }
|
|
89 |
@viewport { width: device-width !important; }
|
90 |
.main-navigation li a:hover { color: #000 !important; }
|
91 |
.main-navigation li a:focus { color: #000 !important; }
|
92 |
-
.main-navigation ul li:hover
|
93 |
-
.main-navigation ul li:focus
|
94 |
.main-navigation li ul li a:hover { background: #e3e3e3 !important; color: #444 !important; }
|
95 |
.main-navigation li ul li a:focus { background: #e3e3e3 !important; color: #444 !important; }
|
96 |
footer a[rel=bookmark]:after { content: " [" attr(href) "] " !important; }
|
89 |
@viewport { width: device-width !important; }
|
90 |
.main-navigation li a:hover { color: #000 !important; }
|
91 |
.main-navigation li a:focus { color: #000 !important; }
|
92 |
+
.main-navigation ul li:hover > ul { border-left: 0 !important; clip: inherit !important; overflow: inherit !important; height: inherit !important; width: inherit !important; }
|
93 |
+
.main-navigation ul li:focus > ul { border-left: 0 !important; clip: inherit !important; overflow: inherit !important; height: inherit !important; width: inherit !important; }
|
94 |
.main-navigation li ul li a:hover { background: #e3e3e3 !important; color: #444 !important; }
|
95 |
.main-navigation li ul li a:focus { background: #e3e3e3 !important; color: #444 !important; }
|
96 |
footer a[rel=bookmark]:after { content: " [" attr(href) "] " !important; }
|
views/waf/debug.php
CHANGED
@@ -111,7 +111,7 @@ try {
|
|
111 |
margin: 20px 0px 8px;
|
112 |
}
|
113 |
pre, p {
|
114 |
-
8px 0px 20px;
|
115 |
}
|
116 |
pre.request-debug {
|
117 |
padding: 12px;
|
111 |
margin: 20px 0px 8px;
|
112 |
}
|
113 |
pre, p {
|
114 |
+
margin: 8px 0px 20px;
|
115 |
}
|
116 |
pre.request-debug {
|
117 |
padding: 12px;
|
waf/wfWAFUserIPRange.php
CHANGED
@@ -50,9 +50,11 @@ class wfWAFUserIPRange {
|
|
50 |
|
51 |
// IPv6 range
|
52 |
} else if (strpos($ip_string, ':') !== false && strpos($ip, ':') !== false) {
|
53 |
-
|
54 |
-
|
55 |
-
|
|
|
|
|
56 |
$mismatch = false;
|
57 |
for ($i = 0; $i <= 7; $i++) {
|
58 |
if (preg_match('/^\[([a-f0-9]+)\-([a-f0-9]+)\]$/i', $whiteParts[$i], $m)) {
|
@@ -219,6 +221,6 @@ class wfWAFUserIPRange {
|
|
219 |
* @param string|null $ip_string
|
220 |
*/
|
221 |
public function setIPString($ip_string) {
|
222 |
-
$this->ip_string = $ip_string;
|
223 |
}
|
224 |
}
|
50 |
|
51 |
// IPv6 range
|
52 |
} else if (strpos($ip_string, ':') !== false && strpos($ip, ':') !== false) {
|
53 |
+
$ip = strtolower(wfWAFUtils::expandIPv6Address($ip));
|
54 |
+
$ip_string = strtolower(self::expandIPv6Range($ip_string));
|
55 |
+
if (preg_match('/\[[a-f0-9]+\-[a-f0-9]+\]/i', $ip_string)) {
|
56 |
+
$IPparts = explode(':', $ip);
|
57 |
+
$whiteParts = explode(':', $ip_string);
|
58 |
$mismatch = false;
|
59 |
for ($i = 0; $i <= 7; $i++) {
|
60 |
if (preg_match('/^\[([a-f0-9]+)\-([a-f0-9]+)\]$/i', $whiteParts[$i], $m)) {
|
221 |
* @param string|null $ip_string
|
222 |
*/
|
223 |
public function setIPString($ip_string) {
|
224 |
+
$this->ip_string = preg_replace('/[\x{2013}-\x{2015}]/u', '-', $ip_string); //Replace em-dash, en-dash, and horizontal bar with a regular dash
|
225 |
}
|
226 |
}
|
wordfence.php
CHANGED
@@ -2,16 +2,16 @@
|
|
2 |
/*
|
3 |
Plugin Name: Wordfence Security
|
4 |
Plugin URI: http://www.wordfence.com/
|
5 |
-
Description: Wordfence Security - Anti-virus, Firewall and
|
6 |
Author: Wordfence
|
7 |
-
Version: 6.2.
|
8 |
Author URI: http://www.wordfence.com/
|
9 |
Network: true
|
10 |
*/
|
11 |
if(defined('WP_INSTALLING') && WP_INSTALLING){
|
12 |
return;
|
13 |
}
|
14 |
-
define('WORDFENCE_VERSION', '6.2.
|
15 |
define('WORDFENCE_BASENAME', function_exists('plugin_basename') ? plugin_basename(__FILE__) :
|
16 |
basename(dirname(__FILE__)) . '/' . basename(__FILE__));
|
17 |
|
2 |
/*
|
3 |
Plugin Name: Wordfence Security
|
4 |
Plugin URI: http://www.wordfence.com/
|
5 |
+
Description: Wordfence Security - Anti-virus, Firewall and Malware Scan
|
6 |
Author: Wordfence
|
7 |
+
Version: 6.2.1
|
8 |
Author URI: http://www.wordfence.com/
|
9 |
Network: true
|
10 |
*/
|
11 |
if(defined('WP_INSTALLING') && WP_INSTALLING){
|
12 |
return;
|
13 |
}
|
14 |
+
define('WORDFENCE_VERSION', '6.2.1');
|
15 |
define('WORDFENCE_BASENAME', function_exists('plugin_basename') ? plugin_basename(__FILE__) :
|
16 |
basename(dirname(__FILE__)) . '/' . basename(__FILE__));
|
17 |
|