Version Description
- Improvement: Reworked blocking for IP ranges, country blocking, and direct IP blocking to minimize server impact when under attack.
- Improvement: Live traffic better indicates the action taken by country blocking when it redirects a visitor.
- Improvement: Added support for finding server logs to the Diagnostics page to help with troubleshooting.
- Improvement: Whitelisted StatusCake IP addresses.
- Improvement: Updated GeoIP database.
- Improvement: Disabling Wordfence now sends an alert.
- Improvement: Improved detection for uploaded PHP content in the firewall.
- Fix: Eliminated memory-related errors resulting from the scan on sites with very large numbers of issues and low memory.
- Fix: Fixed admin page layout for sites using RTL languages.
- Fix: Reduced overhead of the dashboard widget.
- Fix: Improved performance of checking for whitelisted IPs.
- Fix: Changes to the default plugin hello.php are now detected correctly in scans.
- Fix: Fixed IPv6 warning in the dashboard widget.
Download this release
Release Info
Developer | wfryan |
Plugin | Wordfence Security – Firewall & Malware Scan |
Version | 6.2.3 |
Comparing to | |
See all releases |
Code changes from version 6.2.2 to 6.2.3
- js/admin.js +65 -6
- js/admin.liveTraffic.js +1 -0
- lib/GeoIP.dat +0 -0
- lib/GeoIPv6.dat +0 -0
- lib/email_newIssues.php +4 -0
- lib/menu_blockedIPs.php +1 -1
- lib/menu_countryBlocking.php +1 -1
- lib/menu_diagnostic.php +42 -2
- lib/menu_options.php +27 -1
- lib/menu_passwd.php +1 -1
- lib/menu_rangeBlocking.php +1 -1
- lib/menu_scan.php +1 -1
- lib/menu_scanSchedule.php +1 -1
- lib/menu_sitePerf.php +1 -1
- lib/menu_sitePerfStats.php +1 -1
- lib/menu_twoFactor.php +1 -1
- lib/menu_waf.php +14 -4
- lib/menu_whois.php +1 -1
- lib/wf503.php +2 -2
- lib/wfActivityReport.php +0 -12
- lib/wfConfig.php +9 -3
- lib/wfIPWhitelist.php +153 -0
- lib/wfIssues.php +27 -13
- lib/wfLog.php +175 -18
- lib/wfUtils.php +12 -8
- lib/wordfenceClass.php +98 -14
- lib/wordfenceConstants.php +1 -0
- readme.txt +16 -1
- vendor/wordfence/wf-waf/src/lib/request.php +21 -0
- vendor/wordfence/wf-waf/src/lib/rules.php +77 -1
- vendor/wordfence/wf-waf/src/lib/utils.php +196 -0
- vendor/wordfence/wf-waf/src/lib/waf.php +100 -5
- vendor/wordfence/wf-waf/src/views/503.php +35 -0
- waf/bootstrap.php +92 -7
- waf/wfWAFGeoIP.php +765 -0
- waf/wfWAFIPBlocksController.php +394 -0
- waf/wfWAFUserIPRange.php +30 -17
- wordfence.php +2 -2
js/admin.js
CHANGED
@@ -63,6 +63,10 @@
|
|
63 |
$($this.data('selector')).show();
|
64 |
return false;
|
65 |
});
|
|
|
|
|
|
|
|
|
66 |
|
67 |
$('#doSendEmail').click(function() {
|
68 |
var ticket = $('#_ticketnumber').val();
|
@@ -111,11 +115,39 @@
|
|
111 |
jQuery('#consoleActivity').scrollTop(jQuery('#consoleActivity').prop('scrollHeight'));
|
112 |
jQuery('#consoleScan').scrollTop(jQuery('#consoleScan').prop('scrollHeight'));
|
113 |
this.noScanHTML = jQuery('#wfNoScanYetTmpl').tmpl().html();
|
114 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
115 |
this.startActivityLogUpdates();
|
116 |
if (this.needTour()) {
|
117 |
this.scanTourStart();
|
118 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
119 |
} else if (jQuery('#wordfenceMode_waf').length > 0) {
|
120 |
if (this.needTour()) {
|
121 |
this.tour('wfWAFTour', 'wfHeading', 'top', 'left', "Learn about Live Traffic", function() {
|
@@ -321,7 +353,9 @@
|
|
321 |
},
|
322 |
updateConfig: function(key, val, cb) {
|
323 |
this.ajax('wordfence_updateConfig', {key: key, val: val}, function() {
|
324 |
-
cb
|
|
|
|
|
325 |
});
|
326 |
},
|
327 |
tourFinish: function() {
|
@@ -790,15 +824,25 @@
|
|
790 |
jQuery('#wfAuditJobs').empty().html("<p>You don't have any password auditing jobs in progress or completed yet.</p>");
|
791 |
}
|
792 |
},
|
793 |
-
loadIssues: function(callback) {
|
794 |
if (this.mode != 'scan') {
|
795 |
return;
|
796 |
}
|
|
|
|
|
797 |
var self = this;
|
798 |
-
this.ajax('wordfence_loadIssues', {}, function(res) {
|
799 |
self.displayIssues(res, callback);
|
800 |
});
|
801 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
802 |
sev2num: function(str) {
|
803 |
if (/wfProbSev1/.test(str)) {
|
804 |
return 1;
|
@@ -869,7 +913,7 @@
|
|
869 |
"bPaginate": false,
|
870 |
"bLengthChange": false,
|
871 |
"bAutoWidth": false,
|
872 |
-
"aaData": res.issuesLists[issueStatus],
|
873 |
"aoColumns": [
|
874 |
{
|
875 |
"sTitle": '<div class="th_wrapp">Severity</div>',
|
@@ -895,6 +939,22 @@
|
|
895 |
]
|
896 |
});
|
897 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
898 |
if (callback) {
|
899 |
jQuery('#wfIssues_' + this.visibleIssuesPanel).fadeIn(500, function() {
|
900 |
callback();
|
@@ -902,7 +962,6 @@
|
|
902 |
} else {
|
903 |
jQuery('#wfIssues_' + this.visibleIssuesPanel).fadeIn(500);
|
904 |
}
|
905 |
-
return true;
|
906 |
},
|
907 |
ajax: function(action, data, cb, cbErr, noLoading) {
|
908 |
if (typeof(data) == 'string') {
|
63 |
$($this.data('selector')).show();
|
64 |
return false;
|
65 |
});
|
66 |
+
|
67 |
+
$('.downloadLogFile').each(function() {
|
68 |
+
$(this).attr('href', WordfenceAdminVars.ajaxURL + '?action=wordfence_downloadLogFile&nonce=' + WFAD.nonce + '&logfile=' + encodeURIComponent($(this).data('logfile')));
|
69 |
+
});
|
70 |
|
71 |
$('#doSendEmail').click(function() {
|
72 |
var ticket = $('#_ticketnumber').val();
|
115 |
jQuery('#consoleActivity').scrollTop(jQuery('#consoleActivity').prop('scrollHeight'));
|
116 |
jQuery('#consoleScan').scrollTop(jQuery('#consoleScan').prop('scrollHeight'));
|
117 |
this.noScanHTML = jQuery('#wfNoScanYetTmpl').tmpl().html();
|
118 |
+
|
119 |
+
|
120 |
+
var loadingIssues = true;
|
121 |
+
|
122 |
+
this.loadIssues(function() {
|
123 |
+
loadingIssues = false;
|
124 |
+
});
|
125 |
this.startActivityLogUpdates();
|
126 |
if (this.needTour()) {
|
127 |
this.scanTourStart();
|
128 |
}
|
129 |
+
|
130 |
+
var issuesWrapper = $('#wfScanIssuesWrapper');
|
131 |
+
var hasScrolled = false;
|
132 |
+
$(window).on('scroll', function() {
|
133 |
+
var win = $(this);
|
134 |
+
// console.log(win.scrollTop() + window.innerHeight, liveTrafficWrapper.outerHeight() + liveTrafficWrapper.offset().top);
|
135 |
+
var currentScrollBottom = win.scrollTop() + window.innerHeight;
|
136 |
+
var scrollThreshold = issuesWrapper.outerHeight() + issuesWrapper.offset().top;
|
137 |
+
if (hasScrolled && !loadingIssues && currentScrollBottom >= scrollThreshold) {
|
138 |
+
// console.log('infinite scroll');
|
139 |
+
|
140 |
+
loadingIssues = true;
|
141 |
+
hasScrolled = false;
|
142 |
+
var offset = $('div.wfIssue').length;
|
143 |
+
WFAD.loadMoreIssues(function() {
|
144 |
+
loadingIssues = false;
|
145 |
+
}, offset);
|
146 |
+
} else if (currentScrollBottom < scrollThreshold) {
|
147 |
+
hasScrolled = true;
|
148 |
+
// console.log('no infinite scroll');
|
149 |
+
}
|
150 |
+
});
|
151 |
} else if (jQuery('#wordfenceMode_waf').length > 0) {
|
152 |
if (this.needTour()) {
|
153 |
this.tour('wfWAFTour', 'wfHeading', 'top', 'left', "Learn about Live Traffic", function() {
|
353 |
},
|
354 |
updateConfig: function(key, val, cb) {
|
355 |
this.ajax('wordfence_updateConfig', {key: key, val: val}, function() {
|
356 |
+
if (cb) {
|
357 |
+
cb();
|
358 |
+
}
|
359 |
});
|
360 |
},
|
361 |
tourFinish: function() {
|
824 |
jQuery('#wfAuditJobs').empty().html("<p>You don't have any password auditing jobs in progress or completed yet.</p>");
|
825 |
}
|
826 |
},
|
827 |
+
loadIssues: function(callback, offset, limit) {
|
828 |
if (this.mode != 'scan') {
|
829 |
return;
|
830 |
}
|
831 |
+
offset = offset || 0;
|
832 |
+
limit = limit || WordfenceAdminVars.scanIssuesPerPage;
|
833 |
var self = this;
|
834 |
+
this.ajax('wordfence_loadIssues', {offset: offset, limit: limit}, function(res) {
|
835 |
self.displayIssues(res, callback);
|
836 |
});
|
837 |
},
|
838 |
+
loadMoreIssues: function(callback, offset, limit) {
|
839 |
+
offset = offset || 0;
|
840 |
+
limit = limit || WordfenceAdminVars.scanIssuesPerPage;
|
841 |
+
var self = this;
|
842 |
+
this.ajax('wordfence_loadIssues', {offset: offset, limit: limit}, function(res) {
|
843 |
+
self.appendIssues(res.issuesLists, callback);
|
844 |
+
});
|
845 |
+
},
|
846 |
sev2num: function(str) {
|
847 |
if (/wfProbSev1/.test(str)) {
|
848 |
return 1;
|
913 |
"bPaginate": false,
|
914 |
"bLengthChange": false,
|
915 |
"bAutoWidth": false,
|
916 |
+
//"aaData": res.issuesLists[issueStatus],
|
917 |
"aoColumns": [
|
918 |
{
|
919 |
"sTitle": '<div class="th_wrapp">Severity</div>',
|
939 |
]
|
940 |
});
|
941 |
}
|
942 |
+
|
943 |
+
this.appendIssues(res.issuesLists, callback);
|
944 |
+
|
945 |
+
return true;
|
946 |
+
},
|
947 |
+
appendIssues: function(issuesLists, callback) {
|
948 |
+
for (var issueStatus in issuesLists) {
|
949 |
+
var tableID = 'wfIssuesTable_' + issueStatus;
|
950 |
+
if (jQuery('#' + tableID).length < 1) {
|
951 |
+
//Invalid issue status
|
952 |
+
continue;
|
953 |
+
}
|
954 |
+
|
955 |
+
jQuery('#' + tableID).dataTable().fnAddData(issuesLists[issueStatus]);
|
956 |
+
}
|
957 |
+
|
958 |
if (callback) {
|
959 |
jQuery('#wfIssues_' + this.visibleIssuesPanel).fadeIn(500, function() {
|
960 |
callback();
|
962 |
} else {
|
963 |
jQuery('#wfIssues_' + this.visibleIssuesPanel).fadeIn(500);
|
964 |
}
|
|
|
965 |
},
|
966 |
ajax: function(action, data, cb, cbErr, noLoading) {
|
967 |
if (typeof(data) == 'string') {
|
js/admin.liveTraffic.js
CHANGED
@@ -356,6 +356,7 @@
|
|
356 |
case 'lockedOut':
|
357 |
return 'locked out from logging in';
|
358 |
|
|
|
359 |
case 'blocked:wordfence':
|
360 |
case 'blocked:wfsnrepeat':
|
361 |
desc = self.actionDescription();
|
356 |
case 'lockedOut':
|
357 |
return 'locked out from logging in';
|
358 |
|
359 |
+
case 'blocked:waf-always':
|
360 |
case 'blocked:wordfence':
|
361 |
case 'blocked:wfsnrepeat':
|
362 |
desc = self.actionDescription();
|
lib/GeoIP.dat
CHANGED
Binary file
|
lib/GeoIPv6.dat
CHANGED
Binary file
|
lib/email_newIssues.php
CHANGED
@@ -42,6 +42,10 @@
|
|
42 |
|
43 |
<?php } } } ?>
|
44 |
|
|
|
|
|
|
|
|
|
45 |
|
46 |
<?php if(! $isPaid){ ?>
|
47 |
<p>NOTE: You are using the free version of Wordfence. Upgrade today:</p>
|
42 |
|
43 |
<?php } } } ?>
|
44 |
|
45 |
+
<?php if ($issuesNotShown > 0) { ?>
|
46 |
+
<p><?php echo wfUtils::pluralize($issuesNotShown, 'issue'); ?> were omitted from this email. View every issue: <a href="<?php echo $adminURL; ?>admin.php?page=Wordfence"><?php echo $adminURL; ?>admin.php?page=Wordfence</a></p>
|
47 |
+
<?php } ?>
|
48 |
+
|
49 |
|
50 |
<?php if(! $isPaid){ ?>
|
51 |
<p>NOTE: You are using the free version of Wordfence. Upgrade today:</p>
|
lib/menu_blockedIPs.php
CHANGED
@@ -1,5 +1,5 @@
|
|
1 |
<div class="wordfenceModeElem" id="wordfenceMode_blockedIPs"></div>
|
2 |
-
<div class="wrap">
|
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">
|
1 |
<div class="wordfenceModeElem" id="wordfenceMode_blockedIPs"></div>
|
2 |
+
<div class="wrap wordfence">
|
3 |
<?php require('menuHeader.php'); ?>
|
4 |
<?php $helpLink="http://docs.wordfence.com/en/Blocked_IPs"; $helpLabel="Learn more about Blocked IPs"; $pageTitle = "Wordfence Blocked IPs"; include('pageTitle.php'); ?>
|
5 |
<div class="wordfenceLive">
|
lib/menu_countryBlocking.php
CHANGED
@@ -5,7 +5,7 @@ require('wfBulkCountries.php');
|
|
5 |
WFAD.countryMap = <?php echo json_encode($wfBulkCountries); ?>;
|
6 |
</script>
|
7 |
<div class="wordfenceModeElem" id="wordfenceMode_countryBlocking"></div>
|
8 |
-
<div class="wrap" id="paidWrap">
|
9 |
<?php require('menuHeader.php'); ?>
|
10 |
<?php $pageTitle = "Block Selected Countries from Accessing your Site"; $helpLink="http://docs.wordfence.com/en/Country_blocking"; $helpLabel="Learn more about Country Blocking"; include('pageTitle.php'); ?>
|
11 |
<?php
|
5 |
WFAD.countryMap = <?php echo json_encode($wfBulkCountries); ?>;
|
6 |
</script>
|
7 |
<div class="wordfenceModeElem" id="wordfenceMode_countryBlocking"></div>
|
8 |
+
<div class="wrap wordfence" id="paidWrap">
|
9 |
<?php require('menuHeader.php'); ?>
|
10 |
<?php $pageTitle = "Block Selected Countries from Accessing your Site"; $helpLink="http://docs.wordfence.com/en/Country_blocking"; $helpLabel="Learn more about Country Blocking"; include('pageTitle.php'); ?>
|
11 |
<?php
|
lib/menu_diagnostic.php
CHANGED
@@ -19,8 +19,11 @@ $w = new wfConfig();
|
|
19 |
<br clear="both"/>
|
20 |
|
21 |
<?php
|
22 |
-
$
|
23 |
-
|
|
|
|
|
|
|
24 |
?>
|
25 |
|
26 |
<form id="wfConfigForm">
|
@@ -346,6 +349,43 @@ $w = new wfConfig();
|
|
346 |
</table>
|
347 |
</div>
|
348 |
<?php endif ?>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
349 |
</form>
|
350 |
</div>
|
351 |
|
19 |
<br clear="both"/>
|
20 |
|
21 |
<?php
|
22 |
+
if (!isset($sendingDiagnosticEmail)) { $sendingDiagnosticEmail = false; }
|
23 |
+
if (!$sendingDiagnosticEmail) {
|
24 |
+
$rightRail = new wfView('marketing/rightrail', array('additionalClasses' => 'wordfenceRightRailDiagnostics'));
|
25 |
+
echo $rightRail;
|
26 |
+
}
|
27 |
?>
|
28 |
|
29 |
<form id="wfConfigForm">
|
349 |
</table>
|
350 |
</div>
|
351 |
<?php endif ?>
|
352 |
+
<div style="max-width: 100%; overflow: auto; padding: 1px;">
|
353 |
+
<table class="wf-table"<?php echo !empty($inEmail) ? ' border=1' : '' ?>>
|
354 |
+
<tbody class="empty-row">
|
355 |
+
<tr>
|
356 |
+
<td colspan="2"></td>
|
357 |
+
</tr>
|
358 |
+
</tbody>
|
359 |
+
<tbody class="thead">
|
360 |
+
<tr>
|
361 |
+
<th colspan="2">Log Files (Error messages from WordPress core, plugins, and themes)</th>
|
362 |
+
</tr>
|
363 |
+
</tbody>
|
364 |
+
<tbody class="thead thead-subhead" style="font-size: 85%">
|
365 |
+
<tr>
|
366 |
+
<th>File</th>
|
367 |
+
<th>Download</th>
|
368 |
+
</tr>
|
369 |
+
</tbody>
|
370 |
+
<tbody style="font-size: 85%">
|
371 |
+
<?php
|
372 |
+
$errorLogs = wfErrorLogHandler::getErrorLogs();
|
373 |
+
if (count($errorLogs) < 1): ?>
|
374 |
+
<tr>
|
375 |
+
<td colspan="2"><em>No log files found.</em></td>
|
376 |
+
</tr>
|
377 |
+
<?php else:
|
378 |
+
foreach ($errorLogs as $log => $readable): ?>
|
379 |
+
<tr>
|
380 |
+
<td style="width: 100%"><?php echo esc_html($log) . ' (' . wfUtils::formatBytes(filesize($log)) . ')'; ?></td>
|
381 |
+
<td style="white-space: nowrap; text-align: right;"><?php echo ($readable ? '<a href="#" data-logfile="' . esc_html($log) . '" class="downloadLogFile" target="_blank">Download</a>' : '<em>Requires downloading from the server directly</em>'); ?></td>
|
382 |
+
</tr>
|
383 |
+
<?php endforeach;
|
384 |
+
endif; ?>
|
385 |
+
</tbody>
|
386 |
+
|
387 |
+
</table>
|
388 |
+
</div>
|
389 |
</form>
|
390 |
</div>
|
391 |
|
lib/menu_options.php
CHANGED
@@ -2,7 +2,7 @@
|
|
2 |
$w = new wfConfig();
|
3 |
?>
|
4 |
<div class="wordfenceModeElem" id="wordfenceMode_options"></div>
|
5 |
-
<div class="wrap">
|
6 |
<?php require( 'menuHeader.php' ); ?>
|
7 |
<?php $helpLink = "http://docs.wordfence.com/en/Wordfence_options";
|
8 |
$helpLabel = "Learn more about Wordfence Options";
|
@@ -271,6 +271,12 @@ $w = new wfConfig();
|
|
271 |
enabled (see above), you'll get an email when an update occurs.
|
272 |
</td>
|
273 |
</tr>
|
|
|
|
|
|
|
|
|
|
|
|
|
274 |
<tr>
|
275 |
<th>Alert on critical problems</th>
|
276 |
<td><input type="checkbox" id="alertOn_critical" class="wfConfigElem" name="alertOn_critical"
|
@@ -618,6 +624,14 @@ $w = new wfConfig();
|
|
618 |
name="scan_exclude"><?php echo wfUtils::cleanupOneEntryPerLine($w->getHTML( 'scan_exclude' )); ?></textarea>
|
619 |
</td>
|
620 |
</tr>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
621 |
<tr>
|
622 |
<td colspan="2">
|
623 |
<div class="wfMarker" id="wfMarkerFirewallRules"></div>
|
@@ -1031,6 +1045,18 @@ $w = new wfConfig();
|
|
1031 |
name="disableCodeExecutionUploads"
|
1032 |
value="1" <?php $w->cb( 'disableCodeExecutionUploads' ); ?> /></td>
|
1033 |
</tr>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1034 |
|
1035 |
<tr>
|
1036 |
<td colspan="2">
|
2 |
$w = new wfConfig();
|
3 |
?>
|
4 |
<div class="wordfenceModeElem" id="wordfenceMode_options"></div>
|
5 |
+
<div class="wrap wordfence">
|
6 |
<?php require( 'menuHeader.php' ); ?>
|
7 |
<?php $helpLink = "http://docs.wordfence.com/en/Wordfence_options";
|
8 |
$helpLabel = "Learn more about Wordfence Options";
|
271 |
enabled (see above), you'll get an email when an update occurs.
|
272 |
</td>
|
273 |
</tr>
|
274 |
+
<tr>
|
275 |
+
<th>Email me if Wordfence is deactivated</th>
|
276 |
+
<td><input type="checkbox" id="alertOn_wordfenceDeactivated" class="wfConfigElem" name="alertOn_wordfenceDeactivated"
|
277 |
+
value="1" <?php $w->cb( 'alertOn_wordfenceDeactivated' ); ?>/>
|
278 |
+
</td>
|
279 |
+
</tr>
|
280 |
<tr>
|
281 |
<th>Alert on critical problems</th>
|
282 |
<td><input type="checkbox" id="alertOn_critical" class="wfConfigElem" name="alertOn_critical"
|
624 |
name="scan_exclude"><?php echo wfUtils::cleanupOneEntryPerLine($w->getHTML( 'scan_exclude' )); ?></textarea>
|
625 |
</td>
|
626 |
</tr>
|
627 |
+
<tr>
|
628 |
+
<th>Limit the number of issues sent in the scan results email.</th>
|
629 |
+
<td>
|
630 |
+
<input type="text" name="scan_maxIssues" id="scan_maxIssues"
|
631 |
+
value="<?php $w->f( 'scan_maxIssues' ); ?>"/> 0 or empty means unlimited
|
632 |
+
issues will be sent.
|
633 |
+
</td>
|
634 |
+
</tr>
|
635 |
<tr>
|
636 |
<td colspan="2">
|
637 |
<div class="wfMarker" id="wfMarkerFirewallRules"></div>
|
1045 |
name="disableCodeExecutionUploads"
|
1046 |
value="1" <?php $w->cb( 'disableCodeExecutionUploads' ); ?> /></td>
|
1047 |
</tr>
|
1048 |
+
<tr class="hidden">
|
1049 |
+
<th style="vertical-align: top;">Monitor Front-end Background Requests for False Positives</th>
|
1050 |
+
<td><input type="checkbox" name="ajaxWatcherDisabled_front" id="ajaxWatcherDisabled_front" value="1" <?php $w->cb( 'ajaxWatcherDisabled_front' ); ?>></td>
|
1051 |
+
</tr>
|
1052 |
+
<tr class="hidden">
|
1053 |
+
<th style="vertical-align: top;">Monitor Admin Panel Background Requests for False Positives</th>
|
1054 |
+
<td><input type="checkbox" name="ajaxWatcherDisabled_admin" id="ajaxWatcherDisabled_admin" value="1" <?php $w->cb( 'ajaxWatcherDisabled_admin' ); ?>></td>
|
1055 |
+
</tr>
|
1056 |
+
<tr class="hidden">
|
1057 |
+
<th style="vertical-align: top;">Delay IP and Country blocking until after WordPress and plugins have loaded (only process firewall rules early)</th>
|
1058 |
+
<td><input type="checkbox" name="disableWAFIPBlocking" id="disableWAFIPBlocking" value="1" <?php $w->cb( 'disableWAFIPBlocking' ); ?>></td>
|
1059 |
+
</tr>
|
1060 |
|
1061 |
<tr>
|
1062 |
<td colspan="2">
|
lib/menu_passwd.php
CHANGED
@@ -1,5 +1,5 @@
|
|
1 |
<div class="wordfenceModeElem" id="wordfenceMode_passwd"></div>
|
2 |
-
<div class="wrap" id="paidWrap">
|
3 |
<?php require('menuHeader.php'); ?>
|
4 |
<?php $pageTitle = "Audit the Strength of your Passwords";
|
5 |
$helpLink = "http://docs.wordfence.com/en/Wordfence_Password_Auditing";
|
1 |
<div class="wordfenceModeElem" id="wordfenceMode_passwd"></div>
|
2 |
+
<div class="wrap wordfence" id="paidWrap">
|
3 |
<?php require('menuHeader.php'); ?>
|
4 |
<?php $pageTitle = "Audit the Strength of your Passwords";
|
5 |
$helpLink = "http://docs.wordfence.com/en/Wordfence_Password_Auditing";
|
lib/menu_rangeBlocking.php
CHANGED
@@ -1,5 +1,5 @@
|
|
1 |
<div class="wordfenceModeElem" id="wordfenceMode_rangeBlocking"></div>
|
2 |
-
<div class="wrap" id="paidWrap">
|
3 |
<?php require('menuHeader.php'); ?>
|
4 |
<?php $helpLink="http://docs.wordfence.com/en/Advanced_Blocking"; $helpLabel="Learn more about Advanced Blocking"; $pageTitle = "Advanced Blocking"; include('pageTitle.php'); ?>
|
5 |
<?php
|
1 |
<div class="wordfenceModeElem" id="wordfenceMode_rangeBlocking"></div>
|
2 |
+
<div class="wrap wordfence" id="paidWrap">
|
3 |
<?php require('menuHeader.php'); ?>
|
4 |
<?php $helpLink="http://docs.wordfence.com/en/Advanced_Blocking"; $helpLabel="Learn more about Advanced Blocking"; $pageTitle = "Advanced Blocking"; include('pageTitle.php'); ?>
|
5 |
<?php
|
lib/menu_scan.php
CHANGED
@@ -163,7 +163,7 @@ $sigUpdateTime = wfConfig::get('signatureUpdateTime');
|
|
163 |
|
164 |
|
165 |
</div>
|
166 |
-
<div style="margin-top: 20px;">
|
167 |
<div id="wfTabs">
|
168 |
<a href="#" id="wfNewIssuesTab" class="wfTab2 wfTabSwitch selected" onclick="wordfenceAdmin.switchIssuesTab(this, 'new'); return false;">New Issues</a>
|
169 |
<a href="#" class="wfTab2 wfTabSwitch" onclick="wordfenceAdmin.switchIssuesTab(this, 'ignored'); return false;">Ignored Issues</a>
|
163 |
|
164 |
|
165 |
</div>
|
166 |
+
<div id="wfScanIssuesWrapper" style="margin-top: 20px;">
|
167 |
<div id="wfTabs">
|
168 |
<a href="#" id="wfNewIssuesTab" class="wfTab2 wfTabSwitch selected" onclick="wordfenceAdmin.switchIssuesTab(this, 'new'); return false;">New Issues</a>
|
169 |
<a href="#" class="wfTab2 wfTabSwitch" onclick="wordfenceAdmin.switchIssuesTab(this, 'ignored'); return false;">Ignored Issues</a>
|
lib/menu_scanSchedule.php
CHANGED
@@ -1,5 +1,5 @@
|
|
1 |
<div class="wordfenceModeElem" id="wordfenceMode_scanScheduling"></div>
|
2 |
-
<div class="wrap" id="paidWrap">
|
3 |
<?php require('menuHeader.php'); ?>
|
4 |
<?php $pageTitle = "Schedule when Wordfence Scans Occur"; $helpLink="http://docs.wordfence.com/en/Wordfence_scan_scheduling"; $helpLabel="Learn more about Scheduling Wordfence Scans"; include('pageTitle.php'); ?>
|
5 |
<?php
|
1 |
<div class="wordfenceModeElem" id="wordfenceMode_scanScheduling"></div>
|
2 |
+
<div class="wrap wordfence" id="paidWrap">
|
3 |
<?php require('menuHeader.php'); ?>
|
4 |
<?php $pageTitle = "Schedule when Wordfence Scans Occur"; $helpLink="http://docs.wordfence.com/en/Wordfence_scan_scheduling"; $helpLabel="Learn more about Scheduling Wordfence Scans"; include('pageTitle.php'); ?>
|
5 |
<?php
|
lib/menu_sitePerf.php
CHANGED
@@ -2,7 +2,7 @@
|
|
2 |
$w = new wfConfig();
|
3 |
?>
|
4 |
<div class="wordfenceModeElem" id="wordfenceMode_caching"></div>
|
5 |
-
<div class="wrap">
|
6 |
<?php require('menuHeader.php'); ?>
|
7 |
<?php $pageTitle = "Your Site Performance"; $helpLink="http://docs.wordfence.com/en/Falcon_Cache"; $helpLabel="Learn more about Wordfence Caching"; include('pageTitle.php'); ?>
|
8 |
<?php
|
2 |
$w = new wfConfig();
|
3 |
?>
|
4 |
<div class="wordfenceModeElem" id="wordfenceMode_caching"></div>
|
5 |
+
<div class="wrap wordfence">
|
6 |
<?php require('menuHeader.php'); ?>
|
7 |
<?php $pageTitle = "Your Site Performance"; $helpLink="http://docs.wordfence.com/en/Falcon_Cache"; $helpLabel="Learn more about Wordfence Caching"; include('pageTitle.php'); ?>
|
8 |
<?php
|
lib/menu_sitePerfStats.php
CHANGED
@@ -44,7 +44,7 @@
|
|
44 |
}
|
45 |
</style>
|
46 |
|
47 |
-
<div class="wrap">
|
48 |
<?php require('menuHeader.php'); ?>
|
49 |
<div class="wordfence-lock-icon wordfence-icon32"><br /></div>
|
50 |
<h2 id="wfHeading">
|
44 |
}
|
45 |
</style>
|
46 |
|
47 |
+
<div class="wrap wordfence">
|
48 |
<?php require('menuHeader.php'); ?>
|
49 |
<div class="wordfence-lock-icon wordfence-icon32"><br /></div>
|
50 |
<h2 id="wfHeading">
|
lib/menu_twoFactor.php
CHANGED
@@ -1,5 +1,5 @@
|
|
1 |
<div class="wordfenceModeElem" id="wordfenceMode_twoFactor"></div>
|
2 |
-
<div class="wrap" id="paidWrap">
|
3 |
<?php require('menuHeader.php'); ?>
|
4 |
<?php $pageTitle = "Cellphone Sign-in"; $helpLink="http://docs.wordfence.com/en/Cellphone_sign-in"; $helpLabel="Learn more about Cellphone Sign-in"; include('pageTitle.php'); ?>
|
5 |
<?php
|
1 |
<div class="wordfenceModeElem" id="wordfenceMode_twoFactor"></div>
|
2 |
+
<div class="wrap wordfence" id="paidWrap">
|
3 |
<?php require('menuHeader.php'); ?>
|
4 |
<?php $pageTitle = "Cellphone Sign-in"; $helpLink="http://docs.wordfence.com/en/Cellphone_sign-in"; $helpLabel="Learn more about Cellphone Sign-in"; include('pageTitle.php'); ?>
|
5 |
<?php
|
lib/menu_waf.php
CHANGED
@@ -5,7 +5,7 @@ $wafConfigURL = network_admin_url('admin.php?page=WordfenceWAF&wafAction=configu
|
|
5 |
$wafRemoveURL = network_admin_url('admin.php?page=WordfenceWAF&wafAction=removeAutoPrepend');
|
6 |
/** @var array $wafData */
|
7 |
?>
|
8 |
-
<div class="wrap" id="paidWrap">
|
9 |
<?php require('menuHeader.php'); ?>
|
10 |
<?php
|
11 |
$pageTitle = "Wordfence Web Application Firewall";
|
@@ -269,12 +269,17 @@ $wafRemoveURL = network_admin_url('admin.php?page=WordfenceWAF&wafAction=removeA
|
|
269 |
</p>
|
270 |
<br>
|
271 |
|
272 |
-
<?php if (WFWAF_AUTO_PREPEND) : ?>
|
273 |
<h2>Advanced Configuration</h2>
|
|
|
|
|
|
|
|
|
|
|
274 |
|
275 |
-
|
|
|
276 |
class="wfhelp"></a></strong><br>
|
277 |
-
|
278 |
<em>If you're moving to a new host or a new installation location, you may need to temporarily disable extended protection to avoid any file not found errors. Use this action to remove the configuration changes that enable extended protection mode or you can <a href="https://docs.wordfence.com/en/Web_Application_Firewall_FAQ#How_can_I_remove_the_firewall_setup_manually.3F" target="_blank">remove them manually</a>.</em></p>
|
279 |
|
280 |
<p><a href="<?php echo $wafRemoveURL; ?>" class="button button-small" id="waf-remove-extended">Remove Extended Protection</a></p>
|
@@ -746,6 +751,11 @@ $wafRemoveURL = network_admin_url('admin.php?page=WordfenceWAF&wafAction=removeA
|
|
746 |
var disabled = this.checked ? 0 : 1;
|
747 |
WFAD.updateConfig('ajaxWatcherDisabled_admin', disabled);
|
748 |
})
|
|
|
|
|
|
|
|
|
|
|
749 |
})(jQuery);
|
750 |
</script>
|
751 |
|
5 |
$wafRemoveURL = network_admin_url('admin.php?page=WordfenceWAF&wafAction=removeAutoPrepend');
|
6 |
/** @var array $wafData */
|
7 |
?>
|
8 |
+
<div class="wrap wordfence" id="paidWrap">
|
9 |
<?php require('menuHeader.php'); ?>
|
10 |
<?php
|
11 |
$pageTitle = "Wordfence Web Application Firewall";
|
269 |
</p>
|
270 |
<br>
|
271 |
|
|
|
272 |
<h2>Advanced Configuration</h2>
|
273 |
+
|
274 |
+
<p id="waf-advanced-options">
|
275 |
+
<strong>Other Options</strong><br>
|
276 |
+
<label><input type="checkbox" id="waf-disable-ip-blocking" name="waf-disable-ip-blocking" value="1"<?php echo $config->getConfig('disableWAFIPBlocking') ? ' checked' : ''; ?>>Delay IP and Country blocking until after WordPress and plugins have loaded (only process firewall rules early)</label>
|
277 |
+
</p>
|
278 |
|
279 |
+
<?php if (WFWAF_AUTO_PREPEND) : ?>
|
280 |
+
<p><strong>Remove Extended Protection<a href="https://docs.wordfence.com/en/Web_Application_Firewall_FAQ#How_can_I_remove_the_firewall_setup_manually.3F" target="_blank"
|
281 |
class="wfhelp"></a></strong><br>
|
282 |
+
|
283 |
<em>If you're moving to a new host or a new installation location, you may need to temporarily disable extended protection to avoid any file not found errors. Use this action to remove the configuration changes that enable extended protection mode or you can <a href="https://docs.wordfence.com/en/Web_Application_Firewall_FAQ#How_can_I_remove_the_firewall_setup_manually.3F" target="_blank">remove them manually</a>.</em></p>
|
284 |
|
285 |
<p><a href="<?php echo $wafRemoveURL; ?>" class="button button-small" id="waf-remove-extended">Remove Extended Protection</a></p>
|
751 |
var disabled = this.checked ? 0 : 1;
|
752 |
WFAD.updateConfig('ajaxWatcherDisabled_admin', disabled);
|
753 |
})
|
754 |
+
|
755 |
+
$('#waf-disable-ip-blocking').on('click', function() {
|
756 |
+
var disabled = this.checked ? 1 : 0;
|
757 |
+
WFAD.updateConfig('disableWAFIPBlocking', disabled);
|
758 |
+
})
|
759 |
})(jQuery);
|
760 |
</script>
|
761 |
|
lib/menu_whois.php
CHANGED
@@ -1,5 +1,5 @@
|
|
1 |
<div class="wordfenceModeElem" id="wordfenceMode_whois"></div>
|
2 |
-
<div class="wrap" id="paidWrap">
|
3 |
<?php require('menuHeader.php'); ?>
|
4 |
<?php $pageTitle = "WHOIS Lookup"; $helpLink="http://docs.wordfence.com/en/Whois_Lookup"; $helpLabel="Learn more about Whois Lookups"; include('pageTitle.php'); ?>
|
5 |
<?php
|
1 |
<div class="wordfenceModeElem" id="wordfenceMode_whois"></div>
|
2 |
+
<div class="wrap wordfence" id="paidWrap">
|
3 |
<?php require('menuHeader.php'); ?>
|
4 |
<?php $pageTitle = "WHOIS Lookup"; $helpLink="http://docs.wordfence.com/en/Whois_Lookup"; $helpLabel="Learn more about Whois Lookups"; include('pageTitle.php'); ?>
|
5 |
<?php
|
lib/wf503.php
CHANGED
@@ -5,7 +5,7 @@
|
|
5 |
<h1>Your access to this site has been limited</h1>
|
6 |
<p>Your access to this service has been temporarily limited. Please try again in a few minutes. (HTTP response code 503)</p>
|
7 |
<p>Reason: <span style="color: #F00;"><?php echo $reason; ?></span></p>
|
8 |
-
<p style="width: 600px;"><b>Important note for site admins: </b>If you are the administrator of this website note that your access has been limited because you broke one of the Wordfence
|
9 |
The reason your access was limited is: <b>"<?php echo $reason; ?>"</b>.
|
10 |
<br /><br />
|
11 |
If this is a false positive, meaning that your access to your own site has been limited incorrectly, then you
|
@@ -13,7 +13,7 @@ will need to regain access to your site, go to the Wordfence "options" page, go
|
|
13 |
if you were blocked because it was detected that you are a fake Google crawler, then disable the rule that blocks fake google crawlers. Or if you were blocked because you
|
14 |
were accessing your site too quickly, then increase the number of accesses allowed per minute.
|
15 |
<br /><br />
|
16 |
-
If you're still having trouble, then simply disable the Wordfence
|
17 |
still benefit from the other security features that Wordfence provides.
|
18 |
|
19 |
<br /><br />
|
5 |
<h1>Your access to this site has been limited</h1>
|
6 |
<p>Your access to this service has been temporarily limited. Please try again in a few minutes. (HTTP response code 503)</p>
|
7 |
<p>Reason: <span style="color: #F00;"><?php echo $reason; ?></span></p>
|
8 |
+
<p style="width: 600px;"><b>Important note for site admins: </b>If you are the administrator of this website note that your access has been limited because you broke one of the Wordfence blocking rules.
|
9 |
The reason your access was limited is: <b>"<?php echo $reason; ?>"</b>.
|
10 |
<br /><br />
|
11 |
If this is a false positive, meaning that your access to your own site has been limited incorrectly, then you
|
13 |
if you were blocked because it was detected that you are a fake Google crawler, then disable the rule that blocks fake google crawlers. Or if you were blocked because you
|
14 |
were accessing your site too quickly, then increase the number of accesses allowed per minute.
|
15 |
<br /><br />
|
16 |
+
If you're still having trouble, then simply disable the Wordfence advanced blocking and you will
|
17 |
still benefit from the other security features that Wordfence provides.
|
18 |
|
19 |
<br /><br />
|
lib/wfActivityReport.php
CHANGED
@@ -190,16 +190,10 @@ class wfActivityReport {
|
|
190 |
* @return mixed
|
191 |
*/
|
192 |
public function getTopIPsBlocked($limit = 10) {
|
193 |
-
$where = $this->getBlockedIPWhitelistWhereClause();
|
194 |
-
if ($where) {
|
195 |
-
$where = 'WHERE NOT (' . $where . ')';
|
196 |
-
}
|
197 |
-
|
198 |
$results = $this->db->get_results($this->db->prepare(<<<SQL
|
199 |
SELECT *,
|
200 |
SUM(blockCount) as blockCount
|
201 |
FROM {$this->db->prefix}wfBlockedIPLog
|
202 |
-
$where
|
203 |
GROUP BY IP
|
204 |
ORDER BY blockCount DESC
|
205 |
LIMIT %d
|
@@ -218,15 +212,9 @@ SQL
|
|
218 |
* @return array
|
219 |
*/
|
220 |
public function getTopCountriesBlocked($limit = 10) {
|
221 |
-
$where = $this->getBlockedIPWhitelistWhereClause();
|
222 |
-
if ($where) {
|
223 |
-
$where = 'WHERE NOT (' . $where . ')';
|
224 |
-
}
|
225 |
-
|
226 |
$results = $this->db->get_results($this->db->prepare(<<<SQL
|
227 |
SELECT *, COUNT(IP) as totalIPs, SUM(blockCount) as totalBlockCount
|
228 |
FROM {$this->db->base_prefix}wfBlockedIPLog
|
229 |
-
$where
|
230 |
GROUP BY countryCode
|
231 |
ORDER BY totalBlockCount DESC
|
232 |
LIMIT %d
|
190 |
* @return mixed
|
191 |
*/
|
192 |
public function getTopIPsBlocked($limit = 10) {
|
|
|
|
|
|
|
|
|
|
|
193 |
$results = $this->db->get_results($this->db->prepare(<<<SQL
|
194 |
SELECT *,
|
195 |
SUM(blockCount) as blockCount
|
196 |
FROM {$this->db->prefix}wfBlockedIPLog
|
|
|
197 |
GROUP BY IP
|
198 |
ORDER BY blockCount DESC
|
199 |
LIMIT %d
|
212 |
* @return array
|
213 |
*/
|
214 |
public function getTopCountriesBlocked($limit = 10) {
|
|
|
|
|
|
|
|
|
|
|
215 |
$results = $this->db->get_results($this->db->prepare(<<<SQL
|
216 |
SELECT *, COUNT(IP) as totalIPs, SUM(blockCount) as totalBlockCount
|
217 |
FROM {$this->db->base_prefix}wfBlockedIPLog
|
|
|
218 |
GROUP BY countryCode
|
219 |
ORDER BY totalBlockCount DESC
|
220 |
LIMIT %d
|
lib/wfConfig.php
CHANGED
@@ -25,8 +25,8 @@ class wfConfig {
|
|
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),
|
31 |
"checkSpamIP" => array('value' => false, 'autoload' => self::AUTOLOAD),
|
32 |
"spamvertizeCheck" => array('value' => false, 'autoload' => self::AUTOLOAD),
|
@@ -42,6 +42,7 @@ class wfConfig {
|
|
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),
|
@@ -86,11 +87,12 @@ class wfConfig {
|
|
86 |
'ajaxWatcherDisabled_front' => array('value' => false, 'autoload' => self::AUTOLOAD),
|
87 |
'ajaxWatcherDisabled_admin' => array('value' => false, 'autoload' => self::AUTOLOAD),
|
88 |
'wafAlertOnAttacks' => array('value' => true, 'autoload' => self::AUTOLOAD),
|
|
|
89 |
),
|
90 |
"otherParams" => array(
|
91 |
"scan_include_extra" => "",
|
92 |
// 'securityLevel' => '2',
|
93 |
-
"alertEmails" => "", "liveTraf_ignoreUsers" => "", "liveTraf_ignoreIPs" => "", "liveTraf_ignoreUA" => "", "apiKey" => "", "maxMem" => '256', 'scan_exclude' => '', 'whitelisted' => '', 'bannedURLs' => '', 'maxExecutionTime' => '', 'howGetIPs' => '', 'actUpdateInterval' => '', 'alert_maxHourly' => 0, 'loginSec_userBlacklist' => '',
|
94 |
'liveTraf_maxRows' => 2000,
|
95 |
"neverBlockBG" => "neverBlockVerified",
|
96 |
"loginSec_countFailMins" => "240",
|
@@ -282,12 +284,16 @@ class wfConfig {
|
|
282 |
|
283 |
if (!self::$tableExists) {
|
284 |
return;
|
285 |
-
}
|
286 |
|
|
|
287 |
$table = self::table();
|
288 |
if ($wpdb->query($wpdb->prepare("INSERT INTO {$table} (name, val, autoload) values (%s, %s, %s) ON DUPLICATE KEY UPDATE val = %s, autoload = %s", $key, $val, $autoload, $val, $autoload)) !== false && $autoload != self::DONT_AUTOLOAD) {
|
289 |
self::updateCachedOption($key, $val);
|
290 |
}
|
|
|
|
|
|
|
|
|
291 |
}
|
292 |
public static function get($key, $default = false) {
|
293 |
global $wpdb;
|
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 |
+
"alertOn_wordfenceDeactivated" => array('value' => true, 'autoload' => self::AUTOLOAD),
|
29 |
"liveTrafficEnabled" => array('value' => true, 'autoload' => self::AUTOLOAD),
|
|
|
30 |
"advancedCommentScanning" => array('value' => false, 'autoload' => self::AUTOLOAD),
|
31 |
"checkSpamIP" => array('value' => false, 'autoload' => self::AUTOLOAD),
|
32 |
"spamvertizeCheck" => 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_checkReadableConfig" => array('value' => true, 'autoload' => self::AUTOLOAD),
|
46 |
"scansEnabled_suspectedFiles" => array('value' => true, 'autoload' => self::AUTOLOAD),
|
47 |
"scansEnabled_posts" => array('value' => true, 'autoload' => self::AUTOLOAD),
|
48 |
"scansEnabled_comments" => array('value' => true, 'autoload' => self::AUTOLOAD),
|
87 |
'ajaxWatcherDisabled_front' => array('value' => false, 'autoload' => self::AUTOLOAD),
|
88 |
'ajaxWatcherDisabled_admin' => array('value' => false, 'autoload' => self::AUTOLOAD),
|
89 |
'wafAlertOnAttacks' => array('value' => true, 'autoload' => self::AUTOLOAD),
|
90 |
+
'disableWAFIPBlocking' => array('value' => false, 'autoload' => self::AUTOLOAD),
|
91 |
),
|
92 |
"otherParams" => array(
|
93 |
"scan_include_extra" => "",
|
94 |
// 'securityLevel' => '2',
|
95 |
+
"alertEmails" => "", "liveTraf_ignoreUsers" => "", "liveTraf_ignoreIPs" => "", "liveTraf_ignoreUA" => "", "apiKey" => "", "maxMem" => '256', 'scan_exclude' => '', 'scan_maxIssues' => 1000, 'whitelisted' => '', 'bannedURLs' => '', 'maxExecutionTime' => '', 'howGetIPs' => '', 'actUpdateInterval' => '', 'alert_maxHourly' => 0, 'loginSec_userBlacklist' => '',
|
96 |
'liveTraf_maxRows' => 2000,
|
97 |
"neverBlockBG" => "neverBlockVerified",
|
98 |
"loginSec_countFailMins" => "240",
|
284 |
|
285 |
if (!self::$tableExists) {
|
286 |
return;
|
|
|
287 |
|
288 |
+
}
|
289 |
$table = self::table();
|
290 |
if ($wpdb->query($wpdb->prepare("INSERT INTO {$table} (name, val, autoload) values (%s, %s, %s) ON DUPLICATE KEY UPDATE val = %s, autoload = %s", $key, $val, $autoload, $val, $autoload)) !== false && $autoload != self::DONT_AUTOLOAD) {
|
291 |
self::updateCachedOption($key, $val);
|
292 |
}
|
293 |
+
|
294 |
+
if (!WFWAF_SUBDIRECTORY_INSTALL && class_exists('wfWAFIPBlocksController') && (substr($key, 0, 4) == 'cbl_' || $key == 'blockedTime' || $key == 'disableWAFIPBlocking')) {
|
295 |
+
wfWAFIPBlocksController::synchronizeConfigSettings();
|
296 |
+
}
|
297 |
}
|
298 |
public static function get($key, $default = false) {
|
299 |
global $wpdb;
|
lib/wfIPWhitelist.php
CHANGED
@@ -30,6 +30,7 @@ $wfIPWhitelist = array(
|
|
30 |
'69.46.36.8/29',
|
31 |
'69.46.36.16/28',
|
32 |
'69.46.36.32/32',
|
|
|
33 |
),
|
34 |
'sucuri' => array(
|
35 |
'97.74.127.171',
|
@@ -221,4 +222,156 @@ $wfIPWhitelist = array(
|
|
221 |
'69.162.124.224/28',
|
222 |
'63.143.42.240/28',
|
223 |
),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
224 |
);
|
30 |
'69.46.36.8/29',
|
31 |
'69.46.36.16/28',
|
32 |
'69.46.36.32/32',
|
33 |
+
'68.64.48.0/27',
|
34 |
),
|
35 |
'sucuri' => array(
|
36 |
'97.74.127.171',
|
222 |
'69.162.124.224/28',
|
223 |
'63.143.42.240/28',
|
224 |
),
|
225 |
+
'statuscake' => array(
|
226 |
+
'103.194.112.70',
|
227 |
+
'104.131.247.151',
|
228 |
+
'104.131.248.65',
|
229 |
+
'104.131.248.78',
|
230 |
+
'104.156.229.24',
|
231 |
+
'104.156.255.184',
|
232 |
+
'104.206.168.26',
|
233 |
+
'104.238.164.105',
|
234 |
+
'107.150.1.135',
|
235 |
+
'107.155.104.182',
|
236 |
+
'107.155.108.234',
|
237 |
+
'107.155.125.29',
|
238 |
+
'107.161.28.219',
|
239 |
+
'107.170.197.248',
|
240 |
+
'107.170.219.46',
|
241 |
+
'107.170.227.23',
|
242 |
+
'107.170.227.24',
|
243 |
+
'107.170.240.141',
|
244 |
+
'107.170.53.191',
|
245 |
+
'107.191.47.131',
|
246 |
+
'107.191.57.237',
|
247 |
+
'108.61.119.153',
|
248 |
+
'108.61.162.214',
|
249 |
+
'108.61.205.201',
|
250 |
+
'108.61.212.141',
|
251 |
+
'108.61.215.179',
|
252 |
+
'125.63.48.239',
|
253 |
+
'128.199.222.65',
|
254 |
+
'138.197.130.232',
|
255 |
+
'138.197.130.235',
|
256 |
+
'138.197.140.243',
|
257 |
+
'138.204.171.136',
|
258 |
+
'138.68.24.115',
|
259 |
+
'138.68.24.136',
|
260 |
+
'138.68.24.207',
|
261 |
+
'138.68.24.60',
|
262 |
+
'138.68.80.10',
|
263 |
+
'138.68.80.173',
|
264 |
+
'139.59.15.79',
|
265 |
+
'139.59.155.26',
|
266 |
+
'139.59.190.241',
|
267 |
+
'139.59.22.109',
|
268 |
+
'139.59.26.85',
|
269 |
+
'139.59.29.167',
|
270 |
+
'149.154.157.61',
|
271 |
+
'149.255.59.100',
|
272 |
+
'151.236.10.238',
|
273 |
+
'151.236.18.80',
|
274 |
+
'151.80.175.223',
|
275 |
+
'151.80.175.226',
|
276 |
+
'154.127.60.23',
|
277 |
+
'154.127.60.59',
|
278 |
+
'158.255.208.76',
|
279 |
+
'159.203.182.22',
|
280 |
+
'159.203.182.60',
|
281 |
+
'159.203.186.225',
|
282 |
+
'159.203.31.18',
|
283 |
+
'162.243.247.163',
|
284 |
+
'162.243.71.56',
|
285 |
+
'162.248.97.72',
|
286 |
+
'162.253.64.104',
|
287 |
+
'162.253.64.87',
|
288 |
+
'176.56.230.110',
|
289 |
+
'178.62.101.57',
|
290 |
+
'178.62.104.137',
|
291 |
+
'178.62.106.84',
|
292 |
+
'178.62.109.7',
|
293 |
+
'178.62.40.233',
|
294 |
+
'178.62.41.44',
|
295 |
+
'178.62.41.49',
|
296 |
+
'178.62.41.52',
|
297 |
+
'178.62.65.162',
|
298 |
+
'178.62.71.227',
|
299 |
+
'178.62.78.199',
|
300 |
+
'178.62.80.93',
|
301 |
+
'178.62.86.69',
|
302 |
+
'178.73.210.99',
|
303 |
+
'181.41.201.117',
|
304 |
+
'181.41.214.137',
|
305 |
+
'185.112.157.185',
|
306 |
+
'185.12.45.70',
|
307 |
+
'185.47.129.168',
|
308 |
+
'185.60.135.86',
|
309 |
+
'188.166.158.224',
|
310 |
+
'188.166.253.148',
|
311 |
+
'188.226.139.158',
|
312 |
+
'188.226.158.160',
|
313 |
+
'188.226.169.228',
|
314 |
+
'188.226.171.58',
|
315 |
+
'188.226.184.152',
|
316 |
+
'188.226.185.106',
|
317 |
+
'188.226.186.199',
|
318 |
+
'188.226.203.84',
|
319 |
+
'188.226.247.184',
|
320 |
+
'188.68.238.79',
|
321 |
+
'192.241.221.11',
|
322 |
+
'193.124.178.54',
|
323 |
+
'193.124.178.61',
|
324 |
+
'193.182.144.105',
|
325 |
+
'193.182.144.147',
|
326 |
+
'199.167.128.80',
|
327 |
+
'209.222.30.242',
|
328 |
+
'213.183.56.107',
|
329 |
+
'217.148.43.188',
|
330 |
+
'217.148.43.202',
|
331 |
+
'31.220.7.237',
|
332 |
+
'37.157.246.146',
|
333 |
+
'37.235.48.42',
|
334 |
+
'37.235.52.25',
|
335 |
+
'37.235.53.240',
|
336 |
+
'37.235.55.205',
|
337 |
+
'37.97.188.103',
|
338 |
+
'45.32.128.80',
|
339 |
+
'45.32.145.79',
|
340 |
+
'45.32.151.21',
|
341 |
+
'45.32.160.172',
|
342 |
+
'45.32.166.195',
|
343 |
+
'45.32.171.24',
|
344 |
+
'45.32.192.198',
|
345 |
+
'45.32.195.186',
|
346 |
+
'45.32.195.93',
|
347 |
+
'45.32.212.56',
|
348 |
+
'45.32.36.158',
|
349 |
+
'45.32.7.22',
|
350 |
+
'45.63.121.159',
|
351 |
+
'45.63.26.78',
|
352 |
+
'45.63.51.63',
|
353 |
+
'45.63.61.213',
|
354 |
+
'45.63.76.68',
|
355 |
+
'45.63.78.84',
|
356 |
+
'45.63.86.120',
|
357 |
+
'45.63.88.213',
|
358 |
+
'45.76.1.44',
|
359 |
+
'45.76.192.50',
|
360 |
+
'45.76.3.112',
|
361 |
+
'46.101.0.24',
|
362 |
+
'46.101.110.32',
|
363 |
+
'46.101.110.43',
|
364 |
+
'46.101.110.45',
|
365 |
+
'46.101.20.96',
|
366 |
+
'46.101.238.182',
|
367 |
+
'46.101.238.189',
|
368 |
+
'46.101.240.208',
|
369 |
+
'46.101.27.186',
|
370 |
+
'46.101.61.83',
|
371 |
+
'46.101.74.251',
|
372 |
+
'5.45.179.103',
|
373 |
+
'50.2.139.16',
|
374 |
+
'82.221.95.161',
|
375 |
+
'91.236.116.163',
|
376 |
+
),
|
377 |
);
|
lib/wfIssues.php
CHANGED
@@ -6,16 +6,18 @@ class wfIssues {
|
|
6 |
//Properties that are serialized on sleep:
|
7 |
private $updateCalled = false;
|
8 |
private $issuesTable = '';
|
|
|
9 |
private $newIssues = array();
|
10 |
public $totalIssues = 0;
|
11 |
public $totalCriticalIssues = 0;
|
12 |
public $totalWarningIssues = 0;
|
13 |
public function __sleep(){ //Same order here as vars above
|
14 |
-
return array('updateCalled', 'issuesTable', 'newIssues', 'totalIssues', 'totalCriticalIssues', 'totalWarningIssues');
|
15 |
}
|
16 |
public function __construct(){
|
17 |
global $wpdb;
|
18 |
$this->issuesTable = $wpdb->base_prefix . 'wfIssues';
|
|
|
19 |
}
|
20 |
public function __wakeup(){
|
21 |
$this->db = new wfDB();
|
@@ -48,15 +50,18 @@ class wfIssues {
|
|
48 |
$this->totalWarningIssues++;
|
49 |
}
|
50 |
$this->totalIssues++;
|
51 |
-
$this->
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
|
|
|
|
|
|
60 |
|
61 |
$this->getDB()->queryWrite("insert into " . $this->issuesTable . " (time, status, type, severity, ignoreP, ignoreC, shortMsg, longMsg, data) values (unix_timestamp(), '%s', '%s', %d, '%s', '%s', '%s', '%s', '%s')",
|
62 |
'new',
|
@@ -93,6 +98,7 @@ class wfIssues {
|
|
93 |
if(! is_array($emailedIssues)){
|
94 |
$emailedIssues = array();
|
95 |
}
|
|
|
96 |
$finalIssues = array();
|
97 |
foreach($this->newIssues as $newIssue){
|
98 |
$alreadyEmailed = false;
|
@@ -105,8 +111,14 @@ class wfIssues {
|
|
105 |
if(! $alreadyEmailed){
|
106 |
$finalIssues[] = $newIssue;
|
107 |
}
|
|
|
|
|
|
|
108 |
}
|
109 |
if(sizeof($finalIssues) < 1){ return; }
|
|
|
|
|
|
|
110 |
|
111 |
$totalWarningIssues = 0;
|
112 |
$totalCriticalIssues = 0;
|
@@ -126,7 +138,9 @@ class wfIssues {
|
|
126 |
'issues' => $finalIssues,
|
127 |
'totalCriticalIssues' => $totalCriticalIssues,
|
128 |
'totalWarningIssues' => $totalWarningIssues,
|
129 |
-
'level' => $level
|
|
|
|
|
130 |
));
|
131 |
|
132 |
wp_mail(implode(',', $emails), $subject, $content, 'Content-type: text/html');
|
@@ -146,7 +160,7 @@ class wfIssues {
|
|
146 |
$rec['data'] = unserialize($rec['data']);
|
147 |
return $rec;
|
148 |
}
|
149 |
-
public function getIssues(){
|
150 |
/** @var wpdb $wpdb */
|
151 |
global $wpdb;
|
152 |
$ret = array(
|
@@ -154,7 +168,7 @@ class wfIssues {
|
|
154 |
'ignored' => array()
|
155 |
);
|
156 |
$userIni = ini_get('user_ini.filename');
|
157 |
-
$q1 = $this->getDB()->querySelect("select * from " . $this->issuesTable . " order by time desc");
|
158 |
foreach($q1 as $i){
|
159 |
$i['data'] = unserialize($i['data']);
|
160 |
$i['timeAgo'] = wfUtils::makeTimeAgo(time() - $i['time']);
|
6 |
//Properties that are serialized on sleep:
|
7 |
private $updateCalled = false;
|
8 |
private $issuesTable = '';
|
9 |
+
private $maxIssues = 0;
|
10 |
private $newIssues = array();
|
11 |
public $totalIssues = 0;
|
12 |
public $totalCriticalIssues = 0;
|
13 |
public $totalWarningIssues = 0;
|
14 |
public function __sleep(){ //Same order here as vars above
|
15 |
+
return array('updateCalled', 'issuesTable', 'maxIssues', 'newIssues', 'totalIssues', 'totalCriticalIssues', 'totalWarningIssues');
|
16 |
}
|
17 |
public function __construct(){
|
18 |
global $wpdb;
|
19 |
$this->issuesTable = $wpdb->base_prefix . 'wfIssues';
|
20 |
+
$this->maxIssues = wfConfig::get('scan_maxIssues', 0);
|
21 |
}
|
22 |
public function __wakeup(){
|
23 |
$this->db = new wfDB();
|
50 |
$this->totalWarningIssues++;
|
51 |
}
|
52 |
$this->totalIssues++;
|
53 |
+
if (empty($this->maxIssues) || $this->totalIssues <= $this->maxIssues)
|
54 |
+
{
|
55 |
+
$this->newIssues[] = array(
|
56 |
+
'type' => $type,
|
57 |
+
'severity' => $severity,
|
58 |
+
'ignoreP' => $ignoreP,
|
59 |
+
'ignoreC' => $ignoreC,
|
60 |
+
'shortMsg' => $shortMsg,
|
61 |
+
'longMsg' => $longMsg,
|
62 |
+
'tmplData' => $templateData
|
63 |
+
);
|
64 |
+
}
|
65 |
|
66 |
$this->getDB()->queryWrite("insert into " . $this->issuesTable . " (time, status, type, severity, ignoreP, ignoreC, shortMsg, longMsg, data) values (unix_timestamp(), '%s', '%s', %d, '%s', '%s', '%s', '%s', '%s')",
|
67 |
'new',
|
98 |
if(! is_array($emailedIssues)){
|
99 |
$emailedIssues = array();
|
100 |
}
|
101 |
+
$overflowCount = $this->totalIssues - count($this->newIssues);
|
102 |
$finalIssues = array();
|
103 |
foreach($this->newIssues as $newIssue){
|
104 |
$alreadyEmailed = false;
|
111 |
if(! $alreadyEmailed){
|
112 |
$finalIssues[] = $newIssue;
|
113 |
}
|
114 |
+
else {
|
115 |
+
$overflowCount--;
|
116 |
+
}
|
117 |
}
|
118 |
if(sizeof($finalIssues) < 1){ return; }
|
119 |
+
|
120 |
+
$this->newIssues = array();
|
121 |
+
$this->totalIssues = 0;
|
122 |
|
123 |
$totalWarningIssues = 0;
|
124 |
$totalCriticalIssues = 0;
|
138 |
'issues' => $finalIssues,
|
139 |
'totalCriticalIssues' => $totalCriticalIssues,
|
140 |
'totalWarningIssues' => $totalWarningIssues,
|
141 |
+
'level' => $level,
|
142 |
+
'issuesNotShown' => $overflowCount,
|
143 |
+
'adminURL' => get_admin_url(),
|
144 |
));
|
145 |
|
146 |
wp_mail(implode(',', $emails), $subject, $content, 'Content-type: text/html');
|
160 |
$rec['data'] = unserialize($rec['data']);
|
161 |
return $rec;
|
162 |
}
|
163 |
+
public function getIssues($offset = 0, $limit = 100){
|
164 |
/** @var wpdb $wpdb */
|
165 |
global $wpdb;
|
166 |
$ret = array(
|
168 |
'ignored' => array()
|
169 |
);
|
170 |
$userIni = ini_get('user_ini.filename');
|
171 |
+
$q1 = $this->getDB()->querySelect("select * from " . $this->issuesTable . " order by time desc LIMIT %d,%d", $offset, $limit);
|
172 |
foreach($q1 as $i){
|
173 |
$i['data'] = unserialize($i['data']);
|
174 |
$i['timeAgo'] = wfUtils::makeTimeAgo(time() - $i['time']);
|
lib/wfLog.php
CHANGED
@@ -304,17 +304,33 @@ class wfLog {
|
|
304 |
public function unblockAllIPs(){
|
305 |
$this->getDB()->queryWrite("delete from " . $this->blocksTable);
|
306 |
wfCache::updateBlockedIPs('add');
|
|
|
|
|
|
|
|
|
307 |
}
|
308 |
public function unlockAllIPs(){
|
309 |
$this->getDB()->queryWrite("delete from " . $this->lockOutTable);
|
|
|
|
|
|
|
|
|
310 |
}
|
311 |
public function unblockIP($IP){
|
312 |
$this->getDB()->queryWrite("delete from " . $this->blocksTable . " where IP=%s", wfUtils::inet_pton($IP));
|
313 |
wfCache::updateBlockedIPs('add');
|
|
|
|
|
|
|
|
|
314 |
}
|
315 |
public function unblockRange($id){
|
316 |
$this->getDB()->queryWrite("delete from " . $this->ipRangesTable . " where id=%d", $id);
|
317 |
wfCache::updateBlockedIPs('add');
|
|
|
|
|
|
|
|
|
318 |
}
|
319 |
|
320 |
/**
|
@@ -328,6 +344,11 @@ class wfLog {
|
|
328 |
$reason = stripslashes($reason);
|
329 |
$this->getDB()->queryWrite("insert IGNORE into " . $this->ipRangesTable . " (blockType, blockString, ctime, reason, totalBlocked, lastBlocked) values ('%s', '%s', unix_timestamp(), '%s', 0, 0)", $blockType, $range, $reason);
|
330 |
wfCache::updateBlockedIPs('add');
|
|
|
|
|
|
|
|
|
|
|
331 |
return true;
|
332 |
}
|
333 |
public function getRangesBasic(){
|
@@ -430,6 +451,11 @@ class wfLog {
|
|
430 |
|
431 |
wfCache::updateBlockedIPs('add');
|
432 |
wfConfig::inc('totalIPsBlocked');
|
|
|
|
|
|
|
|
|
|
|
433 |
return true;
|
434 |
}
|
435 |
public function lockOutIP($IP, $reason){
|
@@ -450,10 +476,19 @@ class wfLog {
|
|
450 |
}
|
451 |
|
452 |
wfConfig::inc('totalIPsLocked');
|
|
|
|
|
|
|
|
|
|
|
453 |
return true;
|
454 |
}
|
455 |
public function unlockOutIP($IP){
|
456 |
$this->getDB()->queryWrite("delete from " . $this->lockOutTable . " where IP=%s", wfUtils::inet_pton($IP));
|
|
|
|
|
|
|
|
|
457 |
}
|
458 |
public function isIPLockedOut($IP){
|
459 |
if($this->getDB()->querySingle("select IP from " . $this->lockOutTable . " where IP=%s and blockedTime + %s > unix_timestamp()", wfUtils::inet_pton($IP), wfConfig::get('loginSec_lockoutMins') * 60)){
|
@@ -1030,7 +1065,7 @@ class wfLog {
|
|
1030 |
$hasRun = true;
|
1031 |
|
1032 |
$blockedCountries = wfConfig::get('cbl_countries', false);
|
1033 |
-
$bareRequestURI = wfUtils::extractBareURI($_SERVER['REQUEST_URI']);
|
1034 |
$IP = wfUtils::getIP();
|
1035 |
if($country = wfUtils::IP2Country($IP) ){
|
1036 |
foreach(explode(',', $blockedCountries) as $blocked){
|
@@ -1042,7 +1077,7 @@ class wfLog {
|
|
1042 |
if($eRedirHost && $eRedirHost != wfUtils::extractHostname(home_url())){ //It's an external redirect...
|
1043 |
$isExternalRedir = true;
|
1044 |
}
|
1045 |
-
if( (! $isExternalRedir) && wfUtils::extractBareURI($redirURL) == $bareRequestURI){ //Is this the URI we want to redirect to, then don't block it
|
1046 |
//Do nothing
|
1047 |
/* Uncomment the following if page components aren't loading for the page we redirect to.
|
1048 |
Uncommenting is not recommended because it means that anyone from a blocked country
|
@@ -1052,11 +1087,24 @@ class wfLog {
|
|
1052 |
//Do nothing
|
1053 |
*/
|
1054 |
} else {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1055 |
$this->redirect(wfConfig::get('cbl_redirURL'));
|
1056 |
}
|
1057 |
} else {
|
1058 |
$this->currentRequest->actionDescription = 'blocked access via country blocking';
|
1059 |
wfConfig::inc('totalCountryBlocked');
|
|
|
1060 |
$this->do503(3600, "Access from your area has been temporarily limited for security reasons");
|
1061 |
}
|
1062 |
}
|
@@ -1233,6 +1281,15 @@ class wfUserIPRange {
|
|
1233 |
|
1234 |
// IPv4 range
|
1235 |
if (strpos($ip_string, '.') !== false && strpos($ip, '.') !== false) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1236 |
if (preg_match('/\[\d+\-\d+\]/', $ip_string)) {
|
1237 |
$IPparts = explode('.', $ip);
|
1238 |
$whiteParts = explode('.', $ip_string);
|
@@ -1314,23 +1371,26 @@ class wfUserIPRange {
|
|
1314 |
$sql = substr($sql, 0, -5) . ')';
|
1315 |
return $sql;
|
1316 |
|
1317 |
-
} else if (strpos($ip_string, ':') !== false
|
1318 |
-
$
|
1319 |
-
|
1320 |
-
|
1321 |
-
|
1322 |
-
|
1323 |
-
$
|
1324 |
-
|
1325 |
-
|
1326 |
-
$
|
1327 |
-
|
1328 |
-
|
|
|
|
|
|
|
|
|
1329 |
}
|
1330 |
-
$sql
|
|
|
1331 |
}
|
1332 |
-
$sql = substr($sql, 0, -5) . ')';
|
1333 |
-
return $sql;
|
1334 |
}
|
1335 |
return $wpdb->prepare("($column = %s)", wfUtils::inet_pton($ip_string));
|
1336 |
}
|
@@ -1427,7 +1487,7 @@ class wfUserIPRange {
|
|
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 |
|
@@ -2264,3 +2324,100 @@ class wfLiveTrafficQueryGroupBy {
|
|
2264 |
class wfLiveTrafficQueryException extends Exception {
|
2265 |
|
2266 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
304 |
public function unblockAllIPs(){
|
305 |
$this->getDB()->queryWrite("delete from " . $this->blocksTable);
|
306 |
wfCache::updateBlockedIPs('add');
|
307 |
+
|
308 |
+
if (!WFWAF_SUBDIRECTORY_INSTALL && class_exists('wfWAFIPBlocksController')) {
|
309 |
+
wfWAFIPBlocksController::synchronizeConfigSettings();
|
310 |
+
}
|
311 |
}
|
312 |
public function unlockAllIPs(){
|
313 |
$this->getDB()->queryWrite("delete from " . $this->lockOutTable);
|
314 |
+
|
315 |
+
if (!WFWAF_SUBDIRECTORY_INSTALL && class_exists('wfWAFIPBlocksController')) {
|
316 |
+
wfWAFIPBlocksController::synchronizeConfigSettings();
|
317 |
+
}
|
318 |
}
|
319 |
public function unblockIP($IP){
|
320 |
$this->getDB()->queryWrite("delete from " . $this->blocksTable . " where IP=%s", wfUtils::inet_pton($IP));
|
321 |
wfCache::updateBlockedIPs('add');
|
322 |
+
|
323 |
+
if (!WFWAF_SUBDIRECTORY_INSTALL && class_exists('wfWAFIPBlocksController')) {
|
324 |
+
wfWAFIPBlocksController::synchronizeConfigSettings();
|
325 |
+
}
|
326 |
}
|
327 |
public function unblockRange($id){
|
328 |
$this->getDB()->queryWrite("delete from " . $this->ipRangesTable . " where id=%d", $id);
|
329 |
wfCache::updateBlockedIPs('add');
|
330 |
+
|
331 |
+
if (!WFWAF_SUBDIRECTORY_INSTALL && class_exists('wfWAFIPBlocksController')) {
|
332 |
+
wfWAFIPBlocksController::synchronizeConfigSettings();
|
333 |
+
}
|
334 |
}
|
335 |
|
336 |
/**
|
344 |
$reason = stripslashes($reason);
|
345 |
$this->getDB()->queryWrite("insert IGNORE into " . $this->ipRangesTable . " (blockType, blockString, ctime, reason, totalBlocked, lastBlocked) values ('%s', '%s', unix_timestamp(), '%s', 0, 0)", $blockType, $range, $reason);
|
346 |
wfCache::updateBlockedIPs('add');
|
347 |
+
|
348 |
+
if (!WFWAF_SUBDIRECTORY_INSTALL && class_exists('wfWAFIPBlocksController')) {
|
349 |
+
wfWAFIPBlocksController::synchronizeConfigSettings();
|
350 |
+
}
|
351 |
+
|
352 |
return true;
|
353 |
}
|
354 |
public function getRangesBasic(){
|
451 |
|
452 |
wfCache::updateBlockedIPs('add');
|
453 |
wfConfig::inc('totalIPsBlocked');
|
454 |
+
|
455 |
+
if (!WFWAF_SUBDIRECTORY_INSTALL && class_exists('wfWAFIPBlocksController')) {
|
456 |
+
wfWAFIPBlocksController::synchronizeConfigSettings();
|
457 |
+
}
|
458 |
+
|
459 |
return true;
|
460 |
}
|
461 |
public function lockOutIP($IP, $reason){
|
476 |
}
|
477 |
|
478 |
wfConfig::inc('totalIPsLocked');
|
479 |
+
|
480 |
+
if (!WFWAF_SUBDIRECTORY_INSTALL && class_exists('wfWAFIPBlocksController')) {
|
481 |
+
wfWAFIPBlocksController::synchronizeConfigSettings();
|
482 |
+
}
|
483 |
+
|
484 |
return true;
|
485 |
}
|
486 |
public function unlockOutIP($IP){
|
487 |
$this->getDB()->queryWrite("delete from " . $this->lockOutTable . " where IP=%s", wfUtils::inet_pton($IP));
|
488 |
+
|
489 |
+
if (!WFWAF_SUBDIRECTORY_INSTALL && class_exists('wfWAFIPBlocksController')) {
|
490 |
+
wfWAFIPBlocksController::synchronizeConfigSettings();
|
491 |
+
}
|
492 |
}
|
493 |
public function isIPLockedOut($IP){
|
494 |
if($this->getDB()->querySingle("select IP from " . $this->lockOutTable . " where IP=%s and blockedTime + %s > unix_timestamp()", wfUtils::inet_pton($IP), wfConfig::get('loginSec_lockoutMins') * 60)){
|
1065 |
$hasRun = true;
|
1066 |
|
1067 |
$blockedCountries = wfConfig::get('cbl_countries', false);
|
1068 |
+
$bareRequestURI = untrailingslashit(wfUtils::extractBareURI($_SERVER['REQUEST_URI']));
|
1069 |
$IP = wfUtils::getIP();
|
1070 |
if($country = wfUtils::IP2Country($IP) ){
|
1071 |
foreach(explode(',', $blockedCountries) as $blocked){
|
1077 |
if($eRedirHost && $eRedirHost != wfUtils::extractHostname(home_url())){ //It's an external redirect...
|
1078 |
$isExternalRedir = true;
|
1079 |
}
|
1080 |
+
if( (! $isExternalRedir) && untrailingslashit(wfUtils::extractBareURI($redirURL)) == $bareRequestURI){ //Is this the URI we want to redirect to, then don't block it
|
1081 |
//Do nothing
|
1082 |
/* Uncomment the following if page components aren't loading for the page we redirect to.
|
1083 |
Uncommenting is not recommended because it means that anyone from a blocked country
|
1087 |
//Do nothing
|
1088 |
*/
|
1089 |
} else {
|
1090 |
+
wfConfig::inc('totalCountryBlocked');
|
1091 |
+
|
1092 |
+
$this->initLogRequest();
|
1093 |
+
$this->currentRequest->actionDescription = 'blocked access via country blocking and redirected to URL (' . wfConfig::get('cbl_redirURL') . ')';
|
1094 |
+
$this->currentRequest->statusCode = 503;
|
1095 |
+
if (!$this->currentRequest->action) {
|
1096 |
+
$this->currentRequest->action = 'blocked:wordfence';
|
1097 |
+
}
|
1098 |
+
$this->logHit();
|
1099 |
+
|
1100 |
+
wfActivityReport::logBlockedIP($IP);
|
1101 |
+
|
1102 |
$this->redirect(wfConfig::get('cbl_redirURL'));
|
1103 |
}
|
1104 |
} else {
|
1105 |
$this->currentRequest->actionDescription = 'blocked access via country blocking';
|
1106 |
wfConfig::inc('totalCountryBlocked');
|
1107 |
+
wfActivityReport::logBlockedIP($IP);
|
1108 |
$this->do503(3600, "Access from your area has been temporarily limited for security reasons");
|
1109 |
}
|
1110 |
}
|
1281 |
|
1282 |
// IPv4 range
|
1283 |
if (strpos($ip_string, '.') !== false && strpos($ip, '.') !== false) {
|
1284 |
+
// IPv4-mapped-IPv6
|
1285 |
+
if (preg_match('/:ffff:([^:]+)$/i', $ip_string, $matches)) {
|
1286 |
+
$ip_string = $matches[1];
|
1287 |
+
}
|
1288 |
+
if (preg_match('/:ffff:([^:]+)$/i', $ip, $matches)) {
|
1289 |
+
$ip = $matches[1];
|
1290 |
+
}
|
1291 |
+
|
1292 |
+
// Range check
|
1293 |
if (preg_match('/\[\d+\-\d+\]/', $ip_string)) {
|
1294 |
$IPparts = explode('.', $ip);
|
1295 |
$whiteParts = explode('.', $ip_string);
|
1371 |
$sql = substr($sql, 0, -5) . ')';
|
1372 |
return $sql;
|
1373 |
|
1374 |
+
} else if (strpos($ip_string, ':') !== false) {
|
1375 |
+
$ip_string = strtolower(self::expandIPv6Range($ip_string));
|
1376 |
+
if (preg_match('/\[[a-f0-9]+\-[a-f0-9]+\]/i', $ip_string)) {
|
1377 |
+
$whiteParts = explode(':', $ip_string);
|
1378 |
+
$sql = '(';
|
1379 |
+
|
1380 |
+
for ($i = 0; $i <= 7; $i++) {
|
1381 |
+
// MySQL can only perform bitwise operations on integers
|
1382 |
+
$conv = sprintf('CAST(CONV(HEX(SUBSTR(%s, %d, 8)), 16, 10) as UNSIGNED INTEGER)', $column, $i < 4 ? 1 : 9);
|
1383 |
+
$j = 16 * (3 - ($i % 4));
|
1384 |
+
if (preg_match('/^\[([a-f0-9]+)\-([a-f0-9]+)\]$/i', $whiteParts[$i], $m)) {
|
1385 |
+
$sql .= $wpdb->prepare("$conv >> $j & 0xFFFF BETWEEN 0x%x AND 0x%x", hexdec($m[1]), hexdec($m[2]));
|
1386 |
+
} else {
|
1387 |
+
$sql .= $wpdb->prepare("$conv >> $j & 0xFFFF = 0x%x", hexdec($whiteParts[$i]));
|
1388 |
+
}
|
1389 |
+
$sql .= ' AND ';
|
1390 |
}
|
1391 |
+
$sql = substr($sql, 0, -5) . ')';
|
1392 |
+
return $sql;
|
1393 |
}
|
|
|
|
|
1394 |
}
|
1395 |
return $wpdb->prepare("($column = %s)", wfUtils::inet_pton($ip_string));
|
1396 |
}
|
1487 |
* @param string|null $ip_string
|
1488 |
*/
|
1489 |
public function setIPString($ip_string) {
|
1490 |
+
$this->ip_string = strtolower(preg_replace('/[\x{2013}-\x{2015}]/u', '-', $ip_string)); //Replace em-dash, en-dash, and horizontal bar with a regular dash
|
1491 |
}
|
1492 |
}
|
1493 |
|
2324 |
class wfLiveTrafficQueryException extends Exception {
|
2325 |
|
2326 |
}
|
2327 |
+
|
2328 |
+
class wfErrorLogHandler {
|
2329 |
+
public static function getErrorLogs($deepSearch = false) {
|
2330 |
+
static $errorLogs = null;
|
2331 |
+
|
2332 |
+
if ($errorLogs === null) {
|
2333 |
+
$searchPaths = array(ABSPATH, ABSPATH . 'wp-admin', ABSPATH . 'wp-content');
|
2334 |
+
|
2335 |
+
$homePath = get_home_path();
|
2336 |
+
if (!in_array($homePath, $searchPaths)) {
|
2337 |
+
$searchPaths[] = $homePath;
|
2338 |
+
}
|
2339 |
+
|
2340 |
+
$errorLogPath = ini_get('error_log');
|
2341 |
+
if (!empty($errorLogPath) && !in_array($errorLogPath, $searchPaths)) {
|
2342 |
+
$searchPaths[] = $errorLogPath;
|
2343 |
+
}
|
2344 |
+
|
2345 |
+
$errorLogs = array();
|
2346 |
+
foreach ($searchPaths as $s) {
|
2347 |
+
$errorLogs = array_merge($errorLogs, self::_scanForLogs($s, $deepSearch));
|
2348 |
+
}
|
2349 |
+
}
|
2350 |
+
return $errorLogs;
|
2351 |
+
}
|
2352 |
+
|
2353 |
+
private static function _scanForLogs($path, $deepSearch = false) {
|
2354 |
+
static $processedFolders = array(); //Protection for endless loops caused by symlinks
|
2355 |
+
if (is_file($path)) {
|
2356 |
+
$file = basename($path);
|
2357 |
+
if (preg_match('#(?:error_log(\-\d+)?$|\.log$)#i', $file)) {
|
2358 |
+
return array($path => is_readable($path));
|
2359 |
+
}
|
2360 |
+
return array();
|
2361 |
+
}
|
2362 |
+
|
2363 |
+
$path = untrailingslashit($path);
|
2364 |
+
$contents = @scandir($path);
|
2365 |
+
if (!is_array($contents)) {
|
2366 |
+
return array();
|
2367 |
+
}
|
2368 |
+
|
2369 |
+
$processedFolders[$path] = true;
|
2370 |
+
$errorLogs = array();
|
2371 |
+
foreach ($contents as $name) {
|
2372 |
+
if ($name == '.' || $name == '..') { continue; }
|
2373 |
+
$testPath = $path . DIRECTORY_SEPARATOR . $name;
|
2374 |
+
if (!array_key_exists($testPath, $processedFolders)) {
|
2375 |
+
if ((is_dir($testPath) && $deepSearch) || !is_dir($testPath)) {
|
2376 |
+
$errorLogs = array_merge($errorLogs, self::_scanForLogs($testPath, $deepSearch));
|
2377 |
+
}
|
2378 |
+
}
|
2379 |
+
}
|
2380 |
+
return $errorLogs;
|
2381 |
+
}
|
2382 |
+
|
2383 |
+
public static function outputErrorLog($path) {
|
2384 |
+
$errorLogs = self::getErrorLogs();
|
2385 |
+
if (!isset($errorLogs[$path])) { //Only allow error logs we've identified
|
2386 |
+
status_header(404);
|
2387 |
+
nocache_headers();
|
2388 |
+
|
2389 |
+
$template = get_404_template();
|
2390 |
+
if ($template && file_exists($template)) {
|
2391 |
+
include($template);
|
2392 |
+
}
|
2393 |
+
exit;
|
2394 |
+
}
|
2395 |
+
|
2396 |
+
$fh = @fopen($path, 'r');
|
2397 |
+
if (!$fh) {
|
2398 |
+
status_header(503);
|
2399 |
+
nocache_headers();
|
2400 |
+
echo "503 Service Unavailable";
|
2401 |
+
exit;
|
2402 |
+
}
|
2403 |
+
|
2404 |
+
$headersOutputted = false;
|
2405 |
+
while (!feof($fh)) {
|
2406 |
+
$data = fread($fh, 1 * 1024 * 1024); //read 1 megs max per chunk
|
2407 |
+
if ($data === false) { //Handle the error where the file was reported readable but we can't actually read it
|
2408 |
+
status_header(503);
|
2409 |
+
nocache_headers();
|
2410 |
+
echo "503 Service Unavailable";
|
2411 |
+
exit;
|
2412 |
+
}
|
2413 |
+
|
2414 |
+
if (!$headersOutputted) {
|
2415 |
+
header('Content-Type: text/plain');
|
2416 |
+
header('Content-Disposition: attachment; filename="' . basename($path));
|
2417 |
+
$headersOutputted = true;
|
2418 |
+
}
|
2419 |
+
echo $data;
|
2420 |
+
}
|
2421 |
+
exit;
|
2422 |
+
}
|
2423 |
+
}
|
lib/wfUtils.php
CHANGED
@@ -134,13 +134,17 @@ class wfUtils {
|
|
134 |
return false;
|
135 |
}
|
136 |
}
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
$
|
141 |
-
|
142 |
-
|
143 |
-
|
|
|
|
|
|
|
|
|
144 |
}
|
145 |
|
146 |
/**
|
@@ -647,7 +651,7 @@ class wfUtils {
|
|
647 |
return self::getCleanIPAndServerVar(array($connectionIP));
|
648 |
} else {
|
649 |
$ipsToCheck = array(
|
650 |
-
array($_SERVER[$howGet], $howGet),
|
651 |
$connectionIP,
|
652 |
);
|
653 |
return self::getCleanIPAndServerVar($ipsToCheck);
|
134 |
return false;
|
135 |
}
|
136 |
}
|
137 |
+
|
138 |
+
$bin_network = substr(self::inet_pton($network), 0, ceil($prefix / 8));
|
139 |
+
$bin_ip = substr(self::inet_pton($ip), 0, ceil($prefix / 8));
|
140 |
+
if ($prefix % 8 != 0) { //Adjust the last relevant character to fit the mask length since the character's bits are split over it
|
141 |
+
$pos = intval($prefix / 8);
|
142 |
+
$adjustment = chr(((0xff << (8 - ($prefix % 8))) & 0xff));
|
143 |
+
$bin_network[$pos] = ($bin_network[$pos] & $adjustment);
|
144 |
+
$bin_ip[$pos] = ($bin_ip[$pos] & $adjustment);
|
145 |
+
}
|
146 |
+
|
147 |
+
return ($bin_network === $bin_ip);
|
148 |
}
|
149 |
|
150 |
/**
|
651 |
return self::getCleanIPAndServerVar(array($connectionIP));
|
652 |
} else {
|
653 |
$ipsToCheck = array(
|
654 |
+
array((isset($_SERVER[$howGet]) ? $_SERVER[$howGet] : ''), $howGet),
|
655 |
$connectionIP,
|
656 |
);
|
657 |
return self::getCleanIPAndServerVar($ipsToCheck);
|
lib/wordfenceClass.php
CHANGED
@@ -48,6 +48,13 @@ class wordfence {
|
|
48 |
update_option('wordfenceActivated', 1);
|
49 |
}
|
50 |
public static function uninstallPlugin(){
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
51 |
//Check if caching is enabled and if it is, disable it and fix the .htaccess file.
|
52 |
$cacheType = wfConfig::get('cacheType', false);
|
53 |
if($cacheType == 'falcon'){
|
@@ -552,6 +559,11 @@ SQL
|
|
552 |
|
553 |
wp_schedule_single_event(time(), 'wordfence_sendFalconDeprecationNotice');
|
554 |
}
|
|
|
|
|
|
|
|
|
|
|
555 |
|
556 |
//Must be the final line
|
557 |
}
|
@@ -1018,7 +1030,11 @@ SQL
|
|
1018 |
|
1019 |
$wfFunc = isset($_GET['_wfsf']) ? @$_GET['_wfsf'] : false;
|
1020 |
if($wfFunc == 'unlockEmail'){
|
1021 |
-
|
|
|
|
|
|
|
|
|
1022 |
die("Sorry but your browser sent an invalid security token when trying to use this form.");
|
1023 |
}
|
1024 |
$numTries = get_transient('wordfenceUnlockTries');
|
@@ -1029,9 +1045,10 @@ SQL
|
|
1029 |
if(! $numTries){ $numTries = 1; } else { $numTries = $numTries + 1; }
|
1030 |
set_transient('wordfenceUnlockTries', $numTries, 180);
|
1031 |
|
1032 |
-
$email = trim(
|
1033 |
global $wpdb;
|
1034 |
$ws = $wpdb->get_results($wpdb->prepare("SELECT ID, user_login FROM $wpdb->users WHERE user_email = %s", $email));
|
|
|
1035 |
foreach($ws as $user){
|
1036 |
$userDat = get_userdata($user->ID);
|
1037 |
if(wfUtils::isAdmin($userDat)){
|
@@ -1116,10 +1133,15 @@ SQL
|
|
1116 |
'whitelistedIPs' => (string) wfConfig::get('whitelisted'),
|
1117 |
'howGetIPs' => (string) wfConfig::get('howGetIPs'),
|
1118 |
'other_WFNet' => wfConfig::get('other_WFNet', true),
|
|
|
1119 |
);
|
1120 |
foreach ($configDefaults as $key => $value) {
|
1121 |
$waf->getStorageEngine()->setConfig($key, $value);
|
1122 |
}
|
|
|
|
|
|
|
|
|
1123 |
|
1124 |
if (empty($_GET['wordfence_syncAttackData'])) {
|
1125 |
$lastAttackMicroseconds = $wpdb->get_var("SELECT MAX(attackLogTime) FROM {$wpdb->base_prefix}wfHits");
|
@@ -2001,6 +2023,7 @@ SQL
|
|
2001 |
public static function ajax_sendDiagnostic_callback(){
|
2002 |
$inEmail = true;
|
2003 |
$body = "This email is the diagnostic from " . site_url() . ".\nThe IP address that requested this was: " . wfUtils::getIP() . "\nTicket Number/Forum Username: " . $_POST['ticket'];
|
|
|
2004 |
ob_start();
|
2005 |
require 'menu_diagnostic.php';
|
2006 |
$body = nl2br($body) . ob_get_clean();
|
@@ -2685,6 +2708,15 @@ SQL
|
|
2685 |
readfile($file);
|
2686 |
die();
|
2687 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2688 |
public static function ajax_addCacheExclusion_callback(){
|
2689 |
$ex = wfConfig::get('cacheExclusions', false);
|
2690 |
if($ex){
|
@@ -3205,8 +3237,11 @@ HTACCESS;
|
|
3205 |
);
|
3206 |
}
|
3207 |
public static function ajax_loadIssues_callback(){
|
|
|
|
|
|
|
3208 |
$i = new wfIssues();
|
3209 |
-
$iss = $i->getIssues();
|
3210 |
return array(
|
3211 |
'issuesLists' => $iss,
|
3212 |
'summary' => $i->getSummaryItems(),
|
@@ -4253,7 +4288,7 @@ HTML;
|
|
4253 |
'exportSettings', 'importSettings', 'bulkOperation', 'deleteFile', 'deleteDatabaseOption', 'removeExclusion',
|
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',
|
@@ -4390,7 +4425,8 @@ HTML;
|
|
4390 |
'tourClosed' => wfConfig::get('tourClosed', 0),
|
4391 |
'welcomeClosed' => wfConfig::get('welcomeClosed', 0),
|
4392 |
'cacheType' => wfConfig::get('cacheType'),
|
4393 |
-
'liveTrafficEnabled' => wfConfig::liveTrafficEnabled()
|
|
|
4394 |
));
|
4395 |
}
|
4396 |
public static function activation_warning(){
|
@@ -6287,7 +6323,7 @@ ALERTMSG;
|
|
6287 |
$limit = 500;
|
6288 |
$lastSendTime = wfConfig::get('lastAttackDataSendTime');
|
6289 |
$attackData = $wpdb->get_results($wpdb->prepare("SELECT SQL_CALC_FOUND_ROWS * FROM {$wpdb->base_prefix}wfHits
|
6290 |
-
WHERE action in ('blocked:waf', 'learned:waf', 'logged:waf')
|
6291 |
AND attackLogTime > %.6f
|
6292 |
LIMIT %d", $lastSendTime, $limit));
|
6293 |
$totalRows = $wpdb->get_var('SELECT FOUND_ROWS()');
|
@@ -6330,6 +6366,7 @@ LIMIT %d", $lastSendTime, $limit));
|
|
6330 |
'k' => $waf->getStorageEngine()->getConfig('apiKey'),
|
6331 |
's' => $waf->getStorageEngine()->getConfig('siteURL') ? $waf->getStorageEngine()->getConfig('siteURL') :
|
6332 |
sprintf('%s://%s/', $waf->getRequest()->getProtocol(), rawurlencode($waf->getRequest()->getHost())),
|
|
|
6333 |
), null, '&'),
|
6334 |
array(
|
6335 |
'body' => json_encode($dataToSend),
|
@@ -6382,11 +6419,11 @@ LIMIT %d", $lastSendTime, $limit));
|
|
6382 |
$attackData = $waf->getStorageEngine()->getNewestAttackDataArray($lastAttackMicroseconds);
|
6383 |
if ($attackData) {
|
6384 |
foreach ($attackData as $request) {
|
6385 |
-
if (count($request) !== 9) {
|
6386 |
continue;
|
6387 |
}
|
6388 |
|
6389 |
-
list($logTimeMicroseconds, $requestTime, $ip, $learningMode, $paramKey, $paramValue, $failedRules, $ssl, $requestString) = $request;
|
6390 |
|
6391 |
// Skip old entries and hits in learning mode, since they'll get picked up anyways.
|
6392 |
if ($logTimeMicroseconds <= $lastAttackMicroseconds || $learningMode) {
|
@@ -6437,12 +6474,59 @@ LIMIT %d", $lastSendTime, $limit));
|
|
6437 |
$path = $matches[1];
|
6438 |
}
|
6439 |
}
|
6440 |
-
|
6441 |
-
|
6442 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
6443 |
}
|
6444 |
else {
|
6445 |
-
$
|
|
|
|
|
|
|
|
|
|
|
6446 |
}
|
6447 |
|
6448 |
/** @var wfWAFRule $rule */
|
@@ -6457,13 +6541,13 @@ LIMIT %d", $lastSendTime, $limit));
|
|
6457 |
if ($ruleIDs && $ruleIDs[0]) {
|
6458 |
$rule = $waf->getRule($ruleIDs[0]);
|
6459 |
if ($rule) {
|
6460 |
-
$hit->actionDescription = $rule->getDescription();
|
6461 |
$actionData['category'] = $rule->getCategory();
|
6462 |
$actionData['ssl'] = $ssl;
|
6463 |
$actionData['fullRequest'] = base64_encode($requestString);
|
6464 |
}
|
6465 |
else if ($ruleIDs[0] == 'logged') {
|
6466 |
-
$hit->actionDescription = 'Watched IP Traffic: ' . $ip;
|
6467 |
$actionData['category'] = 'logged';
|
6468 |
$actionData['ssl'] = $ssl;
|
6469 |
$actionData['fullRequest'] = base64_encode($requestString);
|
48 |
update_option('wordfenceActivated', 1);
|
49 |
}
|
50 |
public static function uninstallPlugin(){
|
51 |
+
//Send admin alert
|
52 |
+
if (wfConfig::get('alertOn_wordfenceDeactivated')) {
|
53 |
+
$currentUser = wp_get_current_user();
|
54 |
+
$username = $currentUser->user_login;
|
55 |
+
wordfence::alert("Wordfence Deactivated", "A user with username \"$username\" deactivated Wordfence on your WordPress site.", wfUtils::getIP());
|
56 |
+
}
|
57 |
+
|
58 |
//Check if caching is enabled and if it is, disable it and fix the .htaccess file.
|
59 |
$cacheType = wfConfig::get('cacheType', false);
|
60 |
if($cacheType == 'falcon'){
|
559 |
|
560 |
wp_schedule_single_event(time(), 'wordfence_sendFalconDeprecationNotice');
|
561 |
}
|
562 |
+
|
563 |
+
//6.2.3
|
564 |
+
if (!WFWAF_SUBDIRECTORY_INSTALL && class_exists('wfWAFIPBlocksController')) {
|
565 |
+
wfWAFIPBlocksController::synchronizeConfigSettings();
|
566 |
+
}
|
567 |
|
568 |
//Must be the final line
|
569 |
}
|
1030 |
|
1031 |
$wfFunc = isset($_GET['_wfsf']) ? @$_GET['_wfsf'] : false;
|
1032 |
if($wfFunc == 'unlockEmail'){
|
1033 |
+
$nonceValid = wp_verify_nonce(@$_POST['nonce'], 'wf-form');
|
1034 |
+
if (!$nonceValid && method_exists(wfWAF::getInstance(), 'createNonce')) {
|
1035 |
+
$nonceValid = wfWAF::getInstance()->verifyNonce(@$_POST['nonce'], 'wf-form');
|
1036 |
+
}
|
1037 |
+
if(!$nonceValid){
|
1038 |
die("Sorry but your browser sent an invalid security token when trying to use this form.");
|
1039 |
}
|
1040 |
$numTries = get_transient('wordfenceUnlockTries');
|
1045 |
if(! $numTries){ $numTries = 1; } else { $numTries = $numTries + 1; }
|
1046 |
set_transient('wordfenceUnlockTries', $numTries, 180);
|
1047 |
|
1048 |
+
$email = trim(@$_POST['email']);
|
1049 |
global $wpdb;
|
1050 |
$ws = $wpdb->get_results($wpdb->prepare("SELECT ID, user_login FROM $wpdb->users WHERE user_email = %s", $email));
|
1051 |
+
$found = false;
|
1052 |
foreach($ws as $user){
|
1053 |
$userDat = get_userdata($user->ID);
|
1054 |
if(wfUtils::isAdmin($userDat)){
|
1133 |
'whitelistedIPs' => (string) wfConfig::get('whitelisted'),
|
1134 |
'howGetIPs' => (string) wfConfig::get('howGetIPs'),
|
1135 |
'other_WFNet' => wfConfig::get('other_WFNet', true),
|
1136 |
+
'pluginABSPATH' => ABSPATH,
|
1137 |
);
|
1138 |
foreach ($configDefaults as $key => $value) {
|
1139 |
$waf->getStorageEngine()->setConfig($key, $value);
|
1140 |
}
|
1141 |
+
|
1142 |
+
if (class_exists('wfWAFIPBlocksController')) {
|
1143 |
+
wfWAFIPBlocksController::synchronizeConfigSettings();
|
1144 |
+
}
|
1145 |
|
1146 |
if (empty($_GET['wordfence_syncAttackData'])) {
|
1147 |
$lastAttackMicroseconds = $wpdb->get_var("SELECT MAX(attackLogTime) FROM {$wpdb->base_prefix}wfHits");
|
2023 |
public static function ajax_sendDiagnostic_callback(){
|
2024 |
$inEmail = true;
|
2025 |
$body = "This email is the diagnostic from " . site_url() . ".\nThe IP address that requested this was: " . wfUtils::getIP() . "\nTicket Number/Forum Username: " . $_POST['ticket'];
|
2026 |
+
$sendingDiagnosticEmail = true;
|
2027 |
ob_start();
|
2028 |
require 'menu_diagnostic.php';
|
2029 |
$body = nl2br($body) . ob_get_clean();
|
2708 |
readfile($file);
|
2709 |
die();
|
2710 |
}
|
2711 |
+
public static function ajax_downloadLogFile_callback() {
|
2712 |
+
if (!isset($_GET['logfile'])) {
|
2713 |
+
status_header(400);
|
2714 |
+
nocache_headers();
|
2715 |
+
exit;
|
2716 |
+
}
|
2717 |
+
|
2718 |
+
wfErrorLogHandler::outputErrorLog($_GET['logfile']); //exits
|
2719 |
+
}
|
2720 |
public static function ajax_addCacheExclusion_callback(){
|
2721 |
$ex = wfConfig::get('cacheExclusions', false);
|
2722 |
if($ex){
|
3237 |
);
|
3238 |
}
|
3239 |
public static function ajax_loadIssues_callback(){
|
3240 |
+
$offset = isset($_POST['offset']) ? intval($_POST['offset']) : 0;
|
3241 |
+
$limit = isset($_POST['limit']) ? intval($_POST['limit']) : WORDFENCE_SCAN_ISSUES_PER_PAGE;
|
3242 |
+
|
3243 |
$i = new wfIssues();
|
3244 |
+
$iss = $i->getIssues($offset, $limit);
|
3245 |
return array(
|
3246 |
'issuesLists' => $iss,
|
3247 |
'summary' => $i->getSummaryItems(),
|
4288 |
'exportSettings', 'importSettings', 'bulkOperation', 'deleteFile', 'deleteDatabaseOption', 'removeExclusion',
|
4289 |
'activityLogUpdate', 'ticker', 'loadIssues', 'updateIssueStatus', 'deleteIssue', 'updateAllIssues',
|
4290 |
'reverseLookup', 'unlockOutIP', 'loadBlockRanges', 'unblockRange', 'blockIPUARange', 'whois', 'unblockIP',
|
4291 |
+
'blockIP', 'permBlockIP', 'loadStaticPanel', 'saveConfig', 'downloadHtaccess', 'downloadLogFile', 'checkFalconHtaccess',
|
4292 |
'updateConfig', 'saveCacheConfig', 'removeFromCache', 'autoUpdateChoice', 'adminEmailChoice', 'suPHPWAFUpdateChoice', 'falconDeprecationChoice', 'saveCacheOptions', 'clearPageCache',
|
4293 |
'getCacheStats', 'clearAllBlocked', 'killScan', 'saveCountryBlocking', 'saveScanSchedule', 'tourClosed',
|
4294 |
'welcomeClosed', 'startTourAgain', 'downgradeLicense', 'addTwoFactor', 'twoFacActivate', 'twoFacDel',
|
4425 |
'tourClosed' => wfConfig::get('tourClosed', 0),
|
4426 |
'welcomeClosed' => wfConfig::get('welcomeClosed', 0),
|
4427 |
'cacheType' => wfConfig::get('cacheType'),
|
4428 |
+
'liveTrafficEnabled' => wfConfig::liveTrafficEnabled(),
|
4429 |
+
'scanIssuesPerPage' => WORDFENCE_SCAN_ISSUES_PER_PAGE,
|
4430 |
));
|
4431 |
}
|
4432 |
public static function activation_warning(){
|
6323 |
$limit = 500;
|
6324 |
$lastSendTime = wfConfig::get('lastAttackDataSendTime');
|
6325 |
$attackData = $wpdb->get_results($wpdb->prepare("SELECT SQL_CALC_FOUND_ROWS * FROM {$wpdb->base_prefix}wfHits
|
6326 |
+
WHERE action in ('blocked:waf', 'learned:waf', 'logged:waf', 'blocked:waf-always')
|
6327 |
AND attackLogTime > %.6f
|
6328 |
LIMIT %d", $lastSendTime, $limit));
|
6329 |
$totalRows = $wpdb->get_var('SELECT FOUND_ROWS()');
|
6366 |
'k' => $waf->getStorageEngine()->getConfig('apiKey'),
|
6367 |
's' => $waf->getStorageEngine()->getConfig('siteURL') ? $waf->getStorageEngine()->getConfig('siteURL') :
|
6368 |
sprintf('%s://%s/', $waf->getRequest()->getProtocol(), rawurlencode($waf->getRequest()->getHost())),
|
6369 |
+
't' => microtime(true),
|
6370 |
), null, '&'),
|
6371 |
array(
|
6372 |
'body' => json_encode($dataToSend),
|
6419 |
$attackData = $waf->getStorageEngine()->getNewestAttackDataArray($lastAttackMicroseconds);
|
6420 |
if ($attackData) {
|
6421 |
foreach ($attackData as $request) {
|
6422 |
+
if (count($request) !== 9 && count($request) !== 10 /* with metadata */) {
|
6423 |
continue;
|
6424 |
}
|
6425 |
|
6426 |
+
list($logTimeMicroseconds, $requestTime, $ip, $learningMode, $paramKey, $paramValue, $failedRules, $ssl, $requestString, $metadata) = $request;
|
6427 |
|
6428 |
// Skip old entries and hits in learning mode, since they'll get picked up anyways.
|
6429 |
if ($logTimeMicroseconds <= $lastAttackMicroseconds || $learningMode) {
|
6474 |
$path = $matches[1];
|
6475 |
}
|
6476 |
}
|
6477 |
+
|
6478 |
+
$metadata = ($metadata != null ? (array) $metadata : array());
|
6479 |
+
if (isset($metadata['finalAction']) && $metadata['finalAction']) { // The request was blocked/redirected because of its IP based on the plugin's blocking settings. WAF blocks should be reported but not shown in live traffic with that as a reason.
|
6480 |
+
$action = $metadata['finalAction']['action'];
|
6481 |
+
$actionDescription = $action;
|
6482 |
+
if (class_exists('wfWAFIPBlocksController')) {
|
6483 |
+
if ($action == wfWAFIPBlocksController::WFWAF_BLOCK_UAREFIPRANGE) {
|
6484 |
+
$id = $metadata['finalAction']['id'];
|
6485 |
+
$wpdb->query($wpdb->prepare("UPDATE {$wpdb->base_prefix}wfBlocksAdv SET totalBlocked = totalBlocked + 1, lastBlocked = %d WHERE id = %d", $requestTime, $id));
|
6486 |
+
wfActivityReport::logBlockedIP($ip);
|
6487 |
+
}
|
6488 |
+
else if ($action == wfWAFIPBlocksController::WFWAF_BLOCK_COUNTRY_REDIR) {
|
6489 |
+
$actionDescription .= ' (' . wfConfig::get('cbl_redirURL') . ')';
|
6490 |
+
wfConfig::inc('totalCountryBlocked');
|
6491 |
+
wfActivityReport::logBlockedIP($ip);
|
6492 |
+
}
|
6493 |
+
else if ($action == wfWAFIPBlocksController::WFWAF_BLOCK_COUNTRY) {
|
6494 |
+
wfConfig::inc('totalCountryBlocked');
|
6495 |
+
wfActivityReport::logBlockedIP($ip);
|
6496 |
+
}
|
6497 |
+
else if ($action == wfWAFIPBlocksController::WFWAF_BLOCK_WFSN) {
|
6498 |
+
wordfence::wfsnReportBlockedAttempt($ip, 'login');
|
6499 |
+
}
|
6500 |
+
}
|
6501 |
+
|
6502 |
+
if (strlen($actionDescription) == 0) {
|
6503 |
+
$actionDescription = 'Blocked by Wordfence';
|
6504 |
+
}
|
6505 |
+
|
6506 |
+
if (empty($failedRules)) { // Just a plugin block
|
6507 |
+
$hit->action = 'blocked:wordfence';
|
6508 |
+
if (class_exists('wfWAFIPBlocksController')) {
|
6509 |
+
if ($action == wfWAFIPBlocksController::WFWAF_BLOCK_WFSN) {
|
6510 |
+
$hit->action = 'blocked:wfsnrepeat';
|
6511 |
+
}
|
6512 |
+
}
|
6513 |
+
$hit->actionDescription = $actionDescription;
|
6514 |
+
}
|
6515 |
+
else if ($failedRules == 'logged') {
|
6516 |
+
$hit->action = 'logged:waf';
|
6517 |
+
}
|
6518 |
+
else { // Blocked by the WAF but would've been blocked anyway by the plugin settings so that message takes priority
|
6519 |
+
$hit->action = 'blocked:waf-always';
|
6520 |
+
$hit->actionDescription = $actionDescription;
|
6521 |
+
}
|
6522 |
}
|
6523 |
else {
|
6524 |
+
if ($failedRules == 'logged') {
|
6525 |
+
$hit->action = 'logged:waf';
|
6526 |
+
}
|
6527 |
+
else {
|
6528 |
+
$hit->action = 'blocked:waf';
|
6529 |
+
}
|
6530 |
}
|
6531 |
|
6532 |
/** @var wfWAFRule $rule */
|
6541 |
if ($ruleIDs && $ruleIDs[0]) {
|
6542 |
$rule = $waf->getRule($ruleIDs[0]);
|
6543 |
if ($rule) {
|
6544 |
+
if ($hit->action == 'logged:waf' || $hit->action == 'blocked:waf') { $hit->actionDescription = $rule->getDescription(); }
|
6545 |
$actionData['category'] = $rule->getCategory();
|
6546 |
$actionData['ssl'] = $ssl;
|
6547 |
$actionData['fullRequest'] = base64_encode($requestString);
|
6548 |
}
|
6549 |
else if ($ruleIDs[0] == 'logged') {
|
6550 |
+
if ($hit->action == 'logged:waf' || $hit->action == 'blocked:waf') { $hit->actionDescription = 'Watched IP Traffic: ' . $ip; }
|
6551 |
$actionData['category'] = 'logged';
|
6552 |
$actionData['ssl'] = $ssl;
|
6553 |
$actionData['fullRequest'] = base64_encode($requestString);
|
lib/wordfenceConstants.php
CHANGED
@@ -13,4 +13,5 @@ define('WORDFENCE_REVERSE_LOOKUP_CACHE_TIME', 86400);
|
|
13 |
define('WORDFENCE_MAX_FILE_SIZE_TO_PROCESS', 52428800); //50 megs
|
14 |
define('WORDFENCE_TWO_FACTOR_GRACE_TIME_AUTHENTICATOR', 90);
|
15 |
define('WORDFENCE_TWO_FACTOR_GRACE_TIME_PHONE', 1800);
|
|
|
16 |
?>
|
13 |
define('WORDFENCE_MAX_FILE_SIZE_TO_PROCESS', 52428800); //50 megs
|
14 |
define('WORDFENCE_TWO_FACTOR_GRACE_TIME_AUTHENTICATOR', 90);
|
15 |
define('WORDFENCE_TWO_FACTOR_GRACE_TIME_PHONE', 1800);
|
16 |
+
if (!defined('WORDFENCE_SCAN_ISSUES_PER_PAGE')) { define('WORDFENCE_SCAN_ISSUES_PER_PAGE', 100); }
|
17 |
?>
|
readme.txt
CHANGED
@@ -3,7 +3,7 @@ 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 scan, blocking, live traffic, login security & more.
|
9 |
|
@@ -190,6 +190,21 @@ Secure your website with Wordfence.
|
|
190 |
|
191 |
== Changelog ==
|
192 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
193 |
= 6.2.2 =
|
194 |
* Fix: Replaced a slow query in the dashboard widget that could affect sites with very large numbers of users.
|
195 |
|
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.3
|
7 |
|
8 |
Secure your website with the most comprehensive WordPress security plugin. Firewall, malware scan, blocking, live traffic, login security & more.
|
9 |
|
190 |
|
191 |
== Changelog ==
|
192 |
|
193 |
+
= 6.2.3 =
|
194 |
+
* Improvement: Reworked blocking for IP ranges, country blocking, and direct IP blocking to minimize server impact when under attack.
|
195 |
+
* Improvement: Live traffic better indicates the action taken by country blocking when it redirects a visitor.
|
196 |
+
* Improvement: Added support for finding server logs to the Diagnostics page to help with troubleshooting.
|
197 |
+
* Improvement: Whitelisted StatusCake IP addresses.
|
198 |
+
* Improvement: Updated GeoIP database.
|
199 |
+
* Improvement: Disabling Wordfence now sends an alert.
|
200 |
+
* Improvement: Improved detection for uploaded PHP content in the firewall.
|
201 |
+
* Fix: Eliminated memory-related errors resulting from the scan on sites with very large numbers of issues and low memory.
|
202 |
+
* Fix: Fixed admin page layout for sites using RTL languages.
|
203 |
+
* Fix: Reduced overhead of the dashboard widget.
|
204 |
+
* Fix: Improved performance of checking for whitelisted IPs.
|
205 |
+
* Fix: Changes to the default plugin hello.php are now detected correctly in scans.
|
206 |
+
* Fix: Fixed IPv6 warning in the dashboard widget.
|
207 |
+
|
208 |
= 6.2.2 =
|
209 |
* Fix: Replaced a slow query in the dashboard widget that could affect sites with very large numbers of users.
|
210 |
|
vendor/wordfence/wf-waf/src/lib/request.php
CHANGED
@@ -21,6 +21,9 @@ interface wfWAFRequestInterface {
|
|
21 |
public function getHost();
|
22 |
|
23 |
public function getURI();
|
|
|
|
|
|
|
24 |
|
25 |
public function getPath();
|
26 |
|
@@ -73,6 +76,7 @@ class wfWAFRequest implements wfWAFRequestInterface {
|
|
73 |
$request->setMd5QueryString(array());
|
74 |
$request->setTimestamp('');
|
75 |
$request->setURI('');
|
|
|
76 |
|
77 |
list($headersString, $bodyString) = explode("\n\n", $requestString, 2);
|
78 |
$headersString = trim($headersString);
|
@@ -241,6 +245,7 @@ class wfWAFRequest implements wfWAFRequestInterface {
|
|
241 |
$request->setProtocol('');
|
242 |
$request->setTimestamp('');
|
243 |
$request->setURI('');
|
|
|
244 |
|
245 |
$request->setBody(wfWAFUtils::stripMagicQuotes($_POST));
|
246 |
$request->setQueryString(wfWAFUtils::stripMagicQuotes($_GET));
|
@@ -332,6 +337,7 @@ class wfWAFRequest implements wfWAFRequestInterface {
|
|
332 |
private $md5QueryString;
|
333 |
private $timestamp;
|
334 |
private $uri;
|
|
|
335 |
|
336 |
private $highlightParamFormat;
|
337 |
private $highlightMatchFormat;
|
@@ -467,6 +473,14 @@ class wfWAFRequest implements wfWAFRequestInterface {
|
|
467 |
public function getURI() {
|
468 |
return $this->uri;
|
469 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
470 |
|
471 |
public function getPath() {
|
472 |
return $this->path;
|
@@ -909,5 +923,12 @@ FORM;
|
|
909 |
public function setUri($uri) {
|
910 |
$this->uri = $uri;
|
911 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
912 |
}
|
913 |
|
21 |
public function getHost();
|
22 |
|
23 |
public function getURI();
|
24 |
+
|
25 |
+
public function setMetadata($metadata);
|
26 |
+
public function getMetadata();
|
27 |
|
28 |
public function getPath();
|
29 |
|
76 |
$request->setMd5QueryString(array());
|
77 |
$request->setTimestamp('');
|
78 |
$request->setURI('');
|
79 |
+
$request->setMetadata(array());
|
80 |
|
81 |
list($headersString, $bodyString) = explode("\n\n", $requestString, 2);
|
82 |
$headersString = trim($headersString);
|
245 |
$request->setProtocol('');
|
246 |
$request->setTimestamp('');
|
247 |
$request->setURI('');
|
248 |
+
$request->setMetadata(array());
|
249 |
|
250 |
$request->setBody(wfWAFUtils::stripMagicQuotes($_POST));
|
251 |
$request->setQueryString(wfWAFUtils::stripMagicQuotes($_GET));
|
337 |
private $md5QueryString;
|
338 |
private $timestamp;
|
339 |
private $uri;
|
340 |
+
private $metadata;
|
341 |
|
342 |
private $highlightParamFormat;
|
343 |
private $highlightMatchFormat;
|
473 |
public function getURI() {
|
474 |
return $this->uri;
|
475 |
}
|
476 |
+
|
477 |
+
public function getMetadata() {
|
478 |
+
if (func_num_args() > 0) {
|
479 |
+
$args = func_get_args();
|
480 |
+
return $this->_arrayValueByKeys($this->metadata, $args);
|
481 |
+
}
|
482 |
+
return $this->metadata;
|
483 |
+
}
|
484 |
|
485 |
public function getPath() {
|
486 |
return $this->path;
|
923 |
public function setUri($uri) {
|
924 |
$this->uri = $uri;
|
925 |
}
|
926 |
+
|
927 |
+
/**
|
928 |
+
* @param array $metadata
|
929 |
+
*/
|
930 |
+
public function setMetadata($metadata) {
|
931 |
+
$this->metadata = $metadata;
|
932 |
+
}
|
933 |
}
|
934 |
|
vendor/wordfence/wf-waf/src/lib/rules.php
CHANGED
@@ -751,6 +751,7 @@ class wfWAFRuleComparison implements wfWAFRuleInterface {
|
|
751 |
}
|
752 |
|
753 |
$totalRead = 0;
|
|
|
754 |
$hasExecutablePHP = false;
|
755 |
$possiblyHasExecutablePHP = false;
|
756 |
$hasOpenParen = false;
|
@@ -760,7 +761,7 @@ class wfWAFRuleComparison implements wfWAFRuleInterface {
|
|
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 =
|
764 |
while (!feof($fh)) {
|
765 |
$data = fread($fh, $readsize);
|
766 |
$actualReadsize = strlen($data);
|
@@ -782,26 +783,81 @@ class wfWAFRuleComparison implements wfWAFRuleInterface {
|
|
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 |
}
|
@@ -822,6 +878,7 @@ class wfWAFRuleComparison implements wfWAFRuleInterface {
|
|
822 |
}
|
823 |
}
|
824 |
else {
|
|
|
825 |
switch ($token) {
|
826 |
case '(':
|
827 |
$hasOpenParen = true;
|
@@ -841,16 +898,35 @@ class wfWAFRuleComparison implements wfWAFRuleInterface {
|
|
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
|
751 |
}
|
752 |
|
753 |
$totalRead = 0;
|
754 |
+
$insideOpenTag = false;
|
755 |
$hasExecutablePHP = false;
|
756 |
$possiblyHasExecutablePHP = false;
|
757 |
$hasOpenParen = false;
|
761 |
$maxTokenSize = 15; //__halt_compiler
|
762 |
$possibleWrappedTokens = array('<?php', '<?=', '<?', '?>', 'exit', 'new', 'clone', 'echo', 'print', 'require', 'include', 'require_once', 'include_once', '__halt_compiler');
|
763 |
|
764 |
+
$readsize = 100 * 1024; //100k at a time
|
765 |
while (!feof($fh)) {
|
766 |
$data = fread($fh, $readsize);
|
767 |
$actualReadsize = strlen($data);
|
783 |
}
|
784 |
}
|
785 |
|
786 |
+
//Make sure it tokenizes correctly if chunked
|
787 |
+
if ($insideOpenTag) {
|
788 |
+
if ($possiblyHasExecutablePHP) {
|
789 |
+
$data = '<?= ' . $data;
|
790 |
+
}
|
791 |
+
else {
|
792 |
+
$data = '<?php ' . $data;
|
793 |
+
}
|
794 |
+
}
|
795 |
+
|
796 |
//Tokenize the data and check for PHP
|
797 |
+
$this->_resetErrors();
|
798 |
$tokens = @token_get_all($data);
|
799 |
+
$error = error_get_last();
|
800 |
+
if ($error !== null && stripos($error['message'], 'Unexpected character in input') !== false) {
|
801 |
+
break;
|
802 |
+
}
|
803 |
+
|
804 |
+
if ($error !== null && feof($fh) && stripos($error['message'], 'Unterminated comment') !== false) {
|
805 |
+
break;
|
806 |
+
}
|
807 |
+
|
808 |
+
$offset = 0;
|
809 |
foreach ($tokens as $token) {
|
810 |
if (is_array($token)) {
|
811 |
+
$offset += strlen($token[1]);
|
812 |
switch ($token[0]) {
|
813 |
case T_OPEN_TAG:
|
814 |
+
$insideOpenTag = true;
|
815 |
$hasOpenParen = false;
|
816 |
$hasCloseParen = false;
|
817 |
$backtickCount = 0;
|
818 |
$possiblyHasExecutablePHP = false;
|
819 |
+
|
820 |
+
if ($error !== null && stripos($error['message'], 'Unterminated comment') !== false) {
|
821 |
+
$testOffset = $offset - strlen($token[1]);
|
822 |
+
$commentStart = strpos($data, '/*', $testOffset);
|
823 |
+
if ($commentStart !== false) {
|
824 |
+
$testBytes = substr($data, $testOffset, $commentStart - $testOffset);
|
825 |
+
$this->_resetErrors();
|
826 |
+
@token_get_all($testBytes);
|
827 |
+
$error = error_get_last();
|
828 |
+
if ($error !== null && stripos($error['message'], 'Unexpected character in input') !== false) {
|
829 |
+
break 3;
|
830 |
+
}
|
831 |
+
}
|
832 |
+
}
|
833 |
+
|
834 |
break;
|
835 |
|
836 |
case T_OPEN_TAG_WITH_ECHO:
|
837 |
+
$insideOpenTag = true;
|
838 |
$hasOpenParen = false;
|
839 |
$hasCloseParen = false;
|
840 |
$backtickCount = 0;
|
841 |
$possiblyHasExecutablePHP = true;
|
842 |
+
|
843 |
+
if ($error !== null && stripos($error['message'], 'Unterminated comment') !== false) {
|
844 |
+
$testOffset = $offset - strlen($token[1]);
|
845 |
+
$commentStart = strpos($data, '/*', $testOffset);
|
846 |
+
if ($commentStart !== false) {
|
847 |
+
$testBytes = substr($data, $testOffset, $commentStart - $testOffset);
|
848 |
+
$this->_resetErrors();
|
849 |
+
@token_get_all($testBytes);
|
850 |
+
$error = error_get_last();
|
851 |
+
if ($error !== null && stripos($error['message'], 'Unexpected character in input') !== false) {
|
852 |
+
break 3;
|
853 |
+
}
|
854 |
+
}
|
855 |
+
}
|
856 |
+
|
857 |
break;
|
858 |
|
859 |
case T_CLOSE_TAG:
|
860 |
+
$insideOpenTag = false;
|
861 |
if ($possiblyHasExecutablePHP) {
|
862 |
$hasExecutablePHP = true; //Assume the echo short tag outputted something useful
|
863 |
}
|
878 |
}
|
879 |
}
|
880 |
else {
|
881 |
+
$offset += strlen($token);
|
882 |
switch ($token) {
|
883 |
case '(':
|
884 |
$hasOpenParen = true;
|
898 |
}
|
899 |
|
900 |
if ($hasExecutablePHP) {
|
901 |
+
fclose($fh);
|
902 |
return true;
|
903 |
}
|
904 |
|
905 |
$wrappedTokenCheckBytes = substr($data, - min($maxTokenSize, $actualReadsize));
|
906 |
}
|
907 |
+
|
908 |
+
fclose($fh);
|
909 |
}
|
910 |
}
|
911 |
|
912 |
return false;
|
913 |
}
|
914 |
+
|
915 |
+
private function _resetErrors() {
|
916 |
+
if (function_exists('error_clear_last')) {
|
917 |
+
error_clear_last();
|
918 |
+
}
|
919 |
+
else {
|
920 |
+
// set error_get_last() to defined state by forcing an undefined variable error
|
921 |
+
set_error_handler(array($this, '_resetErrorsHandler'), 0);
|
922 |
+
@$undefinedVariable;
|
923 |
+
restore_error_handler();
|
924 |
+
}
|
925 |
+
}
|
926 |
+
|
927 |
+
public function _resetErrorsHandler($errno, $errstr, $errfile, $errline) {
|
928 |
+
//Do nothing
|
929 |
+
}
|
930 |
|
931 |
/**
|
932 |
* @return mixed
|
vendor/wordfence/wf-waf/src/lib/utils.php
CHANGED
@@ -544,4 +544,200 @@ class wfWAFUtils {
|
|
544 |
|
545 |
return intval($val);
|
546 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
547 |
}
|
544 |
|
545 |
return intval($val);
|
546 |
}
|
547 |
+
|
548 |
+
public static function reverseLookup($IP) {
|
549 |
+
$IPn = self::inet_pton($IP);
|
550 |
+
// This function works for IPv4 or IPv6
|
551 |
+
if (function_exists('gethostbyaddr')) {
|
552 |
+
$host = @gethostbyaddr($IP);
|
553 |
+
}
|
554 |
+
if (!$host) {
|
555 |
+
$ptr = false;
|
556 |
+
if (filter_var($IP, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) !== false) {
|
557 |
+
$ptr = implode(".", array_reverse(explode(".", $IP))) . ".in-addr.arpa";
|
558 |
+
} else if (filter_var($IP, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) !== false) {
|
559 |
+
$ptr = implode(".", array_reverse(str_split(bin2hex($IPn)))) . ".ip6.arpa";
|
560 |
+
}
|
561 |
+
|
562 |
+
if ($ptr && function_exists('dns_get_record')) {
|
563 |
+
$host = @dns_get_record($ptr, DNS_PTR);
|
564 |
+
if ($host) {
|
565 |
+
$host = $host[0]['target'];
|
566 |
+
}
|
567 |
+
}
|
568 |
+
}
|
569 |
+
if (!$host) {
|
570 |
+
return '';
|
571 |
+
}
|
572 |
+
return $host;
|
573 |
+
}
|
574 |
+
|
575 |
+
public static function patternToRegex($pattern, $mod = 'i', $sep = '/') {
|
576 |
+
$pattern = preg_quote(trim($pattern), $sep);
|
577 |
+
$pattern = str_replace(' ', '\s', $pattern);
|
578 |
+
return $sep . '^' . str_replace('\*', '.*', $pattern) . '$' . $sep . $mod;
|
579 |
+
}
|
580 |
+
|
581 |
+
public static function isUABlocked($uaPattern, $ua) { // takes a pattern using asterisks as wildcards, turns it into regex and checks it against the visitor UA returning true if blocked
|
582 |
+
return fnmatch($uaPattern, $ua, FNM_CASEFOLD);
|
583 |
+
}
|
584 |
+
|
585 |
+
public static function isRefererBlocked($refPattern, $referer) {
|
586 |
+
return fnmatch($refPattern, $referer, FNM_CASEFOLD);
|
587 |
+
}
|
588 |
+
|
589 |
+
public static function extractBareURI($URL) {
|
590 |
+
$URL = preg_replace('/^https?:\/\/[^\/]+/i', '', $URL); //strip of method and host
|
591 |
+
$URL = preg_replace('/\#.*$/', '', $URL); //strip off fragment
|
592 |
+
$URL = preg_replace('/\?.*$/', '', $URL); //strip off query string
|
593 |
+
return $URL;
|
594 |
+
}
|
595 |
+
|
596 |
+
public static function extractHostname($str) {
|
597 |
+
if (preg_match('/https?:\/\/([a-zA-Z0-9\.\-]+)(?:\/|$)/i', $str, $matches)) {
|
598 |
+
return strtolower($matches[1]);
|
599 |
+
}
|
600 |
+
else {
|
601 |
+
return false;
|
602 |
+
}
|
603 |
+
}
|
604 |
+
|
605 |
+
public static function redirect($location, $status = 302) {
|
606 |
+
$is_apache = (strpos($_SERVER['SERVER_SOFTWARE'], 'Apache') !== false || strpos($_SERVER['SERVER_SOFTWARE'], 'LiteSpeed') !== false);
|
607 |
+
$is_IIS = !$is_apache && (strpos($_SERVER['SERVER_SOFTWARE'], 'Microsoft-IIS') !== false || strpos($_SERVER['SERVER_SOFTWARE'], 'ExpressionDevServer') !== false);
|
608 |
+
|
609 |
+
if (!$is_IIS && PHP_SAPI != 'cgi-fcgi') {
|
610 |
+
self::statusHeader($status); // This causes problems on IIS and some FastCGI setups
|
611 |
+
}
|
612 |
+
|
613 |
+
header("Location: {$location}", true, $status);
|
614 |
+
exit;
|
615 |
+
}
|
616 |
+
|
617 |
+
public static function statusHeader($code) {
|
618 |
+
$code = abs(intval($code));
|
619 |
+
|
620 |
+
$statusCodes = array(
|
621 |
+
100 => 'Continue',
|
622 |
+
101 => 'Switching Protocols',
|
623 |
+
102 => 'Processing',
|
624 |
+
|
625 |
+
200 => 'OK',
|
626 |
+
201 => 'Created',
|
627 |
+
202 => 'Accepted',
|
628 |
+
203 => 'Non-Authoritative Information',
|
629 |
+
204 => 'No Content',
|
630 |
+
205 => 'Reset Content',
|
631 |
+
206 => 'Partial Content',
|
632 |
+
207 => 'Multi-Status',
|
633 |
+
226 => 'IM Used',
|
634 |
+
|
635 |
+
300 => 'Multiple Choices',
|
636 |
+
301 => 'Moved Permanently',
|
637 |
+
302 => 'Found',
|
638 |
+
303 => 'See Other',
|
639 |
+
304 => 'Not Modified',
|
640 |
+
305 => 'Use Proxy',
|
641 |
+
306 => 'Reserved',
|
642 |
+
307 => 'Temporary Redirect',
|
643 |
+
308 => 'Permanent Redirect',
|
644 |
+
|
645 |
+
400 => 'Bad Request',
|
646 |
+
401 => 'Unauthorized',
|
647 |
+
402 => 'Payment Required',
|
648 |
+
403 => 'Forbidden',
|
649 |
+
404 => 'Not Found',
|
650 |
+
405 => 'Method Not Allowed',
|
651 |
+
406 => 'Not Acceptable',
|
652 |
+
407 => 'Proxy Authentication Required',
|
653 |
+
408 => 'Request Timeout',
|
654 |
+
409 => 'Conflict',
|
655 |
+
410 => 'Gone',
|
656 |
+
411 => 'Length Required',
|
657 |
+
412 => 'Precondition Failed',
|
658 |
+
413 => 'Request Entity Too Large',
|
659 |
+
414 => 'Request-URI Too Long',
|
660 |
+
415 => 'Unsupported Media Type',
|
661 |
+
416 => 'Requested Range Not Satisfiable',
|
662 |
+
417 => 'Expectation Failed',
|
663 |
+
418 => 'I\'m a teapot',
|
664 |
+
421 => 'Misdirected Request',
|
665 |
+
422 => 'Unprocessable Entity',
|
666 |
+
423 => 'Locked',
|
667 |
+
424 => 'Failed Dependency',
|
668 |
+
426 => 'Upgrade Required',
|
669 |
+
428 => 'Precondition Required',
|
670 |
+
429 => 'Too Many Requests',
|
671 |
+
431 => 'Request Header Fields Too Large',
|
672 |
+
451 => 'Unavailable For Legal Reasons',
|
673 |
+
|
674 |
+
500 => 'Internal Server Error',
|
675 |
+
501 => 'Not Implemented',
|
676 |
+
502 => 'Bad Gateway',
|
677 |
+
503 => 'Service Unavailable',
|
678 |
+
504 => 'Gateway Timeout',
|
679 |
+
505 => 'HTTP Version Not Supported',
|
680 |
+
506 => 'Variant Also Negotiates',
|
681 |
+
507 => 'Insufficient Storage',
|
682 |
+
510 => 'Not Extended',
|
683 |
+
511 => 'Network Authentication Required',
|
684 |
+
);
|
685 |
+
|
686 |
+
$description = (isset($statusCodes[$code]) ? $statusCodes[$code] : '');
|
687 |
+
|
688 |
+
$protocol = $_SERVER['SERVER_PROTOCOL'];
|
689 |
+
if (!in_array($protocol, array( 'HTTP/1.1', 'HTTP/2', 'HTTP/2.0'))) {
|
690 |
+
$protocol = 'HTTP/1.0';
|
691 |
+
}
|
692 |
+
|
693 |
+
$header = "{$protocol} {$code} {$description}";
|
694 |
+
@header($header, true, $code);
|
695 |
+
}
|
696 |
+
|
697 |
+
/**
|
698 |
+
* Check if an IP address is in a network block
|
699 |
+
*
|
700 |
+
* @param string $subnet Single IP or subnet in CIDR notation (e.g. '192.168.100.0' or '192.168.100.0/22')
|
701 |
+
* @param string $ip IPv4 or IPv6 address in dot or colon notation
|
702 |
+
* @return boolean
|
703 |
+
*/
|
704 |
+
public static function subnetContainsIP($subnet, $ip) {
|
705 |
+
list($network, $prefix) = array_pad(explode('/', $subnet, 2), 2, null);
|
706 |
+
|
707 |
+
if (filter_var($network, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) {
|
708 |
+
// If no prefix was supplied, 32 is implied for IPv4
|
709 |
+
if ($prefix === null) {
|
710 |
+
$prefix = 32;
|
711 |
+
}
|
712 |
+
|
713 |
+
// Validate the IPv4 network prefix
|
714 |
+
if ($prefix < 0 || $prefix > 32) {
|
715 |
+
return false;
|
716 |
+
}
|
717 |
+
|
718 |
+
// Increase the IPv4 network prefix to work in the IPv6 address space
|
719 |
+
$prefix += 96;
|
720 |
+
} else {
|
721 |
+
// If no prefix was supplied, 128 is implied for IPv6
|
722 |
+
if ($prefix === null) {
|
723 |
+
$prefix = 128;
|
724 |
+
}
|
725 |
+
|
726 |
+
// Validate the IPv6 network prefix
|
727 |
+
if ($prefix < 1 || $prefix > 128) {
|
728 |
+
return false;
|
729 |
+
}
|
730 |
+
}
|
731 |
+
|
732 |
+
$bin_network = substr(self::inet_pton($network), 0, ceil($prefix / 8));
|
733 |
+
$bin_ip = substr(self::inet_pton($ip), 0, ceil($prefix / 8));
|
734 |
+
if ($prefix % 8 != 0) { //Adjust the last relevant character to fit the mask length since the character's bits are split over it
|
735 |
+
$pos = intval($prefix / 8);
|
736 |
+
$adjustment = chr(((0xff << (8 - ($prefix % 8))) & 0xff));
|
737 |
+
$bin_network[$pos] = ($bin_network[$pos] & $adjustment);
|
738 |
+
$bin_ip[$pos] = ($bin_ip[$pos] & $adjustment);
|
739 |
+
}
|
740 |
+
|
741 |
+
return ($bin_network === $bin_ip);
|
742 |
+
}
|
743 |
}
|
vendor/wordfence/wf-waf/src/lib/waf.php
CHANGED
@@ -190,6 +190,7 @@ auEa+7b+FGTKs7dUo2BNGR7OVifK4GZ8w/ajS0TelhrSRi3BBQCGXLzUO/UURUAh
|
|
190 |
$this->blockAction($e);
|
191 |
|
192 |
} catch (wfWAFLogException $e) {
|
|
|
193 |
$this->logAction($e);
|
194 |
}
|
195 |
|
@@ -788,9 +789,22 @@ HTML
|
|
788 |
* @param wfWAFBlockException $e
|
789 |
* @param int $httpCode
|
790 |
*/
|
791 |
-
public function blockAction($e, $httpCode = 403) {
|
792 |
-
$this->getStorageEngine()->logAttack($e->getFailedRules(), $e->getParamKey(), $e->getParamValue(), $e->getRequest());
|
793 |
$this->getStorageEngine()->blockIP($this->getRequest()->getTimestamp(), $this->getRequest()->getIP());
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
794 |
header('HTTP/1.0 403 Forbidden');
|
795 |
exit($this->getBlockedMessage());
|
796 |
}
|
@@ -800,8 +814,21 @@ HTML
|
|
800 |
* @param wfWAFBlockXSSException $e
|
801 |
* @param int $httpCode
|
802 |
*/
|
803 |
-
public function blockXSSAction($e, $httpCode = 403) {
|
804 |
-
$this->getStorageEngine()->logAttack($e->getFailedRules(), $e->getParamKey(), $e->getParamValue(), $e->getRequest());
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
805 |
header('HTTP/1.0 403 Forbidden');
|
806 |
exit($this->getBlockedMessage());
|
807 |
}
|
@@ -823,6 +850,24 @@ HTML
|
|
823 |
'waf' => $this,
|
824 |
))->render();
|
825 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
826 |
|
827 |
/**
|
828 |
*
|
@@ -960,6 +1005,7 @@ HTML
|
|
960 |
'k' => $this->getStorageEngine()->getConfig('apiKey'),
|
961 |
's' => $this->getStorageEngine()->getConfig('siteURL') ? $this->getStorageEngine()->getConfig('siteURL') :
|
962 |
sprintf('%s://%s/', $this->getRequest()->getProtocol(), rawurlencode($this->getRequest()->getHost())),
|
|
|
963 |
), null, '&'), $this->getStorageEngine()->getAttackData(), $request);
|
964 |
|
965 |
if ($response instanceof wfWAFHTTPResponse && $response->getBody()) {
|
@@ -1083,6 +1129,33 @@ HTML
|
|
1083 |
$algo = function_exists('hash') ? 'sha256' : 'sha1';
|
1084 |
return wfWAFUtils::hash_hmac($algo, $userID . $role . floor(time() / 43200), $this->getStorageEngine()->getConfig('authKey'));
|
1085 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1086 |
|
1087 |
/**
|
1088 |
* @param string|null $host
|
@@ -1116,6 +1189,14 @@ HTML
|
|
1116 |
public function isIPBlocked($ip) {
|
1117 |
return $this->getStorageEngine()->isIPBlocked($ip);
|
1118 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1119 |
|
1120 |
/**
|
1121 |
* @return array
|
@@ -1455,7 +1536,8 @@ class wfWAFCronFetchIPListEvent extends wfWAFCronEvent {
|
|
1455 |
$response = wfWAFHTTP::post(WFWAF_API_URL_SEC . "?" . http_build_query(array(
|
1456 |
'action' => 'send_waf_attack_data',
|
1457 |
'k' => $waf->getStorageEngine()->getConfig('apiKey'),
|
1458 |
-
's'
|
|
|
1459 |
), null, '&'), '[]', $request);
|
1460 |
|
1461 |
if ($response instanceof wfWAFHTTPResponse && $response->getBody()) {
|
@@ -1541,6 +1623,13 @@ class wfWAFEventBus implements wfWAFObserver {
|
|
1541 |
$observer->blockSQLi($ip, $exception);
|
1542 |
}
|
1543 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1544 |
|
1545 |
|
1546 |
public function wafDisabled() {
|
@@ -1576,6 +1665,8 @@ interface wfWAFObserver {
|
|
1576 |
public function blockXSS($ip, $exception);
|
1577 |
|
1578 |
public function blockSQLi($ip, $exception);
|
|
|
|
|
1579 |
|
1580 |
public function wafDisabled();
|
1581 |
|
@@ -1604,6 +1695,10 @@ class wfWAFBaseObserver implements wfWAFObserver {
|
|
1604 |
|
1605 |
public function blockSQLi($ip, $exception) {
|
1606 |
|
|
|
|
|
|
|
|
|
1607 |
}
|
1608 |
|
1609 |
public function wafDisabled() {
|
190 |
$this->blockAction($e);
|
191 |
|
192 |
} catch (wfWAFLogException $e) {
|
193 |
+
$this->eventBus->log($ip, $e);
|
194 |
$this->logAction($e);
|
195 |
}
|
196 |
|
789 |
* @param wfWAFBlockException $e
|
790 |
* @param int $httpCode
|
791 |
*/
|
792 |
+
public function blockAction($e, $httpCode = 403, $redirect = false) {
|
793 |
+
$this->getStorageEngine()->logAttack($e->getFailedRules(), $e->getParamKey(), $e->getParamValue(), $e->getRequest(), $e->getRequest()->getMetadata());
|
794 |
$this->getStorageEngine()->blockIP($this->getRequest()->getTimestamp(), $this->getRequest()->getIP());
|
795 |
+
|
796 |
+
if ($redirect) {
|
797 |
+
wfWAFUtils::redirect($redirect); // exits
|
798 |
+
}
|
799 |
+
|
800 |
+
if ($httpCode == 503) {
|
801 |
+
wfWAFUtils::statusHeader(503);
|
802 |
+
if ($secsToGo = $e->getRequest()->getMetadata('503Time')) {
|
803 |
+
header('Retry-After: ' . $secsToGo);
|
804 |
+
}
|
805 |
+
exit($this->getUnavailableMessage($e->getRequest()->getMetadata('503Reason')));
|
806 |
+
}
|
807 |
+
|
808 |
header('HTTP/1.0 403 Forbidden');
|
809 |
exit($this->getBlockedMessage());
|
810 |
}
|
814 |
* @param wfWAFBlockXSSException $e
|
815 |
* @param int $httpCode
|
816 |
*/
|
817 |
+
public function blockXSSAction($e, $httpCode = 403, $redirect = false) {
|
818 |
+
$this->getStorageEngine()->logAttack($e->getFailedRules(), $e->getParamKey(), $e->getParamValue(), $e->getRequest(), $e->getRequest()->getMetadata());
|
819 |
+
|
820 |
+
if ($redirect) {
|
821 |
+
wfWAFUtils::redirect($redirect); // exits
|
822 |
+
}
|
823 |
+
|
824 |
+
if ($httpCode == 503) {
|
825 |
+
wfWAFUtils::statusHeader(503);
|
826 |
+
if ($secsToGo = $e->getRequest()->getMetadata('503Time')) {
|
827 |
+
header('Retry-After: ' . $secsToGo);
|
828 |
+
}
|
829 |
+
exit($this->getUnavailableMessage($e->getRequest()->getMetadata('503Reason')));
|
830 |
+
}
|
831 |
+
|
832 |
header('HTTP/1.0 403 Forbidden');
|
833 |
exit($this->getBlockedMessage());
|
834 |
}
|
850 |
'waf' => $this,
|
851 |
))->render();
|
852 |
}
|
853 |
+
|
854 |
+
/**
|
855 |
+
* @return string
|
856 |
+
*/
|
857 |
+
public function getUnavailableMessage($reason = '') {
|
858 |
+
try {
|
859 |
+
$homeURL = wfWAF::getInstance()->getStorageEngine()->getConfig('homeURL');
|
860 |
+
}
|
861 |
+
catch (Exception $e) {
|
862 |
+
//Do nothing
|
863 |
+
}
|
864 |
+
|
865 |
+
return wfWAFView::create('503', array(
|
866 |
+
'waf' => $this,
|
867 |
+
'reason' => $reason,
|
868 |
+
'homeURL' => $homeURL,
|
869 |
+
))->render();
|
870 |
+
}
|
871 |
|
872 |
/**
|
873 |
*
|
1005 |
'k' => $this->getStorageEngine()->getConfig('apiKey'),
|
1006 |
's' => $this->getStorageEngine()->getConfig('siteURL') ? $this->getStorageEngine()->getConfig('siteURL') :
|
1007 |
sprintf('%s://%s/', $this->getRequest()->getProtocol(), rawurlencode($this->getRequest()->getHost())),
|
1008 |
+
't' => microtime(true),
|
1009 |
), null, '&'), $this->getStorageEngine()->getAttackData(), $request);
|
1010 |
|
1011 |
if ($response instanceof wfWAFHTTPResponse && $response->getBody()) {
|
1129 |
$algo = function_exists('hash') ? 'sha256' : 'sha1';
|
1130 |
return wfWAFUtils::hash_hmac($algo, $userID . $role . floor(time() / 43200), $this->getStorageEngine()->getConfig('authKey'));
|
1131 |
}
|
1132 |
+
|
1133 |
+
/**
|
1134 |
+
* @param string $action
|
1135 |
+
* @return bool|string
|
1136 |
+
*/
|
1137 |
+
public function createNonce($action) {
|
1138 |
+
$userInfo = $this->parseAuthCookie();
|
1139 |
+
if ($userInfo === false) {
|
1140 |
+
$userInfo = array('userID' => 0, 'role' => ''); // Use an empty user like WordPress would
|
1141 |
+
}
|
1142 |
+
$userID = $userInfo['userID'];
|
1143 |
+
$role = $userInfo['role'];
|
1144 |
+
$algo = function_exists('hash') ? 'sha256' : 'sha1';
|
1145 |
+
return wfWAFUtils::hash_hmac($algo, $action . $userID . $role . floor(time() / 43200), $this->getStorageEngine()->getConfig('authKey'));
|
1146 |
+
}
|
1147 |
+
|
1148 |
+
/**
|
1149 |
+
* @param string $nonce
|
1150 |
+
* @param string $action
|
1151 |
+
* @return bool
|
1152 |
+
*/
|
1153 |
+
public function verifyNonce($nonce, $action) {
|
1154 |
+
if (empty($nonce)) {
|
1155 |
+
return false;
|
1156 |
+
}
|
1157 |
+
return wfWAFUtils::hash_equals($nonce, $this->createNonce($action));
|
1158 |
+
}
|
1159 |
|
1160 |
/**
|
1161 |
* @param string|null $host
|
1189 |
public function isIPBlocked($ip) {
|
1190 |
return $this->getStorageEngine()->isIPBlocked($ip);
|
1191 |
}
|
1192 |
+
|
1193 |
+
/**
|
1194 |
+
* @param wfWAFRequest $request
|
1195 |
+
* @return bool|array false if it should not be blocked, otherwise an array defining the context for the final action
|
1196 |
+
*/
|
1197 |
+
public function willPerformFinalAction($request) {
|
1198 |
+
return false;
|
1199 |
+
}
|
1200 |
|
1201 |
/**
|
1202 |
* @return array
|
1536 |
$response = wfWAFHTTP::post(WFWAF_API_URL_SEC . "?" . http_build_query(array(
|
1537 |
'action' => 'send_waf_attack_data',
|
1538 |
'k' => $waf->getStorageEngine()->getConfig('apiKey'),
|
1539 |
+
's' => $waf->getStorageEngine()->getConfig('siteURL') ? $waf->getStorageEngine()->getConfig('siteURL') : $guessSiteURL,
|
1540 |
+
't' => microtime(true),
|
1541 |
), null, '&'), '[]', $request);
|
1542 |
|
1543 |
if ($response instanceof wfWAFHTTPResponse && $response->getBody()) {
|
1623 |
$observer->blockSQLi($ip, $exception);
|
1624 |
}
|
1625 |
}
|
1626 |
+
|
1627 |
+
public function log($ip, $exception) {
|
1628 |
+
/** @var wfWAFObserver $observer */
|
1629 |
+
foreach ($this->observers as $observer) {
|
1630 |
+
$observer->log($ip, $exception);
|
1631 |
+
}
|
1632 |
+
}
|
1633 |
|
1634 |
|
1635 |
public function wafDisabled() {
|
1665 |
public function blockXSS($ip, $exception);
|
1666 |
|
1667 |
public function blockSQLi($ip, $exception);
|
1668 |
+
|
1669 |
+
public function log($ip, $exception);
|
1670 |
|
1671 |
public function wafDisabled();
|
1672 |
|
1695 |
|
1696 |
public function blockSQLi($ip, $exception) {
|
1697 |
|
1698 |
+
}
|
1699 |
+
|
1700 |
+
public function log($ip, $exception) {
|
1701 |
+
|
1702 |
}
|
1703 |
|
1704 |
public function wafDisabled() {
|
vendor/wordfence/wf-waf/src/views/503.php
ADDED
@@ -0,0 +1,35 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
|
2 |
+
<html><head>
|
3 |
+
<title>Your access to this site has been limited</title>
|
4 |
+
</head><body>
|
5 |
+
<h1>Your access to this site has been limited</h1>
|
6 |
+
<p>Your access to this service has been temporarily limited. Please try again in a few minutes. (HTTP response code 503)</p>
|
7 |
+
<p>Reason: <span style="color: #F00;"><?php echo $reason; ?></span></p>
|
8 |
+
<p style="width: 600px;"><b>Important note for site admins: </b>If you are the administrator of this website note that your access has been limited because you broke one of the Wordfence advanced blocking rules.
|
9 |
+
The reason your access was limited is: <b>"<?php echo $reason; ?>"</b>.
|
10 |
+
<br /><br />
|
11 |
+
If this is a false positive, meaning that your access to your own site has been limited incorrectly, then you
|
12 |
+
will need to regain access to your site, go to the Wordfence "options" page, go to the section for Rate Limiting Rules and disable the rule that caused you to be blocked. For example,
|
13 |
+
if you were blocked because it was detected that you are a fake Google crawler, then disable the rule that blocks fake google crawlers. Or if you were blocked because you
|
14 |
+
were accessing your site too quickly, then increase the number of accesses allowed per minute.
|
15 |
+
<br /><br />
|
16 |
+
If you're still having trouble, then simply disable the Wordfence advanced blocking and you will
|
17 |
+
still benefit from the other security features that Wordfence provides.
|
18 |
+
</p>
|
19 |
+
|
20 |
+
<?php
|
21 |
+
$nonce = $waf->createNonce('wf-form');
|
22 |
+
if (!empty($homeURL) && !empty($nonce)) : ?>
|
23 |
+
<br /><br />
|
24 |
+
|
25 |
+
If you are a site administrator and have been accidentally locked out, please enter your email in the box below and click "Send". If the email address you enter belongs to a known site administrator or someone set to receive Wordfence alerts, we will send you an email to help you regain access. <a href="https://docs.wordfence.com/en/Help!_I_locked_myself_out_and_can't_get_back_in._What_can_I_do%3F" target="_blank">Please read this FAQ entry if this does not work.</a>
|
26 |
+
<br /><br />
|
27 |
+
<form method="POST" action="<?php echo $homeURL; ?>?_wfsf=unlockEmail">
|
28 |
+
<input type="hidden" name="nonce" value="<?php echo $nonce; ?>" />
|
29 |
+
<input type="text" size="50" name="email" value="" maxlength="255" /> <input type="submit" name="s" value="Send me an unlock email" />
|
30 |
+
</form>
|
31 |
+
<?php endif; ?>
|
32 |
+
<br /><br />
|
33 |
+
|
34 |
+
<address>This response was generated by Wordfence.</address>
|
35 |
+
</body></html>
|
waf/bootstrap.php
CHANGED
@@ -9,10 +9,11 @@ if (!defined('WFWAF_AUTO_PREPEND')) {
|
|
9 |
}
|
10 |
|
11 |
require_once dirname(__FILE__) . '/wfWAFUserIPRange.php';
|
|
|
12 |
require_once dirname(__FILE__) . '/../vendor/wordfence/wf-waf/src/init.php';
|
13 |
|
14 |
class wfWAFWordPressRequest extends wfWAFRequest {
|
15 |
-
|
16 |
/**
|
17 |
* @param wfWAFRequest|null $request
|
18 |
* @return wfWAFRequest
|
@@ -76,6 +77,12 @@ class wfWAFWordPressObserver extends wfWAFBaseObserver {
|
|
76 |
}
|
77 |
}
|
78 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
79 |
}
|
80 |
|
81 |
public function afterRunRules()
|
@@ -93,6 +100,12 @@ class wfWAFWordPressObserver extends wfWAFBaseObserver {
|
|
93 |
}
|
94 |
}
|
95 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
96 |
}
|
97 |
}
|
98 |
|
@@ -108,15 +121,41 @@ class wfWAFWordPress extends wfWAF {
|
|
108 |
* @param wfWAFBlockException $e
|
109 |
* @param int $httpCode
|
110 |
*/
|
111 |
-
public function blockAction($e, $httpCode = 403) {
|
112 |
-
if ($this->isInLearningMode()) {
|
113 |
register_shutdown_function(array(
|
114 |
$this, 'whitelistFailedRulesIfNot404',
|
115 |
));
|
116 |
$this->getStorageEngine()->logAttack($e->getFailedRules(), $e->getParamKey(), $e->getParamValue(), $e->getRequest());
|
117 |
$this->setLearningModeAttackException($e);
|
118 |
} else {
|
119 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
120 |
}
|
121 |
}
|
122 |
|
@@ -124,15 +163,41 @@ class wfWAFWordPress extends wfWAF {
|
|
124 |
* @param wfWAFBlockXSSException $e
|
125 |
* @param int $httpCode
|
126 |
*/
|
127 |
-
public function blockXSSAction($e, $httpCode = 403) {
|
128 |
-
if ($this->isInLearningMode()) {
|
129 |
register_shutdown_function(array(
|
130 |
$this, 'whitelistFailedRulesIfNot404',
|
131 |
));
|
132 |
$this->getStorageEngine()->logAttack($e->getFailedRules(), $e->getParamKey(), $e->getParamValue(), $e->getRequest());
|
133 |
$this->setLearningModeAttackException($e);
|
134 |
} else {
|
135 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
136 |
}
|
137 |
}
|
138 |
|
@@ -185,6 +250,26 @@ class wfWAFWordPress extends wfWAF {
|
|
185 |
return false;
|
186 |
}
|
187 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
188 |
public function uninstall() {
|
189 |
parent::uninstall();
|
190 |
@unlink(rtrim(WFWAF_LOG_PATH . '/') . '/.htaccess');
|
9 |
}
|
10 |
|
11 |
require_once dirname(__FILE__) . '/wfWAFUserIPRange.php';
|
12 |
+
require_once dirname(__FILE__) . '/wfWAFIPBlocksController.php';
|
13 |
require_once dirname(__FILE__) . '/../vendor/wordfence/wf-waf/src/init.php';
|
14 |
|
15 |
class wfWAFWordPressRequest extends wfWAFRequest {
|
16 |
+
|
17 |
/**
|
18 |
* @param wfWAFRequest|null $request
|
19 |
* @return wfWAFRequest
|
77 |
}
|
78 |
}
|
79 |
}
|
80 |
+
|
81 |
+
// Check plugin blocking
|
82 |
+
if ($result = wfWAF::getInstance()->willPerformFinalAction(wfWAF::getInstance()->getRequest())) {
|
83 |
+
if ($result === true) { $result = 'Not available'; } // Should not happen but can if the reason in the blocks table is empty
|
84 |
+
wfWAF::getInstance()->getRequest()->setMetadata(array_merge(wfWAF::getInstance()->getRequest()->getMetadata(), array('finalAction' => $result)));
|
85 |
+
}
|
86 |
}
|
87 |
|
88 |
public function afterRunRules()
|
100 |
}
|
101 |
}
|
102 |
}
|
103 |
+
|
104 |
+
if ($reason = wfWAF::getInstance()->getRequest()->getMetadata('finalAction')) {
|
105 |
+
$e = new wfWAFBlockException($reason['action']);
|
106 |
+
$e->setRequest(wfWAF::getInstance()->getRequest());
|
107 |
+
throw $e;
|
108 |
+
}
|
109 |
}
|
110 |
}
|
111 |
|
121 |
* @param wfWAFBlockException $e
|
122 |
* @param int $httpCode
|
123 |
*/
|
124 |
+
public function blockAction($e, $httpCode = 403, $redirect = false) {
|
125 |
+
if ($this->isInLearningMode() && !$e->getRequest()->getMetadata('finalAction')) {
|
126 |
register_shutdown_function(array(
|
127 |
$this, 'whitelistFailedRulesIfNot404',
|
128 |
));
|
129 |
$this->getStorageEngine()->logAttack($e->getFailedRules(), $e->getParamKey(), $e->getParamValue(), $e->getRequest());
|
130 |
$this->setLearningModeAttackException($e);
|
131 |
} else {
|
132 |
+
$failedRules = $e->getFailedRules();
|
133 |
+
if (empty($failedRules)) {
|
134 |
+
$finalAction = $e->getRequest()->getMetadata('finalAction');
|
135 |
+
if (is_array($finalAction)) {
|
136 |
+
$finalAction = $finalAction['action'];
|
137 |
+
if ($finalAction == wfWAFIPBlocksController::WFWAF_BLOCK_COUNTRY_REDIR) {
|
138 |
+
$redirect = wfWAFIPBlocksController::currentController()->countryRedirURL();
|
139 |
+
}
|
140 |
+
else if ($finalAction == wfWAFIPBlocksController::WFWAF_BLOCK_COUNTRY_BYPASS_REDIR) {
|
141 |
+
$redirect = wfWAFIPBlocksController::currentController()->countryBypassRedirURL();
|
142 |
+
}
|
143 |
+
else if ($finalAction == wfWAFIPBlocksController::WFWAF_BLOCK_UAREFIPRANGE) {
|
144 |
+
wfWAF::getInstance()->getRequest()->setMetadata(array_merge(wfWAF::getInstance()->getRequest()->getMetadata(), array('503Reason' => 'Advanced blocking in effect.', '503Time' => 3600)));
|
145 |
+
$httpCode = 503;
|
146 |
+
}
|
147 |
+
else if ($finalAction == wfWAFIPBlocksController::WFWAF_BLOCK_COUNTRY) {
|
148 |
+
wfWAF::getInstance()->getRequest()->setMetadata(array_merge(wfWAF::getInstance()->getRequest()->getMetadata(), array('503Reason' => 'Access from your area has been temporarily limited for security reasons.', '503Time' => 3600)));
|
149 |
+
$httpCode = 503;
|
150 |
+
}
|
151 |
+
else if (is_string($finalAction) && strlen($finalAction) > 0) {
|
152 |
+
wfWAF::getInstance()->getRequest()->setMetadata(array_merge(wfWAF::getInstance()->getRequest()->getMetadata(), array('503Reason' => $finalAction, '503Time' => 3600)));
|
153 |
+
$httpCode = 503;
|
154 |
+
}
|
155 |
+
}
|
156 |
+
}
|
157 |
+
|
158 |
+
parent::blockAction($e, $httpCode, $redirect);
|
159 |
}
|
160 |
}
|
161 |
|
163 |
* @param wfWAFBlockXSSException $e
|
164 |
* @param int $httpCode
|
165 |
*/
|
166 |
+
public function blockXSSAction($e, $httpCode = 403, $redirect = false) {
|
167 |
+
if ($this->isInLearningMode() && !$e->getRequest()->getMetadata('finalAction')) {
|
168 |
register_shutdown_function(array(
|
169 |
$this, 'whitelistFailedRulesIfNot404',
|
170 |
));
|
171 |
$this->getStorageEngine()->logAttack($e->getFailedRules(), $e->getParamKey(), $e->getParamValue(), $e->getRequest());
|
172 |
$this->setLearningModeAttackException($e);
|
173 |
} else {
|
174 |
+
$failedRules = $e->getFailedRules();
|
175 |
+
if (empty($failedRules)) {
|
176 |
+
$finalAction = $e->getRequest()->getMetadata('finalAction');
|
177 |
+
if (is_array($finalAction)) {
|
178 |
+
$finalAction = $finalAction['action'];
|
179 |
+
if ($finalAction == wfWAFIPBlocksController::WFWAF_BLOCK_COUNTRY_REDIR) {
|
180 |
+
$redirect = wfWAFIPBlocksController::currentController()->countryRedirURL();
|
181 |
+
}
|
182 |
+
else if ($finalAction == wfWAFIPBlocksController::WFWAF_BLOCK_COUNTRY_BYPASS_REDIR) {
|
183 |
+
$redirect = wfWAFIPBlocksController::currentController()->countryBypassRedirURL();
|
184 |
+
}
|
185 |
+
else if ($finalAction == wfWAFIPBlocksController::WFWAF_BLOCK_UAREFIPRANGE) {
|
186 |
+
wfWAF::getInstance()->getRequest()->setMetadata(array_merge(wfWAF::getInstance()->getRequest()->getMetadata(), array('503Reason' => 'Advanced blocking in effect.', '503Time' => 3600)));
|
187 |
+
$httpCode = 503;
|
188 |
+
}
|
189 |
+
else if ($finalAction == wfWAFIPBlocksController::WFWAF_BLOCK_COUNTRY) {
|
190 |
+
wfWAF::getInstance()->getRequest()->setMetadata(array_merge(wfWAF::getInstance()->getRequest()->getMetadata(), array('503Reason' => 'Access from your area has been temporarily limited for security reasons.', '503Time' => 3600)));
|
191 |
+
$httpCode = 503;
|
192 |
+
}
|
193 |
+
else if (is_string($finalAction) && strlen($finalAction) > 0) {
|
194 |
+
wfWAF::getInstance()->getRequest()->setMetadata(array_merge(wfWAF::getInstance()->getRequest()->getMetadata(), array('503Reason' => $finalAction, '503Time' => 3600)));
|
195 |
+
$httpCode = 503;
|
196 |
+
}
|
197 |
+
}
|
198 |
+
}
|
199 |
+
|
200 |
+
parent::blockXSSAction($e, $httpCode, $redirect);
|
201 |
}
|
202 |
}
|
203 |
|
250 |
return false;
|
251 |
}
|
252 |
|
253 |
+
/**
|
254 |
+
* @param wfWAFRequest $request
|
255 |
+
* @return bool|string false if it should not be blocked, otherwise true or a reason for blocking
|
256 |
+
*/
|
257 |
+
public function willPerformFinalAction($request) {
|
258 |
+
try {
|
259 |
+
$disableWAFIPBlocking = $this->getStorageEngine()->getConfig('disableWAFIPBlocking');
|
260 |
+
$advancedBlockingEnabled = $this->getStorageEngine()->getConfig('advancedBlockingEnabled');
|
261 |
+
}
|
262 |
+
catch (Exception $e) {
|
263 |
+
return false;
|
264 |
+
}
|
265 |
+
|
266 |
+
if ($disableWAFIPBlocking || !$advancedBlockingEnabled) {
|
267 |
+
return false;
|
268 |
+
}
|
269 |
+
|
270 |
+
return wfWAFIPBlocksController::currentController()->shouldBlockRequest($request);
|
271 |
+
}
|
272 |
+
|
273 |
public function uninstall() {
|
274 |
parent::uninstall();
|
275 |
@unlink(rtrim(WFWAF_LOG_PATH . '/') . '/.htaccess');
|
waf/wfWAFGeoIP.php
ADDED
@@ -0,0 +1,765 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 2; tab-width: 2 -*- */
|
4 |
+
/* geoip.inc
|
5 |
+
*
|
6 |
+
* Copyright (C) 2007 MaxMind LLC
|
7 |
+
*
|
8 |
+
* This library is free software; you can redistribute it and/or
|
9 |
+
* modify it under the terms of the GNU Lesser General Public
|
10 |
+
* License as published by the Free Software Foundation; either
|
11 |
+
* version 2.1 of the License, or (at your option) any later version.
|
12 |
+
*
|
13 |
+
* This library is distributed in the hope that it will be useful,
|
14 |
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
15 |
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
16 |
+
* Lesser General Public License for more details.
|
17 |
+
*
|
18 |
+
* You should have received a copy of the GNU Lesser General Public
|
19 |
+
* License along with this library; if not, write to the Free Software
|
20 |
+
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
21 |
+
*/
|
22 |
+
if(! class_exists('wfWAFGeoIP')){
|
23 |
+
define("GEOIP_COUNTRY_BEGIN", 16776960);
|
24 |
+
define("GEOIP_STATE_BEGIN_REV0", 16700000);
|
25 |
+
define("GEOIP_STATE_BEGIN_REV1", 16000000);
|
26 |
+
define("GEOIP_STANDARD", 0);
|
27 |
+
define("GEOIP_MEMORY_CACHE", 1);
|
28 |
+
define("GEOIP_SHARED_MEMORY", 2);
|
29 |
+
define("STRUCTURE_INFO_MAX_SIZE", 20);
|
30 |
+
define("DATABASE_INFO_MAX_SIZE", 100);
|
31 |
+
define("GEOIP_COUNTRY_EDITION", 106);
|
32 |
+
define("GEOIP_PROXY_EDITION", 8);
|
33 |
+
define("GEOIP_ASNUM_EDITION", 9);
|
34 |
+
define("GEOIP_NETSPEED_EDITION", 10);
|
35 |
+
define("GEOIP_REGION_EDITION_REV0", 112);
|
36 |
+
define("GEOIP_REGION_EDITION_REV1", 3);
|
37 |
+
define("GEOIP_CITY_EDITION_REV0", 111);
|
38 |
+
define("GEOIP_CITY_EDITION_REV1", 2);
|
39 |
+
define("GEOIP_ORG_EDITION", 110);
|
40 |
+
define("GEOIP_ISP_EDITION", 4);
|
41 |
+
define("SEGMENT_RECORD_LENGTH", 3);
|
42 |
+
define("STANDARD_RECORD_LENGTH", 3);
|
43 |
+
define("ORG_RECORD_LENGTH", 4);
|
44 |
+
define("MAX_RECORD_LENGTH", 4);
|
45 |
+
define("MAX_ORG_RECORD_LENGTH", 300);
|
46 |
+
define("GEOIP_SHM_KEY", 0x4f415401);
|
47 |
+
define("US_OFFSET", 1);
|
48 |
+
define("CANADA_OFFSET", 677);
|
49 |
+
define("WORLD_OFFSET", 1353);
|
50 |
+
define("FIPS_RANGE", 360);
|
51 |
+
define("GEOIP_UNKNOWN_SPEED", 0);
|
52 |
+
define("GEOIP_DIALUP_SPEED", 1);
|
53 |
+
define("GEOIP_CABLEDSL_SPEED", 2);
|
54 |
+
define("GEOIP_CORPORATE_SPEED", 3);
|
55 |
+
define("GEOIP_DOMAIN_EDITION", 11);
|
56 |
+
define("GEOIP_COUNTRY_EDITION_V6", 12);
|
57 |
+
define("GEOIP_LOCATIONA_EDITION", 13);
|
58 |
+
define("GEOIP_ACCURACYRADIUS_EDITION", 14);
|
59 |
+
define("GEOIP_CITYCOMBINED_EDITION", 15);
|
60 |
+
define("GEOIP_CITY_EDITION_REV1_V6", 30);
|
61 |
+
define("GEOIP_CITY_EDITION_REV0_V6",31);
|
62 |
+
define("GEOIP_NETSPEED_EDITION_REV1",32);
|
63 |
+
define("GEOIP_NETSPEED_EDITION_REV1_V6",33);
|
64 |
+
define("GEOIP_USERTYPE_EDITION",28);
|
65 |
+
define("GEOIP_USERTYPE_EDITION_V6",29);
|
66 |
+
define("GEOIP_ASNUM_EDITION_V6",21);
|
67 |
+
define("GEOIP_ISP_EDITION_V6",22);
|
68 |
+
define("GEOIP_ORG_EDITION_V6",23);
|
69 |
+
define("GEOIP_DOMAIN_EDITION_V6",24);
|
70 |
+
|
71 |
+
define("CITYCOMBINED_FIXED_RECORD", 7 );
|
72 |
+
|
73 |
+
class wfWAFGeoIP {
|
74 |
+
var $flags;
|
75 |
+
var $filehandle;
|
76 |
+
var $memory_buffer;
|
77 |
+
var $databaseType;
|
78 |
+
var $databaseSegments;
|
79 |
+
var $record_length;
|
80 |
+
var $shmid;
|
81 |
+
var $GEOIP_COUNTRY_CODE_TO_NUMBER = array(
|
82 |
+
"" => 0, "AP" => 1, "EU" => 2, "AD" => 3, "AE" => 4, "AF" => 5,
|
83 |
+
"AG" => 6, "AI" => 7, "AL" => 8, "AM" => 9, "CW" => 10, "AO" => 11,
|
84 |
+
"AQ" => 12, "AR" => 13, "AS" => 14, "AT" => 15, "AU" => 16, "AW" => 17,
|
85 |
+
"AZ" => 18, "BA" => 19, "BB" => 20, "BD" => 21, "BE" => 22, "BF" => 23,
|
86 |
+
"BG" => 24, "BH" => 25, "BI" => 26, "BJ" => 27, "BM" => 28, "BN" => 29,
|
87 |
+
"BO" => 30, "BR" => 31, "BS" => 32, "BT" => 33, "BV" => 34, "BW" => 35,
|
88 |
+
"BY" => 36, "BZ" => 37, "CA" => 38, "CC" => 39, "CD" => 40, "CF" => 41,
|
89 |
+
"CG" => 42, "CH" => 43, "CI" => 44, "CK" => 45, "CL" => 46, "CM" => 47,
|
90 |
+
"CN" => 48, "CO" => 49, "CR" => 50, "CU" => 51, "CV" => 52, "CX" => 53,
|
91 |
+
"CY" => 54, "CZ" => 55, "DE" => 56, "DJ" => 57, "DK" => 58, "DM" => 59,
|
92 |
+
"DO" => 60, "DZ" => 61, "EC" => 62, "EE" => 63, "EG" => 64, "EH" => 65,
|
93 |
+
"ER" => 66, "ES" => 67, "ET" => 68, "FI" => 69, "FJ" => 70, "FK" => 71,
|
94 |
+
"FM" => 72, "FO" => 73, "FR" => 74, "SX" => 75, "GA" => 76, "GB" => 77,
|
95 |
+
"GD" => 78, "GE" => 79, "GF" => 80, "GH" => 81, "GI" => 82, "GL" => 83,
|
96 |
+
"GM" => 84, "GN" => 85, "GP" => 86, "GQ" => 87, "GR" => 88, "GS" => 89,
|
97 |
+
"GT" => 90, "GU" => 91, "GW" => 92, "GY" => 93, "HK" => 94, "HM" => 95,
|
98 |
+
"HN" => 96, "HR" => 97, "HT" => 98, "HU" => 99, "ID" => 100, "IE" => 101,
|
99 |
+
"IL" => 102, "IN" => 103, "IO" => 104, "IQ" => 105, "IR" => 106, "IS" => 107,
|
100 |
+
"IT" => 108, "JM" => 109, "JO" => 110, "JP" => 111, "KE" => 112, "KG" => 113,
|
101 |
+
"KH" => 114, "KI" => 115, "KM" => 116, "KN" => 117, "KP" => 118, "KR" => 119,
|
102 |
+
"KW" => 120, "KY" => 121, "KZ" => 122, "LA" => 123, "LB" => 124, "LC" => 125,
|
103 |
+
"LI" => 126, "LK" => 127, "LR" => 128, "LS" => 129, "LT" => 130, "LU" => 131,
|
104 |
+
"LV" => 132, "LY" => 133, "MA" => 134, "MC" => 135, "MD" => 136, "MG" => 137,
|
105 |
+
"MH" => 138, "MK" => 139, "ML" => 140, "MM" => 141, "MN" => 142, "MO" => 143,
|
106 |
+
"MP" => 144, "MQ" => 145, "MR" => 146, "MS" => 147, "MT" => 148, "MU" => 149,
|
107 |
+
"MV" => 150, "MW" => 151, "MX" => 152, "MY" => 153, "MZ" => 154, "NA" => 155,
|
108 |
+
"NC" => 156, "NE" => 157, "NF" => 158, "NG" => 159, "NI" => 160, "NL" => 161,
|
109 |
+
"NO" => 162, "NP" => 163, "NR" => 164, "NU" => 165, "NZ" => 166, "OM" => 167,
|
110 |
+
"PA" => 168, "PE" => 169, "PF" => 170, "PG" => 171, "PH" => 172, "PK" => 173,
|
111 |
+
"PL" => 174, "PM" => 175, "PN" => 176, "PR" => 177, "PS" => 178, "PT" => 179,
|
112 |
+
"PW" => 180, "PY" => 181, "QA" => 182, "RE" => 183, "RO" => 184, "RU" => 185,
|
113 |
+
"RW" => 186, "SA" => 187, "SB" => 188, "SC" => 189, "SD" => 190, "SE" => 191,
|
114 |
+
"SG" => 192, "SH" => 193, "SI" => 194, "SJ" => 195, "SK" => 196, "SL" => 197,
|
115 |
+
"SM" => 198, "SN" => 199, "SO" => 200, "SR" => 201, "ST" => 202, "SV" => 203,
|
116 |
+
"SY" => 204, "SZ" => 205, "TC" => 206, "TD" => 207, "TF" => 208, "TG" => 209,
|
117 |
+
"TH" => 210, "TJ" => 211, "TK" => 212, "TM" => 213, "TN" => 214, "TO" => 215,
|
118 |
+
"TL" => 216, "TR" => 217, "TT" => 218, "TV" => 219, "TW" => 220, "TZ" => 221,
|
119 |
+
"UA" => 222, "UG" => 223, "UM" => 224, "US" => 225, "UY" => 226, "UZ" => 227,
|
120 |
+
"VA" => 228, "VC" => 229, "VE" => 230, "VG" => 231, "VI" => 232, "VN" => 233,
|
121 |
+
"VU" => 234, "WF" => 235, "WS" => 236, "YE" => 237, "YT" => 238, "RS" => 239,
|
122 |
+
"ZA" => 240, "ZM" => 241, "ME" => 242, "ZW" => 243, "A1" => 244, "A2" => 245,
|
123 |
+
"O1" => 246, "AX" => 247, "GG" => 248, "IM" => 249, "JE" => 250, "BL" => 251,
|
124 |
+
"MF" => 252, "BQ" => 253,
|
125 |
+
);
|
126 |
+
var $GEOIP_COUNTRY_CODES = array(
|
127 |
+
"","AP","EU","AD","AE","AF","AG","AI","AL","AM","CW",
|
128 |
+
"AO","AQ","AR","AS","AT","AU","AW","AZ","BA","BB",
|
129 |
+
"BD","BE","BF","BG","BH","BI","BJ","BM","BN","BO",
|
130 |
+
"BR","BS","BT","BV","BW","BY","BZ","CA","CC","CD",
|
131 |
+
"CF","CG","CH","CI","CK","CL","CM","CN","CO","CR",
|
132 |
+
"CU","CV","CX","CY","CZ","DE","DJ","DK","DM","DO",
|
133 |
+
"DZ","EC","EE","EG","EH","ER","ES","ET","FI","FJ",
|
134 |
+
"FK","FM","FO","FR","SX","GA","GB","GD","GE","GF",
|
135 |
+
"GH","GI","GL","GM","GN","GP","GQ","GR","GS","GT",
|
136 |
+
"GU","GW","GY","HK","HM","HN","HR","HT","HU","ID",
|
137 |
+
"IE","IL","IN","IO","IQ","IR","IS","IT","JM","JO",
|
138 |
+
"JP","KE","KG","KH","KI","KM","KN","KP","KR","KW",
|
139 |
+
"KY","KZ","LA","LB","LC","LI","LK","LR","LS","LT",
|
140 |
+
"LU","LV","LY","MA","MC","MD","MG","MH","MK","ML",
|
141 |
+
"MM","MN","MO","MP","MQ","MR","MS","MT","MU","MV",
|
142 |
+
"MW","MX","MY","MZ","NA","NC","NE","NF","NG","NI",
|
143 |
+
"NL","NO","NP","NR","NU","NZ","OM","PA","PE","PF",
|
144 |
+
"PG","PH","PK","PL","PM","PN","PR","PS","PT","PW",
|
145 |
+
"PY","QA","RE","RO","RU","RW","SA","SB","SC","SD",
|
146 |
+
"SE","SG","SH","SI","SJ","SK","SL","SM","SN","SO",
|
147 |
+
"SR","ST","SV","SY","SZ","TC","TD","TF","TG","TH",
|
148 |
+
"TJ","TK","TM","TN","TO","TL","TR","TT","TV","TW",
|
149 |
+
"TZ","UA","UG","UM","US","UY","UZ","VA","VC","VE",
|
150 |
+
"VG","VI","VN","VU","WF","WS","YE","YT","RS","ZA",
|
151 |
+
"ZM","ME","ZW","A1","A2","O1","AX","GG","IM","JE",
|
152 |
+
"BL","MF", "BQ");
|
153 |
+
var $GEOIP_COUNTRY_CODES3 = array(
|
154 |
+
"","AP","EU","AND","ARE","AFG","ATG","AIA","ALB","ARM","CUW",
|
155 |
+
"AGO","ATA","ARG","ASM","AUT","AUS","ABW","AZE","BIH","BRB",
|
156 |
+
"BGD","BEL","BFA","BGR","BHR","BDI","BEN","BMU","BRN","BOL",
|
157 |
+
"BRA","BHS","BTN","BVT","BWA","BLR","BLZ","CAN","CCK","COD",
|
158 |
+
"CAF","COG","CHE","CIV","COK","CHL","CMR","CHN","COL","CRI",
|
159 |
+
"CUB","CPV","CXR","CYP","CZE","DEU","DJI","DNK","DMA","DOM",
|
160 |
+
"DZA","ECU","EST","EGY","ESH","ERI","ESP","ETH","FIN","FJI",
|
161 |
+
"FLK","FSM","FRO","FRA","SXM","GAB","GBR","GRD","GEO","GUF",
|
162 |
+
"GHA","GIB","GRL","GMB","GIN","GLP","GNQ","GRC","SGS","GTM",
|
163 |
+
"GUM","GNB","GUY","HKG","HMD","HND","HRV","HTI","HUN","IDN",
|
164 |
+
"IRL","ISR","IND","IOT","IRQ","IRN","ISL","ITA","JAM","JOR",
|
165 |
+
"JPN","KEN","KGZ","KHM","KIR","COM","KNA","PRK","KOR","KWT",
|
166 |
+
"CYM","KAZ","LAO","LBN","LCA","LIE","LKA","LBR","LSO","LTU",
|
167 |
+
"LUX","LVA","LBY","MAR","MCO","MDA","MDG","MHL","MKD","MLI",
|
168 |
+
"MMR","MNG","MAC","MNP","MTQ","MRT","MSR","MLT","MUS","MDV",
|
169 |
+
"MWI","MEX","MYS","MOZ","NAM","NCL","NER","NFK","NGA","NIC",
|
170 |
+
"NLD","NOR","NPL","NRU","NIU","NZL","OMN","PAN","PER","PYF",
|
171 |
+
"PNG","PHL","PAK","POL","SPM","PCN","PRI","PSE","PRT","PLW",
|
172 |
+
"PRY","QAT","REU","ROU","RUS","RWA","SAU","SLB","SYC","SDN",
|
173 |
+
"SWE","SGP","SHN","SVN","SJM","SVK","SLE","SMR","SEN","SOM",
|
174 |
+
"SUR","STP","SLV","SYR","SWZ","TCA","TCD","ATF","TGO","THA",
|
175 |
+
"TJK","TKL","TKM","TUN","TON","TLS","TUR","TTO","TUV","TWN",
|
176 |
+
"TZA","UKR","UGA","UMI","USA","URY","UZB","VAT","VCT","VEN",
|
177 |
+
"VGB","VIR","VNM","VUT","WLF","WSM","YEM","MYT","SRB","ZAF",
|
178 |
+
"ZMB","MNE","ZWE","A1","A2","O1","ALA","GGY","IMN","JEY",
|
179 |
+
"BLM","MAF", "BES"
|
180 |
+
);
|
181 |
+
var $GEOIP_COUNTRY_NAMES = array(
|
182 |
+
"","Asia/Pacific Region","Europe","Andorra","United Arab Emirates","Afghanistan","Antigua and Barbuda","Anguilla","Albania","Armenia","Curacao",
|
183 |
+
"Angola","Antarctica","Argentina","American Samoa","Austria","Australia","Aruba","Azerbaijan","Bosnia and Herzegovina","Barbados",
|
184 |
+
"Bangladesh","Belgium","Burkina Faso","Bulgaria","Bahrain","Burundi","Benin","Bermuda","Brunei Darussalam","Bolivia",
|
185 |
+
"Brazil","Bahamas","Bhutan","Bouvet Island","Botswana","Belarus","Belize","Canada","Cocos (Keeling) Islands","Congo, The Democratic Republic of the",
|
186 |
+
"Central African Republic","Congo","Switzerland","Cote D'Ivoire","Cook Islands","Chile","Cameroon","China","Colombia","Costa Rica",
|
187 |
+
"Cuba","Cape Verde","Christmas Island","Cyprus","Czech Republic","Germany","Djibouti","Denmark","Dominica","Dominican Republic",
|
188 |
+
"Algeria","Ecuador","Estonia","Egypt","Western Sahara","Eritrea","Spain","Ethiopia","Finland","Fiji",
|
189 |
+
"Falkland Islands (Malvinas)","Micronesia, Federated States of","Faroe Islands","France","Sint Maarten (Dutch part)","Gabon","United Kingdom","Grenada","Georgia","French Guiana",
|
190 |
+
"Ghana","Gibraltar","Greenland","Gambia","Guinea","Guadeloupe","Equatorial Guinea","Greece","South Georgia and the South Sandwich Islands","Guatemala",
|
191 |
+
"Guam","Guinea-Bissau","Guyana","Hong Kong","Heard Island and McDonald Islands","Honduras","Croatia","Haiti","Hungary","Indonesia",
|
192 |
+
"Ireland","Israel","India","British Indian Ocean Territory","Iraq","Iran, Islamic Republic of","Iceland","Italy","Jamaica","Jordan",
|
193 |
+
"Japan","Kenya","Kyrgyzstan","Cambodia","Kiribati","Comoros","Saint Kitts and Nevis","Korea, Democratic People's Republic of","Korea, Republic of","Kuwait",
|
194 |
+
"Cayman Islands","Kazakhstan","Lao People's Democratic Republic","Lebanon","Saint Lucia","Liechtenstein","Sri Lanka","Liberia","Lesotho","Lithuania",
|
195 |
+
"Luxembourg","Latvia","Libya","Morocco","Monaco","Moldova, Republic of","Madagascar","Marshall Islands","Macedonia","Mali",
|
196 |
+
"Myanmar","Mongolia","Macau","Northern Mariana Islands","Martinique","Mauritania","Montserrat","Malta","Mauritius","Maldives",
|
197 |
+
"Malawi","Mexico","Malaysia","Mozambique","Namibia","New Caledonia","Niger","Norfolk Island","Nigeria","Nicaragua",
|
198 |
+
"Netherlands","Norway","Nepal","Nauru","Niue","New Zealand","Oman","Panama","Peru","French Polynesia",
|
199 |
+
"Papua New Guinea","Philippines","Pakistan","Poland","Saint Pierre and Miquelon","Pitcairn Islands","Puerto Rico","Palestinian Territory","Portugal","Palau",
|
200 |
+
"Paraguay","Qatar","Reunion","Romania","Russian Federation","Rwanda","Saudi Arabia","Solomon Islands","Seychelles","Sudan",
|
201 |
+
"Sweden","Singapore","Saint Helena","Slovenia","Svalbard and Jan Mayen","Slovakia","Sierra Leone","San Marino","Senegal","Somalia","Suriname",
|
202 |
+
"Sao Tome and Principe","El Salvador","Syrian Arab Republic","Swaziland","Turks and Caicos Islands","Chad","French Southern Territories","Togo","Thailand",
|
203 |
+
"Tajikistan","Tokelau","Turkmenistan","Tunisia","Tonga","Timor-Leste","Turkey","Trinidad and Tobago","Tuvalu","Taiwan",
|
204 |
+
"Tanzania, United Republic of","Ukraine","Uganda","United States Minor Outlying Islands","United States","Uruguay","Uzbekistan","Holy See (Vatican City State)","Saint Vincent and the Grenadines","Venezuela",
|
205 |
+
"Virgin Islands, British","Virgin Islands, U.S.","Vietnam","Vanuatu","Wallis and Futuna","Samoa","Yemen","Mayotte","Serbia","South Africa",
|
206 |
+
"Zambia","Montenegro","Zimbabwe","Anonymous Proxy","Satellite Provider","Other","Aland Islands","Guernsey","Isle of Man","Jersey",
|
207 |
+
"Saint Barthelemy","Saint Martin", "Bonaire, Saint Eustatius and Saba"
|
208 |
+
);
|
209 |
+
|
210 |
+
var $GEOIP_CONTINENT_CODES = array(
|
211 |
+
"--", "AS","EU","EU","AS","AS","NA","NA","EU","AS","NA",
|
212 |
+
"AF","AN","SA","OC","EU","OC","NA","AS","EU","NA",
|
213 |
+
"AS","EU","AF","EU","AS","AF","AF","NA","AS","SA",
|
214 |
+
"SA","NA","AS","AN","AF","EU","NA","NA","AS","AF",
|
215 |
+
"AF","AF","EU","AF","OC","SA","AF","AS","SA","NA",
|
216 |
+
"NA","AF","AS","AS","EU","EU","AF","EU","NA","NA",
|
217 |
+
"AF","SA","EU","AF","AF","AF","EU","AF","EU","OC",
|
218 |
+
"SA","OC","EU","EU","NA","AF","EU","NA","AS","SA",
|
219 |
+
"AF","EU","NA","AF","AF","NA","AF","EU","AN","NA",
|
220 |
+
"OC","AF","SA","AS","AN","NA","EU","NA","EU","AS",
|
221 |
+
"EU","AS","AS","AS","AS","AS","EU","EU","NA","AS",
|
222 |
+
"AS","AF","AS","AS","OC","AF","NA","AS","AS","AS",
|
223 |
+
"NA","AS","AS","AS","NA","EU","AS","AF","AF","EU",
|
224 |
+
"EU","EU","AF","AF","EU","EU","AF","OC","EU","AF",
|
225 |
+
"AS","AS","AS","OC","NA","AF","NA","EU","AF","AS",
|
226 |
+
"AF","NA","AS","AF","AF","OC","AF","OC","AF","NA",
|
227 |
+
"EU","EU","AS","OC","OC","OC","AS","NA","SA","OC",
|
228 |
+
"OC","AS","AS","EU","NA","OC","NA","AS","EU","OC",
|
229 |
+
"SA","AS","AF","EU","EU","AF","AS","OC","AF","AF",
|
230 |
+
"EU","AS","AF","EU","EU","EU","AF","EU","AF","AF",
|
231 |
+
"SA","AF","NA","AS","AF","NA","AF","AN","AF","AS",
|
232 |
+
"AS","OC","AS","AF","OC","AS","EU","NA","OC","AS",
|
233 |
+
"AF","EU","AF","OC","NA","SA","AS","EU","NA","SA",
|
234 |
+
"NA","NA","AS","OC","OC","OC","AS","AF","EU","AF",
|
235 |
+
"AF","EU","AF","--","--","--","EU","EU","EU","EU",
|
236 |
+
"NA","NA","NA"
|
237 |
+
);
|
238 |
+
|
239 |
+
}
|
240 |
+
if(! function_exists('geoip_load_shared_mem')){
|
241 |
+
function geoip_load_shared_mem ($file) {
|
242 |
+
|
243 |
+
$fp = fopen($file, "rb");
|
244 |
+
if (!$fp) {
|
245 |
+
print "error opening $file: $php_errormsg\n";
|
246 |
+
exit;
|
247 |
+
}
|
248 |
+
$s_array = fstat($fp);
|
249 |
+
$size = $s_array['size'];
|
250 |
+
if ($shmid = @shmop_open (GEOIP_SHM_KEY, "w", 0, 0)) {
|
251 |
+
shmop_delete ($shmid);
|
252 |
+
shmop_close ($shmid);
|
253 |
+
}
|
254 |
+
$shmid = shmop_open (GEOIP_SHM_KEY, "c", 0644, $size);
|
255 |
+
shmop_write ($shmid, fread($fp, $size), 0);
|
256 |
+
shmop_close ($shmid);
|
257 |
+
}
|
258 |
+
}
|
259 |
+
|
260 |
+
if(! function_exists('')){
|
261 |
+
function _setup_segments($gi){
|
262 |
+
$gi->databaseType = GEOIP_COUNTRY_EDITION;
|
263 |
+
$gi->record_length = STANDARD_RECORD_LENGTH;
|
264 |
+
if ($gi->flags & GEOIP_SHARED_MEMORY) {
|
265 |
+
$offset = @shmop_size ($gi->shmid) - 3;
|
266 |
+
for ($i = 0; $i < STRUCTURE_INFO_MAX_SIZE; $i++) {
|
267 |
+
$delim = @shmop_read ($gi->shmid, $offset, 3);
|
268 |
+
$offset += 3;
|
269 |
+
if ($delim == (chr(255).chr(255).chr(255))) {
|
270 |
+
$gi->databaseType = ord(@shmop_read ($gi->shmid, $offset, 1));
|
271 |
+
$offset++;
|
272 |
+
|
273 |
+
if ($gi->databaseType == GEOIP_REGION_EDITION_REV0){
|
274 |
+
$gi->databaseSegments = GEOIP_STATE_BEGIN_REV0;
|
275 |
+
} else if ($gi->databaseType == GEOIP_REGION_EDITION_REV1){
|
276 |
+
$gi->databaseSegments = GEOIP_STATE_BEGIN_REV1;
|
277 |
+
} else if (($gi->databaseType == GEOIP_CITY_EDITION_REV0)||
|
278 |
+
($gi->databaseType == GEOIP_CITY_EDITION_REV1)
|
279 |
+
|| ($gi->databaseType == GEOIP_ORG_EDITION)
|
280 |
+
|| ($gi->databaseType == GEOIP_ORG_EDITION_V6)
|
281 |
+
|| ($gi->databaseType == GEOIP_DOMAIN_EDITION)
|
282 |
+
|| ($gi->databaseType == GEOIP_DOMAIN_EDITION_V6)
|
283 |
+
|| ($gi->databaseType == GEOIP_ISP_EDITION)
|
284 |
+
|| ($gi->databaseType == GEOIP_ISP_EDITION_V6)
|
285 |
+
|| ($gi->databaseType == GEOIP_USERTYPE_EDITION)
|
286 |
+
|| ($gi->databaseType == GEOIP_USERTYPE_EDITION_V6)
|
287 |
+
|| ($gi->databaseType == GEOIP_LOCATIONA_EDITION)
|
288 |
+
|| ($gi->databaseType == GEOIP_ACCURACYRADIUS_EDITION)
|
289 |
+
|| ($gi->databaseType == GEOIP_CITY_EDITION_REV0_V6)
|
290 |
+
|| ($gi->databaseType == GEOIP_CITY_EDITION_REV1_V6)
|
291 |
+
|| ($gi->databaseType == GEOIP_NETSPEED_EDITION_REV1)
|
292 |
+
|| ($gi->databaseType == GEOIP_NETSPEED_EDITION_REV1_V6)
|
293 |
+
|| ($gi->databaseType == GEOIP_ASNUM_EDITION)
|
294 |
+
|| ($gi->databaseType == GEOIP_ASNUM_EDITION_V6)){
|
295 |
+
$gi->databaseSegments = 0;
|
296 |
+
$buf = @shmop_read ($gi->shmid, $offset, SEGMENT_RECORD_LENGTH);
|
297 |
+
for ($j = 0;$j < SEGMENT_RECORD_LENGTH;$j++){
|
298 |
+
$gi->databaseSegments += (ord($buf[$j]) << ($j * 8));
|
299 |
+
}
|
300 |
+
if (($gi->databaseType == GEOIP_ORG_EDITION)
|
301 |
+
|| ($gi->databaseType == GEOIP_ORG_EDITION_V6)
|
302 |
+
|| ($gi->databaseType == GEOIP_DOMAIN_EDITION)
|
303 |
+
|| ($gi->databaseType == GEOIP_DOMAIN_EDITION_V6)
|
304 |
+
|| ($gi->databaseType == GEOIP_ISP_EDITION)
|
305 |
+
|| ($gi->databaseType == GEOIP_ISP_EDITION_V6)) {
|
306 |
+
$gi->record_length = ORG_RECORD_LENGTH;
|
307 |
+
}
|
308 |
+
}
|
309 |
+
break;
|
310 |
+
} else {
|
311 |
+
$offset -= 4;
|
312 |
+
}
|
313 |
+
}
|
314 |
+
if (($gi->databaseType == GEOIP_COUNTRY_EDITION)||
|
315 |
+
($gi->databaseType == GEOIP_COUNTRY_EDITION_V6)||
|
316 |
+
($gi->databaseType == GEOIP_PROXY_EDITION)||
|
317 |
+
($gi->databaseType == GEOIP_NETSPEED_EDITION)){
|
318 |
+
$gi->databaseSegments = GEOIP_COUNTRY_BEGIN;
|
319 |
+
}
|
320 |
+
} else {
|
321 |
+
$filepos = ftell($gi->filehandle);
|
322 |
+
fseek($gi->filehandle, -3, SEEK_END);
|
323 |
+
for ($i = 0; $i < STRUCTURE_INFO_MAX_SIZE; $i++) {
|
324 |
+
$delim = fread($gi->filehandle,3);
|
325 |
+
if ($delim == (chr(255).chr(255).chr(255))){
|
326 |
+
$gi->databaseType = ord(fread($gi->filehandle,1));
|
327 |
+
if ($gi->databaseType == GEOIP_REGION_EDITION_REV0){
|
328 |
+
$gi->databaseSegments = GEOIP_STATE_BEGIN_REV0;
|
329 |
+
}
|
330 |
+
else if ($gi->databaseType == GEOIP_REGION_EDITION_REV1){
|
331 |
+
$gi->databaseSegments = GEOIP_STATE_BEGIN_REV1;
|
332 |
+
} else if (($gi->databaseType == GEOIP_CITY_EDITION_REV0)
|
333 |
+
|| ($gi->databaseType == GEOIP_CITY_EDITION_REV1)
|
334 |
+
|| ($gi->databaseType == GEOIP_CITY_EDITION_REV0_V6)
|
335 |
+
|| ($gi->databaseType == GEOIP_CITY_EDITION_REV1_V6)
|
336 |
+
|| ($gi->databaseType == GEOIP_ORG_EDITION)
|
337 |
+
|| ($gi->databaseType == GEOIP_DOMAIN_EDITION)
|
338 |
+
|| ($gi->databaseType == GEOIP_ISP_EDITION)
|
339 |
+
|| ($gi->databaseType == GEOIP_ORG_EDITION_V6)
|
340 |
+
|| ($gi->databaseType == GEOIP_DOMAIN_EDITION_V6)
|
341 |
+
|| ($gi->databaseType == GEOIP_ISP_EDITION_V6)
|
342 |
+
|| ($gi->databaseType == GEOIP_LOCATIONA_EDITION)
|
343 |
+
|| ($gi->databaseType == GEOIP_ACCURACYRADIUS_EDITION)
|
344 |
+
|| ($gi->databaseType == GEOIP_CITY_EDITION_REV0_V6)
|
345 |
+
|| ($gi->databaseType == GEOIP_CITY_EDITION_REV1_V6)
|
346 |
+
|| ($gi->databaseType == GEOIP_NETSPEED_EDITION_REV1)
|
347 |
+
|| ($gi->databaseType == GEOIP_NETSPEED_EDITION_REV1_V6)
|
348 |
+
|| ($gi->databaseType == GEOIP_USERTYPE_EDITION)
|
349 |
+
|| ($gi->databaseType == GEOIP_USERTYPE_EDITION_V6)
|
350 |
+
|| ($gi->databaseType == GEOIP_ASNUM_EDITION)
|
351 |
+
|| ($gi->databaseType == GEOIP_ASNUM_EDITION_V6)){
|
352 |
+
$gi->databaseSegments = 0;
|
353 |
+
$buf = fread($gi->filehandle,SEGMENT_RECORD_LENGTH);
|
354 |
+
for ($j = 0;$j < SEGMENT_RECORD_LENGTH;$j++){
|
355 |
+
$gi->databaseSegments += (ord($buf[$j]) << ($j * 8));
|
356 |
+
}
|
357 |
+
if ( ( $gi->databaseType == GEOIP_ORG_EDITION )
|
358 |
+
|| ( $gi->databaseType == GEOIP_DOMAIN_EDITION )
|
359 |
+
|| ( $gi->databaseType == GEOIP_ISP_EDITION )
|
360 |
+
|| ( $gi->databaseType == GEOIP_ORG_EDITION_V6 )
|
361 |
+
|| ( $gi->databaseType == GEOIP_DOMAIN_EDITION_V6 )
|
362 |
+
|| ( $gi->databaseType == GEOIP_ISP_EDITION_V6 )) {
|
363 |
+
$gi->record_length = ORG_RECORD_LENGTH;
|
364 |
+
}
|
365 |
+
}
|
366 |
+
break;
|
367 |
+
} else {
|
368 |
+
fseek($gi->filehandle, -4, SEEK_CUR);
|
369 |
+
}
|
370 |
+
}
|
371 |
+
if (($gi->databaseType == GEOIP_COUNTRY_EDITION)||
|
372 |
+
($gi->databaseType == GEOIP_COUNTRY_EDITION_V6)||
|
373 |
+
($gi->databaseType == GEOIP_PROXY_EDITION)||
|
374 |
+
($gi->databaseType == GEOIP_NETSPEED_EDITION)){
|
375 |
+
$gi->databaseSegments = GEOIP_COUNTRY_BEGIN;
|
376 |
+
}
|
377 |
+
fseek($gi->filehandle,$filepos,SEEK_SET);
|
378 |
+
}
|
379 |
+
return $gi;
|
380 |
+
}
|
381 |
+
}
|
382 |
+
|
383 |
+
if(! function_exists('geoip_open')){
|
384 |
+
function geoip_open($filename, $flags) {
|
385 |
+
$gi = new wfWAFGeoIP;
|
386 |
+
$gi->flags = $flags;
|
387 |
+
if ($gi->flags & GEOIP_SHARED_MEMORY) {
|
388 |
+
$gi->shmid = @shmop_open (GEOIP_SHM_KEY, "a", 0, 0);
|
389 |
+
} else {
|
390 |
+
$gi->filehandle = fopen($filename,"rb") or die( "Can not open $filename\n" );
|
391 |
+
if ($gi->flags & GEOIP_MEMORY_CACHE) {
|
392 |
+
$s_array = fstat($gi->filehandle);
|
393 |
+
$gi->memory_buffer = fread($gi->filehandle, $s_array['size']);
|
394 |
+
}
|
395 |
+
}
|
396 |
+
|
397 |
+
$gi = _setup_segments($gi);
|
398 |
+
return $gi;
|
399 |
+
}
|
400 |
+
}
|
401 |
+
|
402 |
+
if(! function_exists('geoip_close')){
|
403 |
+
function geoip_close($gi) {
|
404 |
+
if ($gi->flags & GEOIP_SHARED_MEMORY) {
|
405 |
+
return true;
|
406 |
+
}
|
407 |
+
|
408 |
+
return fclose($gi->filehandle);
|
409 |
+
}
|
410 |
+
}
|
411 |
+
|
412 |
+
if(! function_exists('geoip_country_id_by_name_v6')){
|
413 |
+
function geoip_country_id_by_name_v6($gi, $name) {
|
414 |
+
$rec = @dns_get_record($name, DNS_AAAA);
|
415 |
+
if ( !$rec ) {
|
416 |
+
return false;
|
417 |
+
}
|
418 |
+
$addr = $rec[0]["ipv6"];
|
419 |
+
if (!$addr || $addr == $name) {
|
420 |
+
return false;
|
421 |
+
}
|
422 |
+
return geoip_country_id_by_addr_v6($gi, $addr);
|
423 |
+
}
|
424 |
+
}
|
425 |
+
|
426 |
+
if(! function_exists('geoip_country_id_by_name')){
|
427 |
+
function geoip_country_id_by_name($gi, $name) {
|
428 |
+
$addr = gethostbyname($name);
|
429 |
+
if (!$addr || $addr == $name) {
|
430 |
+
return false;
|
431 |
+
}
|
432 |
+
return geoip_country_id_by_addr($gi, $addr);
|
433 |
+
}
|
434 |
+
}
|
435 |
+
|
436 |
+
if(! function_exists('geoip_country_id_by_name')){
|
437 |
+
function geoip_country_code_by_name_v6($gi, $name) {
|
438 |
+
$country_id = geoip_country_id_by_name_v6($gi,$name);
|
439 |
+
if ($country_id !== false) {
|
440 |
+
return $gi->GEOIP_COUNTRY_CODES[$country_id];
|
441 |
+
}
|
442 |
+
return false;
|
443 |
+
}
|
444 |
+
}
|
445 |
+
|
446 |
+
if(! function_exists('geoip_country_code_by_name')){
|
447 |
+
function geoip_country_code_by_name($gi, $name) {
|
448 |
+
$country_id = geoip_country_id_by_name($gi,$name);
|
449 |
+
if ($country_id !== false) {
|
450 |
+
return $gi->GEOIP_COUNTRY_CODES[$country_id];
|
451 |
+
}
|
452 |
+
return false;
|
453 |
+
}
|
454 |
+
}
|
455 |
+
|
456 |
+
if(! function_exists('geoip_country_name_by_name_v6')){
|
457 |
+
function geoip_country_name_by_name_v6($gi, $name) {
|
458 |
+
$country_id = geoip_country_id_by_name_v6($gi,$name);
|
459 |
+
if ($country_id !== false) {
|
460 |
+
return $gi->GEOIP_COUNTRY_NAMES[$country_id];
|
461 |
+
}
|
462 |
+
return false;
|
463 |
+
}
|
464 |
+
}
|
465 |
+
|
466 |
+
if(! function_exists('geoip_country_name_by_name')){
|
467 |
+
function geoip_country_name_by_name($gi, $name) {
|
468 |
+
$country_id = geoip_country_id_by_name($gi,$name);
|
469 |
+
if ($country_id !== false) {
|
470 |
+
return $gi->GEOIP_COUNTRY_NAMES[$country_id];
|
471 |
+
}
|
472 |
+
return false;
|
473 |
+
}
|
474 |
+
}
|
475 |
+
|
476 |
+
if(! function_exists('geoip_country_id_by_addr_v6')){
|
477 |
+
function geoip_country_id_by_addr_v6($gi, $addr) {
|
478 |
+
$ipnum = wfWAFUtils::inet_pton($addr);
|
479 |
+
return _geoip_seek_country_v6($gi, $ipnum) - GEOIP_COUNTRY_BEGIN;
|
480 |
+
}
|
481 |
+
}
|
482 |
+
|
483 |
+
if(! function_exists('geoip_country_id_by_addr')){
|
484 |
+
function geoip_country_id_by_addr($gi, $addr) {
|
485 |
+
$ipnum = ip2long($addr);
|
486 |
+
return _geoip_seek_country($gi, $ipnum) - GEOIP_COUNTRY_BEGIN;
|
487 |
+
}
|
488 |
+
}
|
489 |
+
|
490 |
+
if(! function_exists('geoip_country_code_by_addr_v6')){
|
491 |
+
function geoip_country_code_by_addr_v6($gi, $addr) {
|
492 |
+
$country_id = geoip_country_id_by_addr_v6($gi,$addr);
|
493 |
+
if ($country_id !== false) {
|
494 |
+
return $gi->GEOIP_COUNTRY_CODES[$country_id];
|
495 |
+
}
|
496 |
+
return false;
|
497 |
+
}
|
498 |
+
}
|
499 |
+
|
500 |
+
if(! function_exists('geoip_country_code_by_addr')){
|
501 |
+
function geoip_country_code_by_addr($gi, $addr) {
|
502 |
+
if ($gi->databaseType == GEOIP_CITY_EDITION_REV1) {
|
503 |
+
$record = geoip_record_by_addr($gi,$addr);
|
504 |
+
if ( $record !== false ) {
|
505 |
+
return $record->country_code;
|
506 |
+
}
|
507 |
+
} else {
|
508 |
+
$country_id = geoip_country_id_by_addr($gi,$addr);
|
509 |
+
if ($country_id !== false) {
|
510 |
+
return $gi->GEOIP_COUNTRY_CODES[$country_id];
|
511 |
+
}
|
512 |
+
}
|
513 |
+
return false;
|
514 |
+
}
|
515 |
+
}
|
516 |
+
|
517 |
+
if(! function_exists('geoip_country_name_by_addr_v6')){
|
518 |
+
function geoip_country_name_by_addr_v6($gi, $addr) {
|
519 |
+
$country_id = geoip_country_id_by_addr_v6($gi,$addr);
|
520 |
+
if ($country_id !== false) {
|
521 |
+
return $gi->GEOIP_COUNTRY_NAMES[$country_id];
|
522 |
+
}
|
523 |
+
return false;
|
524 |
+
}
|
525 |
+
}
|
526 |
+
|
527 |
+
if(! function_exists('geoip_country_name_by_addr')){
|
528 |
+
function geoip_country_name_by_addr($gi, $addr) {
|
529 |
+
if ($gi->databaseType == GEOIP_CITY_EDITION_REV1) {
|
530 |
+
$record = geoip_record_by_addr($gi,$addr);
|
531 |
+
return $record->country_name;
|
532 |
+
} else {
|
533 |
+
$country_id = geoip_country_id_by_addr($gi,$addr);
|
534 |
+
if ($country_id !== false) {
|
535 |
+
return $gi->GEOIP_COUNTRY_NAMES[$country_id];
|
536 |
+
}
|
537 |
+
}
|
538 |
+
return false;
|
539 |
+
}
|
540 |
+
}
|
541 |
+
|
542 |
+
if(! function_exists('_geoip_seek_country_v6')){
|
543 |
+
function _geoip_seek_country_v6($gi, $ipnum) {
|
544 |
+
|
545 |
+
# arrays from unpack start with offset 1
|
546 |
+
# yet another php mystery. array_merge work around
|
547 |
+
# this broken behaviour
|
548 |
+
$v6vec = array_merge(unpack( "C16", $ipnum));
|
549 |
+
|
550 |
+
$offset = 0;
|
551 |
+
for ($depth = 127; $depth >= 0; --$depth) {
|
552 |
+
if ($gi->flags & GEOIP_MEMORY_CACHE) {
|
553 |
+
// workaround php's broken substr, strpos, etc handling with
|
554 |
+
// mbstring.func_overload and mbstring.internal_encoding
|
555 |
+
$enc = mb_internal_encoding();
|
556 |
+
mb_internal_encoding('ISO-8859-1');
|
557 |
+
|
558 |
+
$buf = substr($gi->memory_buffer,
|
559 |
+
2 * $gi->record_length * $offset,
|
560 |
+
2 * $gi->record_length);
|
561 |
+
|
562 |
+
mb_internal_encoding($enc);
|
563 |
+
} elseif ($gi->flags & GEOIP_SHARED_MEMORY) {
|
564 |
+
$buf = @shmop_read ($gi->shmid,
|
565 |
+
2 * $gi->record_length * $offset,
|
566 |
+
2 * $gi->record_length );
|
567 |
+
} else {
|
568 |
+
fseek($gi->filehandle, 2 * $gi->record_length * $offset, SEEK_SET) == 0
|
569 |
+
or die("fseek failed");
|
570 |
+
$buf = fread($gi->filehandle, 2 * $gi->record_length);
|
571 |
+
}
|
572 |
+
$x = array(0,0);
|
573 |
+
for ($i = 0; $i < 2; ++$i) {
|
574 |
+
for ($j = 0; $j < $gi->record_length; ++$j) {
|
575 |
+
$x[$i] += ord($buf[$gi->record_length * $i + $j]) << ($j * 8);
|
576 |
+
}
|
577 |
+
}
|
578 |
+
|
579 |
+
$bnum = 127 - $depth;
|
580 |
+
$idx = $bnum >> 3;
|
581 |
+
$b_mask = 1 << ( $bnum & 7 ^ 7 );
|
582 |
+
if (($v6vec[$idx] & $b_mask) > 0) {
|
583 |
+
if ($x[1] >= $gi->databaseSegments) {
|
584 |
+
return $x[1];
|
585 |
+
}
|
586 |
+
$offset = $x[1];
|
587 |
+
} else {
|
588 |
+
if ($x[0] >= $gi->databaseSegments) {
|
589 |
+
return $x[0];
|
590 |
+
}
|
591 |
+
$offset = $x[0];
|
592 |
+
}
|
593 |
+
}
|
594 |
+
trigger_error("error traversing database - perhaps it is corrupt?", E_USER_ERROR);
|
595 |
+
return false;
|
596 |
+
}
|
597 |
+
}
|
598 |
+
|
599 |
+
if(! function_exists('_geoip_seek_country')){
|
600 |
+
function _geoip_seek_country($gi, $ipnum) {
|
601 |
+
$offset = 0;
|
602 |
+
for ($depth = 31; $depth >= 0; --$depth) {
|
603 |
+
if ($gi->flags & GEOIP_MEMORY_CACHE) {
|
604 |
+
// workaround php's broken substr, strpos, etc handling with
|
605 |
+
// mbstring.func_overload and mbstring.internal_encoding
|
606 |
+
$enc = mb_internal_encoding();
|
607 |
+
mb_internal_encoding('ISO-8859-1');
|
608 |
+
|
609 |
+
$buf = substr($gi->memory_buffer,
|
610 |
+
2 * $gi->record_length * $offset,
|
611 |
+
2 * $gi->record_length);
|
612 |
+
|
613 |
+
mb_internal_encoding($enc);
|
614 |
+
} elseif ($gi->flags & GEOIP_SHARED_MEMORY) {
|
615 |
+
$buf = @shmop_read ($gi->shmid,
|
616 |
+
2 * $gi->record_length * $offset,
|
617 |
+
2 * $gi->record_length );
|
618 |
+
} else {
|
619 |
+
fseek($gi->filehandle, 2 * $gi->record_length * $offset, SEEK_SET) == 0
|
620 |
+
or die("fseek failed");
|
621 |
+
$buf = fread($gi->filehandle, 2 * $gi->record_length);
|
622 |
+
}
|
623 |
+
$x = array(0,0);
|
624 |
+
for ($i = 0; $i < 2; ++$i) {
|
625 |
+
for ($j = 0; $j < $gi->record_length; ++$j) {
|
626 |
+
$x[$i] += ord($buf[$gi->record_length * $i + $j]) << ($j * 8);
|
627 |
+
}
|
628 |
+
}
|
629 |
+
if ($ipnum & (1 << $depth)) {
|
630 |
+
if ($x[1] >= $gi->databaseSegments) {
|
631 |
+
return $x[1];
|
632 |
+
}
|
633 |
+
$offset = $x[1];
|
634 |
+
} else {
|
635 |
+
if ($x[0] >= $gi->databaseSegments) {
|
636 |
+
return $x[0];
|
637 |
+
}
|
638 |
+
$offset = $x[0];
|
639 |
+
}
|
640 |
+
}
|
641 |
+
trigger_error("error traversing database - perhaps it is corrupt?", E_USER_ERROR);
|
642 |
+
return false;
|
643 |
+
}
|
644 |
+
}
|
645 |
+
|
646 |
+
if(! function_exists('_common_get_org')){
|
647 |
+
function _common_get_org($gi, $seek_org){
|
648 |
+
$record_pointer = $seek_org + (2 * $gi->record_length - 1) * $gi->databaseSegments;
|
649 |
+
if ($gi->flags & GEOIP_SHARED_MEMORY) {
|
650 |
+
$org_buf = @shmop_read ($gi->shmid, $record_pointer, MAX_ORG_RECORD_LENGTH);
|
651 |
+
} else {
|
652 |
+
fseek($gi->filehandle, $record_pointer, SEEK_SET);
|
653 |
+
$org_buf = fread($gi->filehandle,MAX_ORG_RECORD_LENGTH);
|
654 |
+
}
|
655 |
+
// workaround php's broken substr, strpos, etc handling with
|
656 |
+
// mbstring.func_overload and mbstring.internal_encoding
|
657 |
+
$enc = mb_internal_encoding();
|
658 |
+
mb_internal_encoding('ISO-8859-1');
|
659 |
+
$org_buf = substr($org_buf, 0, strpos($org_buf, "\0"));
|
660 |
+
mb_internal_encoding($enc);
|
661 |
+
return $org_buf;
|
662 |
+
}
|
663 |
+
}
|
664 |
+
|
665 |
+
if(! function_exists('_get_org_v6')){
|
666 |
+
function _get_org_v6($gi,$ipnum){
|
667 |
+
$seek_org = _geoip_seek_country_v6($gi,$ipnum);
|
668 |
+
if ($seek_org == $gi->databaseSegments) {
|
669 |
+
return NULL;
|
670 |
+
}
|
671 |
+
return _common_get_org($gi, $seek_org);
|
672 |
+
}
|
673 |
+
}
|
674 |
+
|
675 |
+
if(! function_exists('_get_org')){
|
676 |
+
function _get_org($gi,$ipnum){
|
677 |
+
$seek_org = _geoip_seek_country($gi,$ipnum);
|
678 |
+
if ($seek_org == $gi->databaseSegments) {
|
679 |
+
return NULL;
|
680 |
+
}
|
681 |
+
return _common_get_org($gi, $seek_org);
|
682 |
+
}
|
683 |
+
}
|
684 |
+
|
685 |
+
if(! function_exists('geoip_name_by_addr_v6')){
|
686 |
+
function geoip_name_by_addr_v6 ($gi,$addr) {
|
687 |
+
if ($addr == NULL) {
|
688 |
+
return 0;
|
689 |
+
}
|
690 |
+
$ipnum = wfWAFUtils::inet_pton($addr);
|
691 |
+
return _get_org_v6($gi, $ipnum);
|
692 |
+
}
|
693 |
+
}
|
694 |
+
|
695 |
+
if(! function_exists('geoip_name_by_addr')){
|
696 |
+
function geoip_name_by_addr ($gi,$addr) {
|
697 |
+
if ($addr == NULL) {
|
698 |
+
return 0;
|
699 |
+
}
|
700 |
+
$ipnum = ip2long($addr);
|
701 |
+
return _get_org($gi, $ipnum);
|
702 |
+
}
|
703 |
+
}
|
704 |
+
|
705 |
+
if(! function_exists('geoip_org_by_addr')){
|
706 |
+
function geoip_org_by_addr ($gi,$addr) {
|
707 |
+
return geoip_name_by_addr($gi, $addr);
|
708 |
+
}
|
709 |
+
}
|
710 |
+
|
711 |
+
if(! function_exists('_get_region')){
|
712 |
+
function _get_region($gi,$ipnum){
|
713 |
+
if ($gi->databaseType == GEOIP_REGION_EDITION_REV0){
|
714 |
+
$seek_region = _geoip_seek_country($gi,$ipnum) - GEOIP_STATE_BEGIN_REV0;
|
715 |
+
if ($seek_region >= 1000){
|
716 |
+
$country_code = "US";
|
717 |
+
$region = chr(($seek_region - 1000)/26 + 65) . chr(($seek_region - 1000)%26 + 65);
|
718 |
+
} else {
|
719 |
+
$country_code = $gi->GEOIP_COUNTRY_CODES[$seek_region];
|
720 |
+
$region = "";
|
721 |
+
}
|
722 |
+
return array ($country_code,$region);
|
723 |
+
} else if ($gi->databaseType == GEOIP_REGION_EDITION_REV1) {
|
724 |
+
$seek_region = _geoip_seek_country($gi,$ipnum) - GEOIP_STATE_BEGIN_REV1;
|
725 |
+
//print $seek_region;
|
726 |
+
if ($seek_region < US_OFFSET){
|
727 |
+
$country_code = "";
|
728 |
+
$region = "";
|
729 |
+
} else if ($seek_region < CANADA_OFFSET) {
|
730 |
+
$country_code = "US";
|
731 |
+
$region = chr(($seek_region - US_OFFSET)/26 + 65) . chr(($seek_region - US_OFFSET)%26 + 65);
|
732 |
+
} else if ($seek_region < WORLD_OFFSET) {
|
733 |
+
$country_code = "CA";
|
734 |
+
$region = chr(($seek_region - CANADA_OFFSET)/26 + 65) . chr(($seek_region - CANADA_OFFSET)%26 + 65);
|
735 |
+
} else {
|
736 |
+
$country_code = $gi->GEOIP_COUNTRY_CODES[($seek_region - WORLD_OFFSET) / FIPS_RANGE];
|
737 |
+
$region = "";
|
738 |
+
}
|
739 |
+
return array ($country_code,$region);
|
740 |
+
}
|
741 |
+
}
|
742 |
+
}
|
743 |
+
|
744 |
+
if(! function_exists('geoip_region_by_addr')){
|
745 |
+
function geoip_region_by_addr ($gi,$addr) {
|
746 |
+
if ($addr == NULL) {
|
747 |
+
return 0;
|
748 |
+
}
|
749 |
+
$ipnum = ip2long($addr);
|
750 |
+
return _get_region($gi, $ipnum);
|
751 |
+
}
|
752 |
+
}
|
753 |
+
|
754 |
+
if(! function_exists('getdnsattributes')){
|
755 |
+
function getdnsattributes ($l,$ip){
|
756 |
+
$r = new Net_DNS_Resolver();
|
757 |
+
$r->nameservers = array("ws1.maxmind.com");
|
758 |
+
$p = $r->search($l."." . $ip .".s.maxmind.com","TXT","IN");
|
759 |
+
$str = is_object($p->answer[0])?$p->answer[0]->string():'';
|
760 |
+
$str = substr( $str, 1, -1 );
|
761 |
+
return $str;
|
762 |
+
}
|
763 |
+
}
|
764 |
+
}
|
765 |
+
?>
|
waf/wfWAFIPBlocksController.php
ADDED
@@ -0,0 +1,394 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
class wfWAFIPBlocksController
|
3 |
+
{
|
4 |
+
const WFWAF_BLOCK_UAREFIPRANGE = 'UA/Referrer/IP Range not allowed';
|
5 |
+
const WFWAF_BLOCK_COUNTRY = 'blocked access via country blocking';
|
6 |
+
const WFWAF_BLOCK_COUNTRY_REDIR = 'blocked access via country blocking and redirected to URL';
|
7 |
+
const WFWAF_BLOCK_COUNTRY_BYPASS_REDIR = 'redirected to bypass URL';
|
8 |
+
const WFWAF_BLOCK_WFSN = 'Blocked by Wordfence Security Network';
|
9 |
+
|
10 |
+
protected static $_currentController = null;
|
11 |
+
|
12 |
+
public static function currentController() {
|
13 |
+
if (self::$_currentController === null) {
|
14 |
+
self::$_currentController = new wfWAFIPBlocksController();
|
15 |
+
}
|
16 |
+
return self::$_currentController;
|
17 |
+
}
|
18 |
+
|
19 |
+
public static function setCurrentController($currentController) {
|
20 |
+
self::$_currentController = $currentController;
|
21 |
+
}
|
22 |
+
|
23 |
+
public static function synchronizeConfigSettings() {
|
24 |
+
if (!class_exists('wfConfig')) { // Ensure this is only called when WordPress and the plugin are fully loaded
|
25 |
+
return;
|
26 |
+
}
|
27 |
+
|
28 |
+
static $isSynchronizing = false;
|
29 |
+
if ($isSynchronizing) {
|
30 |
+
return;
|
31 |
+
}
|
32 |
+
$isSynchronizing = true;
|
33 |
+
|
34 |
+
global $wpdb;
|
35 |
+
$db = new wfDB();
|
36 |
+
|
37 |
+
// Pattern Blocks
|
38 |
+
$r1 = $db->querySelect("SELECT id, blockType, blockString FROM {$wpdb->base_prefix}wfBlocksAdv");
|
39 |
+
$patternBlocks = array();
|
40 |
+
foreach ($r1 as $blockRec) {
|
41 |
+
if ($blockRec['blockType'] == 'IU') {
|
42 |
+
$bDat = explode('|', $blockRec['blockString']);
|
43 |
+
$ipRange = isset($bDat[0]) ? $bDat[0] : '';
|
44 |
+
$uaPattern = isset($bDat[1]) ? $bDat[1] : '';
|
45 |
+
$refPattern = isset($bDat[2]) ? $bDat[2] : '';
|
46 |
+
$hostnamePattern = isset($bDat[3]) ? $bDat[3] : '';
|
47 |
+
|
48 |
+
$patternBlocks[] = array('id' => $blockRec['id'], 'ipRange' => $ipRange, 'hostnamePattern' => $hostnamePattern, 'uaPattern' => $uaPattern, 'refPattern' => $refPattern);
|
49 |
+
}
|
50 |
+
}
|
51 |
+
|
52 |
+
// Country Blocks
|
53 |
+
$wfLog = new wfLog(wfConfig::get('apiKey'), wfUtils::getWPVersion());
|
54 |
+
$cblCookie = $wfLog->getCBLCookieVal(); //Ensure we have the bypass cookie option set
|
55 |
+
|
56 |
+
$countryBlocks = array();
|
57 |
+
$countryBlocks['action'] = wfConfig::get('cbl_action', false);
|
58 |
+
$countryBlocks['loggedInBlocked'] = wfConfig::get('cbl_loggedInBlocked', false);
|
59 |
+
$countryBlocks['loginFormBlocked'] = wfConfig::get('cbl_loginFormBlocked', false);
|
60 |
+
$countryBlocks['restOfSiteBlocked'] = wfConfig::get('cbl_restOfSiteBlocked', false);
|
61 |
+
$countryBlocks['bypassRedirURL'] = wfConfig::get('cbl_bypassRedirURL', '');
|
62 |
+
$countryBlocks['bypassRedirDest'] = wfConfig::get('cbl_bypassRedirDest', '');
|
63 |
+
$countryBlocks['bypassViewURL'] = wfConfig::get('cbl_bypassViewURL', '');
|
64 |
+
$countryBlocks['redirURL'] = wfConfig::get('cbl_redirURL', '');
|
65 |
+
$countryBlocks['countries'] = explode(',', wfConfig::get('cbl_countries', ''));
|
66 |
+
$countryBlocks['cookieVal'] = $cblCookie;
|
67 |
+
|
68 |
+
//Other Blocks
|
69 |
+
$otherBlocks = array('blockedTime' => wfConfig::get('blockedTime', 0));
|
70 |
+
$otherBlockEntries = $db->querySelect("SELECT IP, blockedTime, reason, permanent, wfsn FROM {$wpdb->base_prefix}wfBlocks WHERE permanent = 1 OR (blockedTime + %d > unix_timestamp())", $otherBlocks['blockedTime']);
|
71 |
+
$otherBlocks['blocks'] = (is_array($otherBlockEntries) ? $otherBlockEntries : array());
|
72 |
+
foreach ($otherBlocks['blocks'] as &$b) {
|
73 |
+
$b['IP'] = base64_encode($b['IP']);
|
74 |
+
}
|
75 |
+
|
76 |
+
// Save it
|
77 |
+
try {
|
78 |
+
$patternBlocksJSON = wfWAFUtils::json_encode($patternBlocks);
|
79 |
+
wfWAF::getInstance()->getStorageEngine()->setConfig('patternBlocks', $patternBlocksJSON);
|
80 |
+
$countryBlocksJSON = wfWAFUtils::json_encode($countryBlocks);
|
81 |
+
wfWAF::getInstance()->getStorageEngine()->setConfig('countryBlocks', $countryBlocksJSON);
|
82 |
+
$otherBlocksJSON = wfWAFUtils::json_encode($otherBlocks);
|
83 |
+
wfWAF::getInstance()->getStorageEngine()->setConfig('otherBlocks', $otherBlocksJSON);
|
84 |
+
|
85 |
+
wfWAF::getInstance()->getStorageEngine()->setConfig('advancedBlockingEnabled', wfConfig::get('firewallEnabled'));
|
86 |
+
wfWAF::getInstance()->getStorageEngine()->setConfig('disableWAFIPBlocking', wfConfig::get('disableWAFIPBlocking'));
|
87 |
+
}
|
88 |
+
catch (Exception $e) {
|
89 |
+
// Do nothing
|
90 |
+
}
|
91 |
+
$isSynchronizing = false;
|
92 |
+
}
|
93 |
+
|
94 |
+
/**
|
95 |
+
* @param wfWAFRequest $request
|
96 |
+
* @return bool|string If not blocked, returns false. Otherwise a string of the reason it was blocked or true.
|
97 |
+
*/
|
98 |
+
public function shouldBlockRequest($request) {
|
99 |
+
// Checking the user whitelist is done before reaching this call
|
100 |
+
|
101 |
+
$ip = $request->getIP();
|
102 |
+
|
103 |
+
//Check the system whitelist
|
104 |
+
if ($this->checkForWhitelisted($ip)) {
|
105 |
+
return false;
|
106 |
+
}
|
107 |
+
|
108 |
+
//Let the plugin handle these
|
109 |
+
$wfFunc = $request->getQueryString('_wfsf');
|
110 |
+
if ($wfFunc == 'unlockEmail' || $wfFunc == 'unlockAccess') { // Can't check validity here, let it pass through to plugin level where it can
|
111 |
+
return false;
|
112 |
+
}
|
113 |
+
|
114 |
+
$logHuman = $request->getQueryString('wordfence_logHuman');
|
115 |
+
if ($logHuman !== null) {
|
116 |
+
return false;
|
117 |
+
}
|
118 |
+
|
119 |
+
//Start block checks
|
120 |
+
$ipNum = wfWAFUtils::inet_pton($ip);
|
121 |
+
$hostname = null;
|
122 |
+
$ua = $request->getHeaders('User-Agent'); if ($ua === null) { $ua = ''; }
|
123 |
+
$referer = $request->getHeaders('Referer'); if ($referer === null) { $referer = ''; }
|
124 |
+
|
125 |
+
$isPaid = false;
|
126 |
+
try {
|
127 |
+
$isPaid = wfWAF::getInstance()->getStorageEngine()->getConfig('isPaid');
|
128 |
+
$pluginABSPATH = wfWAF::getInstance()->getStorageEngine()->getConfig('pluginABSPATH');
|
129 |
+
|
130 |
+
$patternBlocksJSON = wfWAF::getInstance()->getStorageEngine()->getConfig('patternBlocks');
|
131 |
+
$countryBlocksJSON = wfWAF::getInstance()->getStorageEngine()->getConfig('countryBlocks');
|
132 |
+
$otherBlocksJSON = wfWAF::getInstance()->getStorageEngine()->getConfig('otherBlocks');
|
133 |
+
}
|
134 |
+
catch (Exception $e) {
|
135 |
+
// Do nothing
|
136 |
+
}
|
137 |
+
|
138 |
+
if (isset($_SERVER['SCRIPT_FILENAME']) && (strpos($_SERVER['SCRIPT_FILENAME'], $pluginABSPATH . "wp-admin/") === 0 || strpos($_SERVER['SCRIPT_FILENAME'], $pluginABSPATH . "wp-content/") === 0 || strpos($_SERVER['SCRIPT_FILENAME'], $pluginABSPATH . "wp-includes/") === 0)) {
|
139 |
+
return false; //Rely on WordPress's own access control and blocking at the plugin level
|
140 |
+
}
|
141 |
+
|
142 |
+
// Pattern Blocks from the Advanced Blocking page (IP Range, UA, Referer)
|
143 |
+
$patternBlocks = @wfWAFUtils::json_decode($patternBlocksJSON, true);
|
144 |
+
if (is_array($patternBlocks)) {
|
145 |
+
// Instead of a long block of if/else statements, using bitshifting to generate an expected value and a found value
|
146 |
+
$ipRangeOffset = 1;
|
147 |
+
$uaPatternOffset = 2;
|
148 |
+
$refPatternOffset = 3;
|
149 |
+
|
150 |
+
foreach ($patternBlocks as $b) {
|
151 |
+
$expectedBits = 0;
|
152 |
+
$foundBits = 0;
|
153 |
+
|
154 |
+
if (!empty($b['ipRange'])) {
|
155 |
+
$expectedBits |= (1 << $ipRangeOffset);
|
156 |
+
list($start_range, $end_range) = explode('-', $b['ipRange']);
|
157 |
+
if (preg_match('/[\.:]/', $start_range)) {
|
158 |
+
$start_range = wfWAFUtils::inet_pton($start_range);
|
159 |
+
$end_range = wfWAFUtils::inet_pton($end_range);
|
160 |
+
} else {
|
161 |
+
$start_range = wfWAFUtils::inet_pton(long2ip($start_range));
|
162 |
+
$end_range = wfWAFUtils::inet_pton(long2ip($end_range));
|
163 |
+
}
|
164 |
+
|
165 |
+
if (strcmp($ipNum, $start_range) >= 0 && strcmp($ipNum, $end_range) <= 0) {
|
166 |
+
$foundBits |= (1 << $ipRangeOffset);
|
167 |
+
}
|
168 |
+
}
|
169 |
+
|
170 |
+
if (!empty($b['hostnamePattern'])) {
|
171 |
+
$expectedBits |= (1 << $ipRangeOffset);
|
172 |
+
if ($hostname === null) {
|
173 |
+
$hostname = wfWAFUtils::reverseLookup($ip);
|
174 |
+
}
|
175 |
+
if (preg_match(wfWAFUtils::patternToRegex($b['hostnamePattern']), $hostname)) {
|
176 |
+
$foundBits |= (1 << $ipRangeOffset);
|
177 |
+
}
|
178 |
+
}
|
179 |
+
|
180 |
+
if (!empty($b['uaPattern'])) {
|
181 |
+
$expectedBits |= (1 << $uaPatternOffset);
|
182 |
+
if (wfWAFUtils::isUABlocked($b['uaPattern'], $ua)) {
|
183 |
+
$foundBits |= (1 << $uaPatternOffset);
|
184 |
+
}
|
185 |
+
}
|
186 |
+
|
187 |
+
if (!empty($b['refPattern'])) {
|
188 |
+
$expectedBits |= (1 << $refPatternOffset);
|
189 |
+
if (wfWAFUtils::isRefererBlocked($b['refPattern'], $referer)) {
|
190 |
+
$foundBits |= (1 << $refPatternOffset);
|
191 |
+
}
|
192 |
+
}
|
193 |
+
|
194 |
+
if ($foundBits === $expectedBits && $expectedBits > 0) {
|
195 |
+
return array('action' => self::WFWAF_BLOCK_UAREFIPRANGE, 'id' => $b['id']);
|
196 |
+
}
|
197 |
+
}
|
198 |
+
}
|
199 |
+
// End Pattern Blocks
|
200 |
+
|
201 |
+
// Country Blocking
|
202 |
+
if ($isPaid) {
|
203 |
+
$countryBlocks = @wfWAFUtils::json_decode($countryBlocksJSON, true);
|
204 |
+
if (is_array($countryBlocks)) {
|
205 |
+
$blockedCountries = $countryBlocks['countries'];
|
206 |
+
$bareRequestURI = wfWAFUtils::extractBareURI($request->getURI());
|
207 |
+
$bareBypassRedirURI = wfWAFUtils::extractBareURI($countryBlocks['bypassRedirURL']);
|
208 |
+
$skipCountryBlocking = false;
|
209 |
+
|
210 |
+
if ($bareBypassRedirURI && $bareRequestURI == $bareBypassRedirURI) { // Run this before country blocking because even if the user isn't blocked we need to set the bypass cookie so they can bypass future blocks.
|
211 |
+
if ($countryBlocks['bypassRedirDest']) {
|
212 |
+
setcookie('wfCBLBypass', $countryBlocks['cookieVal'], time() + (86400 * 365), '/', null, null, true);
|
213 |
+
return array('action' => self::WFWAF_BLOCK_COUNTRY_BYPASS_REDIR);
|
214 |
+
}
|
215 |
+
}
|
216 |
+
|
217 |
+
$bareBypassViewURI = wfWAFUtils::extractBareURI($countryBlocks['bypassViewURL']);
|
218 |
+
if ($bareBypassViewURI && $bareBypassViewURI == $bareRequestURI) {
|
219 |
+
setcookie('wfCBLBypass', $countryBlocks['cookieVal'], time() + (86400 * 365), '/', null, null, true);
|
220 |
+
$skipCountryBlocking = true;
|
221 |
+
}
|
222 |
+
|
223 |
+
$bypassCookieSet = false;
|
224 |
+
$bypassCookie = $request->getCookies('wfCBLBypass');
|
225 |
+
if (isset($bypassCookie) && $bypassCookie == $countryBlocks['cookieVal']) {
|
226 |
+
$bypassCookieSet = true;
|
227 |
+
}
|
228 |
+
|
229 |
+
if (!$skipCountryBlocking && $blockedCountries && !$bypassCookieSet) {
|
230 |
+
$isAuthRequest = (strpos($bareRequestURI, '/wp-login.php') !== false);
|
231 |
+
$isXMLRPC = (strpos($bareRequestURI, '/xmlrpc.php') !== false);
|
232 |
+
$isUserLoggedIn = wfWAF::getInstance()->parseAuthCookie() !== false;
|
233 |
+
|
234 |
+
// If everything is checked, make sure this always runs.
|
235 |
+
if ($countryBlocks['loggedInBlocked'] && $countryBlocks['loginFormBlocked'] && $countryBlocks['restOfSiteBlocked']) {
|
236 |
+
if ($blocked = $this->checkForBlockedCountry($countryBlocks, $ip, $bareRequestURI)) { return $blocked; }
|
237 |
+
}
|
238 |
+
// Block logged in users.
|
239 |
+
if ($countryBlocks['loggedInBlocked'] && $isUserLoggedIn) {
|
240 |
+
if ($blocked = $this->checkForBlockedCountry($countryBlocks, $ip, $bareRequestURI)) { return $blocked; }
|
241 |
+
}
|
242 |
+
// Block the login form itself and any attempt to authenticate.
|
243 |
+
if ($countryBlocks['loginFormBlocked'] && $isAuthRequest) {
|
244 |
+
if ($blocked = $this->checkForBlockedCountry($countryBlocks, $ip, $bareRequestURI)) { return $blocked; }
|
245 |
+
}
|
246 |
+
// Block requests that aren't to the login page, xmlrpc.php, or a user already logged in.
|
247 |
+
if ($countryBlocks['restOfSiteBlocked'] && !$isAuthRequest && !$isXMLRPC && !$isUserLoggedIn) {
|
248 |
+
if ($blocked = $this->checkForBlockedCountry($countryBlocks, $ip, $bareRequestURI)) { return $blocked; }
|
249 |
+
}
|
250 |
+
// XMLRPC is inaccesible when public portion of the site and auth is disabled.
|
251 |
+
if ($countryBlocks['loginFormBlocked'] && $countryBlocks['restOfSiteBlocked'] && $isXMLRPC) {
|
252 |
+
if ($blocked = $this->checkForBlockedCountry($countryBlocks, $ip, $bareRequestURI)) { return $blocked; }
|
253 |
+
}
|
254 |
+
|
255 |
+
// Any bypasses and other block possibilities will be checked at the plugin level once WordPress loads
|
256 |
+
}
|
257 |
+
}
|
258 |
+
}
|
259 |
+
// End Country Blocking
|
260 |
+
|
261 |
+
// Other Blocks
|
262 |
+
$otherBlocks = @wfWAFUtils::json_decode($otherBlocksJSON, true);
|
263 |
+
if (is_array($otherBlocks)) {
|
264 |
+
$blockedTime = $otherBlocks['blockedTime'];
|
265 |
+
$blocks = $otherBlocks['blocks'];
|
266 |
+
$bareRequestURI = wfWAFUtils::extractBareURI($request->getURI());
|
267 |
+
$isAuthRequest = (strpos($bareRequestURI, '/wp-login.php') !== false);
|
268 |
+
foreach ($blocks as $b) {
|
269 |
+
if (!$b['permanent'] && ($b['blockedTime'] + $blockedTime) < time()) {
|
270 |
+
continue;
|
271 |
+
}
|
272 |
+
|
273 |
+
if (base64_decode($b['IP']) != $ipNum) {
|
274 |
+
continue;
|
275 |
+
}
|
276 |
+
|
277 |
+
if ($isAuthRequest) {
|
278 |
+
return array('action' => self::WFWAF_BLOCK_WFSN);
|
279 |
+
}
|
280 |
+
|
281 |
+
return array('action' => (empty($b['reason']) ? '' : $b['reason']));
|
282 |
+
}
|
283 |
+
}
|
284 |
+
// End Other Blocks
|
285 |
+
|
286 |
+
return false;
|
287 |
+
}
|
288 |
+
|
289 |
+
public function countryRedirURL($countryBlocks = null) {
|
290 |
+
if (!isset($countryBlocks)) {
|
291 |
+
try {
|
292 |
+
$countryBlocksJSON = wfWAF::getInstance()->getStorageEngine()->getConfig('countryBlocks');
|
293 |
+
}
|
294 |
+
catch (Exception $e) {
|
295 |
+
return false;
|
296 |
+
}
|
297 |
+
}
|
298 |
+
|
299 |
+
$countryBlocks = @wfWAFUtils::json_decode($countryBlocksJSON, true);
|
300 |
+
if (is_array($countryBlocks)) {
|
301 |
+
if ($countryBlocks['action'] == 'redir') {
|
302 |
+
return $countryBlocks['redirURL'];
|
303 |
+
}
|
304 |
+
}
|
305 |
+
return false;
|
306 |
+
}
|
307 |
+
|
308 |
+
public function countryBypassRedirURL($countryBlocks = null) {
|
309 |
+
if (!isset($countryBlocks)) {
|
310 |
+
try {
|
311 |
+
$countryBlocksJSON = wfWAF::getInstance()->getStorageEngine()->getConfig('countryBlocks');
|
312 |
+
}
|
313 |
+
catch (Exception $e) {
|
314 |
+
return false;
|
315 |
+
}
|
316 |
+
}
|
317 |
+
|
318 |
+
$countryBlocks = @wfWAFUtils::json_decode($countryBlocksJSON, true);
|
319 |
+
if (is_array($countryBlocks)) {
|
320 |
+
return $countryBlocks['bypassRedirDest'];
|
321 |
+
}
|
322 |
+
return false;
|
323 |
+
}
|
324 |
+
|
325 |
+
protected function checkForBlockedCountry($countryBlock, $ip, $bareRequestURI) {
|
326 |
+
try {
|
327 |
+
$homeURL = wfWAF::getInstance()->getStorageEngine()->getConfig('homeURL');
|
328 |
+
}
|
329 |
+
catch (Exception $e) {
|
330 |
+
//Do nothing
|
331 |
+
}
|
332 |
+
|
333 |
+
$bareRequestURI = rtrim($bareRequestURI, '/\\');
|
334 |
+
if ($country = $this->ip2Country($ip)) {
|
335 |
+
foreach ($countryBlock['countries'] as $blocked) {
|
336 |
+
if (strtoupper($blocked) == strtoupper($country)) {
|
337 |
+
if ($countryBlock['action'] == 'redir') {
|
338 |
+
$redirURL = $countryBlock['redirURL'];
|
339 |
+
$eRedirHost = wfWAFUtils::extractHostname($redirURL);
|
340 |
+
$isExternalRedir = false;
|
341 |
+
if ($eRedirHost && $homeURL && $eRedirHost != wfWAFUtils::extractHostname($homeURL)) {
|
342 |
+
$isExternalRedir = true;
|
343 |
+
}
|
344 |
+
|
345 |
+
if ((!$isExternalRedir) && rtrim(wfWAFUtils::extractBareURI($redirURL), '/\\') == $bareRequestURI){ //Is this the URI we want to redirect to, then don't block it
|
346 |
+
//Do nothing
|
347 |
+
}
|
348 |
+
else {
|
349 |
+
return array('action' => self::WFWAF_BLOCK_COUNTRY_REDIR);
|
350 |
+
}
|
351 |
+
}
|
352 |
+
else {
|
353 |
+
return array('action' => self::WFWAF_BLOCK_COUNTRY);
|
354 |
+
}
|
355 |
+
}
|
356 |
+
}
|
357 |
+
}
|
358 |
+
|
359 |
+
return false;
|
360 |
+
}
|
361 |
+
|
362 |
+
protected function checkForWhitelisted($ip) {
|
363 |
+
$wordfenceLib = realpath(dirname(__FILE__) . '/../lib');
|
364 |
+
include($wordfenceLib . '/wfIPWhitelist.php'); // defines $wfIPWhitelist
|
365 |
+
foreach ($wfIPWhitelist as $group) {
|
366 |
+
foreach ($group as $subnet) {
|
367 |
+
if ($subnet instanceof wfWAFUserIPRange) { //Not currently reached
|
368 |
+
if ($subnet->isIPInRange($ip)) {
|
369 |
+
return true;
|
370 |
+
}
|
371 |
+
} elseif (wfWAFUtils::subnetContainsIP($subnet, $ip)) {
|
372 |
+
return true;
|
373 |
+
}
|
374 |
+
}
|
375 |
+
}
|
376 |
+
return false;
|
377 |
+
}
|
378 |
+
|
379 |
+
protected function ip2Country($ip){
|
380 |
+
$wordfenceLib = realpath(dirname(__FILE__) . '/../lib');
|
381 |
+
if (!(function_exists('geoip_open') && function_exists('geoip_country_code_by_addr') && function_exists('geoip_country_code_by_addr_v6'))) {
|
382 |
+
require_once(dirname(__FILE__) . '/wfWAFGeoIP.php');
|
383 |
+
}
|
384 |
+
if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) !== false) {
|
385 |
+
$gi = geoip_open($wordfenceLib . "/GeoIPv6.dat", GEOIP_STANDARD);
|
386 |
+
$country = geoip_country_code_by_addr_v6($gi, $ip);
|
387 |
+
} else {
|
388 |
+
$gi = geoip_open($wordfenceLib . "/GeoIP.dat", GEOIP_STANDARD);
|
389 |
+
$country = geoip_country_code_by_addr($gi, $ip);
|
390 |
+
}
|
391 |
+
geoip_close($gi);
|
392 |
+
return $country ? $country : '';
|
393 |
+
}
|
394 |
+
}
|
waf/wfWAFUserIPRange.php
CHANGED
@@ -28,6 +28,15 @@ class wfWAFUserIPRange {
|
|
28 |
|
29 |
// IPv4 range
|
30 |
if (strpos($ip_string, '.') !== false && strpos($ip, '.') !== false) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
31 |
if (preg_match('/\[\d+\-\d+\]/', $ip_string)) {
|
32 |
$IPparts = explode('.', $ip);
|
33 |
$whiteParts = explode('.', $ip_string);
|
@@ -108,25 +117,29 @@ class wfWAFUserIPRange {
|
|
108 |
}
|
109 |
$sql = substr($sql, 0, -5) . ')';
|
110 |
return $sql;
|
111 |
-
|
112 |
-
} else if (strpos($ip_string, ':') !== false
|
113 |
-
$
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
$
|
119 |
-
|
120 |
-
|
121 |
-
$
|
122 |
-
|
123 |
-
|
|
|
|
|
|
|
|
|
124 |
}
|
125 |
-
$sql
|
|
|
126 |
}
|
127 |
-
$sql = substr($sql, 0, -5) . ')';
|
128 |
-
return $sql;
|
129 |
}
|
|
|
130 |
return $wpdb->prepare("($column = %s)", wfWAFUtils::inet_pton($ip_string));
|
131 |
}
|
132 |
|
@@ -221,6 +234,6 @@ class wfWAFUserIPRange {
|
|
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 |
}
|
28 |
|
29 |
// IPv4 range
|
30 |
if (strpos($ip_string, '.') !== false && strpos($ip, '.') !== false) {
|
31 |
+
// IPv4-mapped-IPv6
|
32 |
+
if (preg_match('/:ffff:([^:]+)$/i', $ip_string, $matches)) {
|
33 |
+
$ip_string = $matches[1];
|
34 |
+
}
|
35 |
+
if (preg_match('/:ffff:([^:]+)$/i', $ip, $matches)) {
|
36 |
+
$ip = $matches[1];
|
37 |
+
}
|
38 |
+
|
39 |
+
// Range check
|
40 |
if (preg_match('/\[\d+\-\d+\]/', $ip_string)) {
|
41 |
$IPparts = explode('.', $ip);
|
42 |
$whiteParts = explode('.', $ip_string);
|
117 |
}
|
118 |
$sql = substr($sql, 0, -5) . ')';
|
119 |
return $sql;
|
120 |
+
|
121 |
+
} else if (strpos($ip_string, ':') !== false) {
|
122 |
+
$ip_string = strtolower(self::expandIPv6Range($ip_string));
|
123 |
+
if (preg_match('/\[[a-f0-9]+\-[a-f0-9]+\]/i', $ip_string)) {
|
124 |
+
$whiteParts = explode(':', $ip_string);
|
125 |
+
$sql = '(';
|
126 |
+
|
127 |
+
for ($i = 0; $i <= 7; $i++) {
|
128 |
+
// MySQL can only perform bitwise operations on integers
|
129 |
+
$conv = sprintf('CAST(CONV(HEX(SUBSTR(%s, %d, 8)), 16, 10) as UNSIGNED INTEGER)', $column, $i < 4 ? 1 : 9);
|
130 |
+
$j = 16 * (3 - ($i % 4));
|
131 |
+
if (preg_match('/^\[([a-f0-9]+)\-([a-f0-9]+)\]$/i', $whiteParts[$i], $m)) {
|
132 |
+
$sql .= $wpdb->prepare("$conv >> $j & 0xFFFF BETWEEN 0x%x AND 0x%x", hexdec($m[1]), hexdec($m[2]));
|
133 |
+
} else {
|
134 |
+
$sql .= $wpdb->prepare("$conv >> $j & 0xFFFF = 0x%x", hexdec($whiteParts[$i]));
|
135 |
+
}
|
136 |
+
$sql .= ' AND ';
|
137 |
}
|
138 |
+
$sql = substr($sql, 0, -5) . ')';
|
139 |
+
return $sql;
|
140 |
}
|
|
|
|
|
141 |
}
|
142 |
+
|
143 |
return $wpdb->prepare("($column = %s)", wfWAFUtils::inet_pton($ip_string));
|
144 |
}
|
145 |
|
234 |
* @param string|null $ip_string
|
235 |
*/
|
236 |
public function setIPString($ip_string) {
|
237 |
+
$this->ip_string = strtolower(preg_replace('/[\x{2013}-\x{2015}]/u', '-', $ip_string)); //Replace em-dash, en-dash, and horizontal bar with a regular dash
|
238 |
}
|
239 |
}
|
wordfence.php
CHANGED
@@ -4,14 +4,14 @@ Plugin Name: Wordfence Security
|
|
4 |
Plugin URI: http://www.wordfence.com/
|
5 |
Description: Wordfence Security - Anti-virus, Firewall and Malware Scan
|
6 |
Author: Wordfence
|
7 |
-
Version: 6.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 |
|
4 |
Plugin URI: http://www.wordfence.com/
|
5 |
Description: Wordfence Security - Anti-virus, Firewall and Malware Scan
|
6 |
Author: Wordfence
|
7 |
+
Version: 6.2.3
|
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.3');
|
15 |
define('WORDFENCE_BASENAME', function_exists('plugin_basename') ? plugin_basename(__FILE__) :
|
16 |
basename(dirname(__FILE__)) . '/' . basename(__FILE__));
|
17 |
|