Version Description
- Improvement: Improved the performance of our config table status check.
- Improvement: The IP address of the user activating Wordfence is now used by the breached password check until an admin successfully logs in.
- Improvement: Added several new error displays for scan failures to help diagnose and fix issues.
- Improvement: Added the block duration to alerts generated when an IP is blocked.
- Improvement: A text version of scan results is now included in the activity log email.
- Improvement: The WAF install/uninstall process no longer asks to backup files that do not exist.
- Change: Began a phased rollout of moving brute force queries to be https-only.
- Change: Added the initial deprecation notice for PHP 5.2.
- Change: Suppressed a script tag on the diagnostics page from being output in the email version.
- Fix: Addressed an issue where plugins that return a null user during authentication would cause a PHP notice to be logged.
- Fix: Fixed an issue where plugins that use non-standard version formatting could end up with a inaccurate vulnerability status.
- Fix: Added a workaround for web email clients that erroneously encode some URL characters (e.g., #).
Download this release
Release Info
Developer | wfryan |
Plugin | Wordfence Security – Firewall & Malware Scan |
Version | 7.1.3 |
Comparing to | |
See all releases |
Code changes from version 7.1.2 to 7.1.3
- css/{activity-report-widget.1522855379.css → activity-report-widget.1523983877.css} +0 -0
- css/{diff.1522855379.css → diff.1523983877.css} +0 -0
- css/{dt_table.1522855379.css → dt_table.1523983877.css} +0 -0
- css/{fullLog.1522855379.css → fullLog.1523983877.css} +0 -0
- css/{iptraf.1522855379.css → iptraf.1523983877.css} +0 -0
- css/{jquery-ui-timepicker-addon.1522855379.css → jquery-ui-timepicker-addon.1523983877.css} +0 -0
- css/{jquery-ui.min.1522855379.css → jquery-ui.min.1523983877.css} +0 -0
- css/{jquery-ui.structure.min.1522855379.css → jquery-ui.structure.min.1523983877.css} +0 -0
- css/{jquery-ui.theme.min.1522855379.css → jquery-ui.theme.min.1523983877.css} +0 -0
- css/{main.1522855379.css → main.1523983877.css} +0 -0
- css/{phpinfo.1522855379.css → phpinfo.1523983877.css} +0 -0
- css/{wf-adminbar.1522855379.css → wf-adminbar.1523983877.css} +0 -0
- css/{wf-colorbox.1522855379.css → wf-colorbox.1523983877.css} +0 -0
- css/{wf-font-awesome.1522855379.css → wf-font-awesome.1523983877.css} +0 -0
- css/{wf-ionicons.1522855379.css → wf-ionicons.1523983877.css} +0 -0
- css/{wf-onboarding.1522855379.css → wf-onboarding.1523983877.css} +0 -0
- css/{wfselect2.min.1522855379.css → wfselect2.min.1523983877.css} +0 -0
- css/{wordfenceBox.1522855379.css → wordfenceBox.1523983877.css} +0 -0
- js/{Chart.bundle.min.1522855379.js → Chart.bundle.min.1523983877.js} +0 -0
- js/{admin.1522855379.js → admin.1523983877.js} +13 -2
- js/{admin.ajaxWatcher.1522855379.js → admin.ajaxWatcher.1523983877.js} +0 -0
- js/{admin.liveTraffic.1522855379.js → admin.liveTraffic.1523983877.js} +0 -0
- js/{date.1522855379.js → date.1523983877.js} +0 -0
- js/{jquery-ui-timepicker-addon.1522855379.js → jquery-ui-timepicker-addon.1523983877.js} +0 -0
- js/{jquery.colorbox-min.1522855379.js → jquery.colorbox-min.1523983877.js} +0 -0
- js/{jquery.colorbox.1522855379.js → jquery.colorbox.1523983877.js} +0 -0
- js/{jquery.dataTables.min.1522855379.js → jquery.dataTables.min.1523983877.js} +0 -0
- js/{jquery.qrcode.min.1522855379.js → jquery.qrcode.min.1523983877.js} +0 -0
- js/{jquery.tmpl.min.1522855379.js → jquery.tmpl.min.1523983877.js} +0 -0
- js/{jquery.tools.min.1522855379.js → jquery.tools.min.1523983877.js} +0 -0
- js/{knockout-3.3.0.1522855379.js → knockout-3.3.0.1523983877.js} +0 -0
- js/{perf.1522855379.js → perf.1523983877.js} +0 -0
- js/{wfdashboard.1522855379.js → wfdashboard.1523983877.js} +0 -0
- js/{wfdropdown.1522855379.js → wfdropdown.1523983877.js} +0 -0
- js/{wfglobal.1522855379.js → wfglobal.1523983877.js} +0 -0
- js/{wfpopover.1522855379.js → wfpopover.1523983877.js} +0 -0
- js/{wfselect2.min.1522855379.js → wfselect2.min.1523983877.js} +0 -0
- lib/menu_dashboard_options.php +1 -1
- lib/menu_firewall_blocking_options.php +1 -1
- lib/menu_firewall_waf_options.php +1 -1
- lib/menu_options.php +1 -1
- lib/menu_scanner_options.php +1 -1
- lib/menu_tools_diagnostic.php +2 -0
- lib/wfAPI.php +18 -6
- lib/wfConfig.php +24 -8
- lib/wfCredentialsController.php +20 -2
- lib/wfDiagnostic.php +2 -2
- lib/wfIssues.php +24 -0
- lib/wfLog.php +8 -3
- lib/wfScan.php +109 -65
- lib/wfScanEngine.php +75 -21
- lib/wfSupportController.php +10 -0
- lib/wfUtils.php +0 -39
- lib/wfVersionCheckController.php +291 -0
- lib/wordfenceClass.php +135 -11
- lib/wordfenceConstants.php +2 -0
- readme.txt +16 -1
- views/blocking/block-list.php +1 -1
- views/scanner/issue-base.php +103 -0
- views/scanner/issue-checkGSB.php +6 -0
- views/scanner/issue-checkHowGetIPs.php +4 -0
- views/scanner/issue-checkSpamIP.php +4 -0
- views/scanner/issue-commentBadURL.php +13 -1
- views/scanner/issue-configReadable.php +7 -1
- views/scanner/issue-coreUnknown.php +5 -1
- views/scanner/issue-database.php +7 -0
- views/scanner/issue-diskSpace.php +7 -1
- views/scanner/issue-dnsChange.php +8 -1
- views/scanner/issue-easyPassword.php +9 -1
- views/scanner/issue-file.php +11 -1
- views/scanner/issue-geoipSupport.php +5 -1
- views/scanner/issue-knownfile.php +10 -1
- views/scanner/issue-optionBadURL.php +11 -0
- views/scanner/issue-postBadTitle.php +12 -1
- views/scanner/issue-postBadURL.php +13 -1
- views/scanner/issue-publiclyAccessible.php +7 -1
- views/scanner/issue-spamvertizeCheck.php +4 -0
- views/scanner/issue-suspiciousAdminUsers.php +5 -1
- views/scanner/issue-timelimit.php +5 -1
- views/scanner/issue-wfPluginAbandoned.php +14 -1
- views/scanner/issue-wfPluginRemoved.php +11 -1
- views/scanner/issue-wfPluginUpgrade.php +14 -1
- views/scanner/issue-wfPluginVulnerable.php +12 -1
- views/scanner/issue-wfThemeUpgrade.php +13 -1
- views/scanner/issue-wfUpgrade.php +11 -1
- views/scanner/issue-wpscan_directoryList.php +7 -1
- views/scanner/issue-wpscan_fullPathDiscl.php +7 -1
- views/scanner/scan-failed.php +1 -1
- views/waf/options-group-basic-firewall.php +10 -3
- views/waf/waf-install.php +12 -4
- views/waf/waf-uninstall.php +12 -4
- wordfence.php +3 -3
css/{activity-report-widget.1522855379.css → activity-report-widget.1523983877.css}
RENAMED
File without changes
|
css/{diff.1522855379.css → diff.1523983877.css}
RENAMED
File without changes
|
css/{dt_table.1522855379.css → dt_table.1523983877.css}
RENAMED
File without changes
|
css/{fullLog.1522855379.css → fullLog.1523983877.css}
RENAMED
File without changes
|
css/{iptraf.1522855379.css → iptraf.1523983877.css}
RENAMED
File without changes
|
css/{jquery-ui-timepicker-addon.1522855379.css → jquery-ui-timepicker-addon.1523983877.css}
RENAMED
File without changes
|
css/{jquery-ui.min.1522855379.css → jquery-ui.min.1523983877.css}
RENAMED
File without changes
|
css/{jquery-ui.structure.min.1522855379.css → jquery-ui.structure.min.1523983877.css}
RENAMED
File without changes
|
css/{jquery-ui.theme.min.1522855379.css → jquery-ui.theme.min.1523983877.css}
RENAMED
File without changes
|
css/{main.1522855379.css → main.1523983877.css}
RENAMED
File without changes
|
css/{phpinfo.1522855379.css → phpinfo.1523983877.css}
RENAMED
File without changes
|
css/{wf-adminbar.1522855379.css → wf-adminbar.1523983877.css}
RENAMED
File without changes
|
css/{wf-colorbox.1522855379.css → wf-colorbox.1523983877.css}
RENAMED
File without changes
|
css/{wf-font-awesome.1522855379.css → wf-font-awesome.1523983877.css}
RENAMED
File without changes
|
css/{wf-ionicons.1522855379.css → wf-ionicons.1523983877.css}
RENAMED
File without changes
|
css/{wf-onboarding.1522855379.css → wf-onboarding.1523983877.css}
RENAMED
File without changes
|
css/{wfselect2.min.1522855379.css → wfselect2.min.1523983877.css}
RENAMED
File without changes
|
css/{wordfenceBox.1522855379.css → wordfenceBox.1523983877.css}
RENAMED
File without changes
|
js/{Chart.bundle.min.1522855379.js → Chart.bundle.min.1523983877.js}
RENAMED
File without changes
|
js/{admin.1522855379.js → admin.1523983877.js}
RENAMED
@@ -128,7 +128,7 @@
|
|
128 |
$(window).trigger('wfTabChange', [tab.data('target')]);
|
129 |
});
|
130 |
if (window.location.hash) {
|
131 |
-
var hashes =
|
132 |
var hash = hashes[hashes.length - 1];
|
133 |
for (var i = 0; i < tabs.length; i++) {
|
134 |
if (hash == jQuery(tabs[i]).closest('.wf-tab').data('target')) {
|
@@ -140,7 +140,7 @@
|
|
140 |
jQuery(tabs[0]).trigger('click');
|
141 |
}
|
142 |
jQuery(window).on('hashchange', function () {
|
143 |
-
var hashes =
|
144 |
var hash = hashes[hashes.length - 1];
|
145 |
for (var i = 0; i < tabs.length; i++) {
|
146 |
if (hash == jQuery(tabs[i]).closest('.wf-tab').data('target')) {
|
@@ -2226,6 +2226,17 @@
|
|
2226 |
makeViewOptionLink: function(option, siteID) {
|
2227 |
return WordfenceAdminVars.siteBaseURL + '?_wfsf=viewOption&nonce=' + this.nonce + '&option=' + encodeURIComponent(option) + '&site_id=' + encodeURIComponent(siteID);
|
2228 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2229 |
makeTimeAgo: function(t) {
|
2230 |
var months = Math.floor(t / (86400 * 30));
|
2231 |
var days = Math.floor(t / 86400);
|
128 |
$(window).trigger('wfTabChange', [tab.data('target')]);
|
129 |
});
|
130 |
if (window.location.hash) {
|
131 |
+
var hashes = WFAD.parseHashes();
|
132 |
var hash = hashes[hashes.length - 1];
|
133 |
for (var i = 0; i < tabs.length; i++) {
|
134 |
if (hash == jQuery(tabs[i]).closest('.wf-tab').data('target')) {
|
140 |
jQuery(tabs[0]).trigger('click');
|
141 |
}
|
142 |
jQuery(window).on('hashchange', function () {
|
143 |
+
var hashes = WFAD.parseHashes();
|
144 |
var hash = hashes[hashes.length - 1];
|
145 |
for (var i = 0; i < tabs.length; i++) {
|
146 |
if (hash == jQuery(tabs[i]).closest('.wf-tab').data('target')) {
|
2226 |
makeViewOptionLink: function(option, siteID) {
|
2227 |
return WordfenceAdminVars.siteBaseURL + '?_wfsf=viewOption&nonce=' + this.nonce + '&option=' + encodeURIComponent(option) + '&site_id=' + encodeURIComponent(siteID);
|
2228 |
},
|
2229 |
+
parseHashes: function() {
|
2230 |
+
var hashes = window.location.hash.replace('%23', '#');
|
2231 |
+
var splitHashes = hashes.split('#');
|
2232 |
+
var result = [];
|
2233 |
+
for (var i = 0; i < splitHashes.length; i++) {
|
2234 |
+
if (splitHashes[i].length > 0) {
|
2235 |
+
result.push(splitHashes[i]);
|
2236 |
+
}
|
2237 |
+
}
|
2238 |
+
return result;
|
2239 |
+
},
|
2240 |
makeTimeAgo: function(t) {
|
2241 |
var months = Math.floor(t / (86400 * 30));
|
2242 |
var days = Math.floor(t / 86400);
|
js/{admin.ajaxWatcher.1522855379.js → admin.ajaxWatcher.1523983877.js}
RENAMED
File without changes
|
js/{admin.liveTraffic.1522855379.js → admin.liveTraffic.1523983877.js}
RENAMED
File without changes
|
js/{date.1522855379.js → date.1523983877.js}
RENAMED
File without changes
|
js/{jquery-ui-timepicker-addon.1522855379.js → jquery-ui-timepicker-addon.1523983877.js}
RENAMED
File without changes
|
js/{jquery.colorbox-min.1522855379.js → jquery.colorbox-min.1523983877.js}
RENAMED
File without changes
|
js/{jquery.colorbox.1522855379.js → jquery.colorbox.1523983877.js}
RENAMED
File without changes
|
js/{jquery.dataTables.min.1522855379.js → jquery.dataTables.min.1523983877.js}
RENAMED
File without changes
|
js/{jquery.qrcode.min.1522855379.js → jquery.qrcode.min.1523983877.js}
RENAMED
File without changes
|
js/{jquery.tmpl.min.1522855379.js → jquery.tmpl.min.1523983877.js}
RENAMED
File without changes
|
js/{jquery.tools.min.1522855379.js → jquery.tools.min.1523983877.js}
RENAMED
File without changes
|
js/{knockout-3.3.0.1522855379.js → knockout-3.3.0.1523983877.js}
RENAMED
File without changes
|
js/{perf.1522855379.js → perf.1523983877.js}
RENAMED
File without changes
|
js/{wfdashboard.1522855379.js → wfdashboard.1523983877.js}
RENAMED
File without changes
|
js/{wfdropdown.1522855379.js → wfdropdown.1523983877.js}
RENAMED
File without changes
|
js/{wfglobal.1522855379.js → wfglobal.1523983877.js}
RENAMED
File without changes
|
js/{wfpopover.1522855379.js → wfpopover.1523983877.js}
RENAMED
File without changes
|
js/{wfselect2.min.1522855379.js → wfselect2.min.1523983877.js}
RENAMED
File without changes
|
lib/menu_dashboard_options.php
CHANGED
@@ -12,7 +12,7 @@ $d = new wfDashboard();
|
|
12 |
|
13 |
//Hash-based option block linking
|
14 |
if (window.location.hash) {
|
15 |
-
var hashes =
|
16 |
var hash = hashes[hashes.length - 1];
|
17 |
var block = $('.wf-block[data-persistence-key="' + hash + '"]');
|
18 |
if (block) {
|
12 |
|
13 |
//Hash-based option block linking
|
14 |
if (window.location.hash) {
|
15 |
+
var hashes = WFAD.parseHashes();
|
16 |
var hash = hashes[hashes.length - 1];
|
17 |
var block = $('.wf-block[data-persistence-key="' + hash + '"]');
|
18 |
if (block) {
|
lib/menu_firewall_blocking_options.php
CHANGED
@@ -13,7 +13,7 @@ if (isset($_GET['source']) && wfPage::isValidPage($_GET['source'])) {
|
|
13 |
|
14 |
//Hash-based option block linking
|
15 |
if (window.location.hash) {
|
16 |
-
var hashes =
|
17 |
var hash = hashes[hashes.length - 1];
|
18 |
var block = $('.wf-block[data-persistence-key="' + hash + '"]');
|
19 |
if (block) {
|
13 |
|
14 |
//Hash-based option block linking
|
15 |
if (window.location.hash) {
|
16 |
+
var hashes = WFAD.parseHashes();
|
17 |
var hash = hashes[hashes.length - 1];
|
18 |
var block = $('.wf-block[data-persistence-key="' + hash + '"]');
|
19 |
if (block) {
|
lib/menu_firewall_waf_options.php
CHANGED
@@ -26,7 +26,7 @@ if (isset($_GET['source']) && wfPage::isValidPage($_GET['source'])) {
|
|
26 |
|
27 |
//Hash-based option block linking
|
28 |
if (window.location.hash) {
|
29 |
-
var hashes =
|
30 |
var hash = hashes[hashes.length - 1];
|
31 |
var block = $('.wf-block[data-persistence-key="' + hash + '"]');
|
32 |
if (block.length) {
|
26 |
|
27 |
//Hash-based option block linking
|
28 |
if (window.location.hash) {
|
29 |
+
var hashes = WFAD.parseHashes();
|
30 |
var hash = hashes[hashes.length - 1];
|
31 |
var block = $('.wf-block[data-persistence-key="' + hash + '"]');
|
32 |
if (block.length) {
|
lib/menu_options.php
CHANGED
@@ -27,7 +27,7 @@ if (isset($_GET['source']) && wfPage::isValidPage($_GET['source'])) {
|
|
27 |
|
28 |
//Hash-based option block linking
|
29 |
if (window.location.hash) {
|
30 |
-
var hashes =
|
31 |
var hash = hashes[hashes.length - 1];
|
32 |
var block = $('.wf-block[data-persistence-key="' + hash + '"]');
|
33 |
if (block.length) {
|
27 |
|
28 |
//Hash-based option block linking
|
29 |
if (window.location.hash) {
|
30 |
+
var hashes = WFAD.parseHashes();
|
31 |
var hash = hashes[hashes.length - 1];
|
32 |
var block = $('.wf-block[data-persistence-key="' + hash + '"]');
|
33 |
if (block.length) {
|
lib/menu_scanner_options.php
CHANGED
@@ -15,7 +15,7 @@ if (isset($_GET['source']) && wfPage::isValidPage($_GET['source'])) {
|
|
15 |
|
16 |
//Hash-based option block linking
|
17 |
if (window.location.hash) {
|
18 |
-
var hashes =
|
19 |
var hash = hashes[hashes.length - 1];
|
20 |
var block = $('.wf-block[data-persistence-key="' + hash + '"]');
|
21 |
if (block) {
|
15 |
|
16 |
//Hash-based option block linking
|
17 |
if (window.location.hash) {
|
18 |
+
var hashes = WFAD.parseHashes();
|
19 |
var hash = hashes[hashes.length - 1];
|
20 |
var block = $('.wf-block[data-persistence-key="' + hash + '"]');
|
21 |
if (block) {
|
lib/menu_tools_diagnostic.php
CHANGED
@@ -17,6 +17,7 @@ if (!isset($sendingDiagnosticEmail)) {
|
|
17 |
$sendingDiagnosticEmail = false;
|
18 |
}
|
19 |
?>
|
|
|
20 |
<script type="application/javascript">
|
21 |
(function($) {
|
22 |
$(function() {
|
@@ -24,6 +25,7 @@ if (!isset($sendingDiagnosticEmail)) {
|
|
24 |
});
|
25 |
})(jQuery);
|
26 |
</script>
|
|
|
27 |
<div id="wf-diagnostics">
|
28 |
<?php if (!$sendingDiagnosticEmail): ?>
|
29 |
<div class="wf-diagnostics-wrapper">
|
17 |
$sendingDiagnosticEmail = false;
|
18 |
}
|
19 |
?>
|
20 |
+
<?php if (!$sendingDiagnosticEmail): ?>
|
21 |
<script type="application/javascript">
|
22 |
(function($) {
|
23 |
$(function() {
|
25 |
});
|
26 |
})(jQuery);
|
27 |
</script>
|
28 |
+
<?php endif; ?>
|
29 |
<div id="wf-diagnostics">
|
30 |
<?php if (!$sendingDiagnosticEmail): ?>
|
31 |
<div class="wf-diagnostics-wrapper">
|
lib/wfAPI.php
CHANGED
@@ -27,7 +27,7 @@ class wfAPI {
|
|
27 |
//Sanity check. Developer should call wfAPI::SSLEnabled() to check if SSL is enabled before forcing SSL and return a user friendly msg if it's not.
|
28 |
if ($forceSSL && (!preg_match('/^https:/i', $apiURL))) {
|
29 |
//User's should never see this message unless we aren't calling SSLEnabled() to check if SSL is enabled before using call() with forceSSL
|
30 |
-
throw new
|
31 |
}
|
32 |
$json = $this->getURL(rtrim($apiURL, '/') . '/v' . WORDFENCE_API_VERSION . '/?' . $this->makeAPIQueryString() . '&' . self::buildQuery(
|
33 |
array_merge(
|
@@ -35,7 +35,7 @@ class wfAPI {
|
|
35 |
$getParams
|
36 |
)), $postParams, $timeout);
|
37 |
if (!$json) {
|
38 |
-
throw new
|
39 |
}
|
40 |
|
41 |
$dat = json_decode($json, true);
|
@@ -84,10 +84,10 @@ class wfAPI {
|
|
84 |
}
|
85 |
|
86 |
if (!is_array($dat)) {
|
87 |
-
throw new
|
88 |
}
|
89 |
if (is_array($dat) && isset($dat['errorMsg'])) {
|
90 |
-
throw new
|
91 |
}
|
92 |
return $dat;
|
93 |
}
|
@@ -118,7 +118,7 @@ class wfAPI {
|
|
118 |
|
119 |
if (is_wp_error($response)) {
|
120 |
$error_message = $response->get_error_message();
|
121 |
-
throw new
|
122 |
}
|
123 |
|
124 |
$dateHeader = @$response['headers']['date'];
|
@@ -140,7 +140,7 @@ class wfAPI {
|
|
140 |
}
|
141 |
|
142 |
if (200 != $this->lastHTTPStatus) {
|
143 |
-
throw new
|
144 |
}
|
145 |
|
146 |
$content = wp_remote_retrieve_body($response);
|
@@ -193,3 +193,15 @@ class wfAPI {
|
|
193 |
return wp_http_supports(array('ssl'));
|
194 |
}
|
195 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
27 |
//Sanity check. Developer should call wfAPI::SSLEnabled() to check if SSL is enabled before forcing SSL and return a user friendly msg if it's not.
|
28 |
if ($forceSSL && (!preg_match('/^https:/i', $apiURL))) {
|
29 |
//User's should never see this message unless we aren't calling SSLEnabled() to check if SSL is enabled before using call() with forceSSL
|
30 |
+
throw new wfAPICallSSLUnavailableException("SSL is not supported by your web server and is required to use this function. Please ask your hosting provider or site admin to install cURL with openSSL to use this feature.");
|
31 |
}
|
32 |
$json = $this->getURL(rtrim($apiURL, '/') . '/v' . WORDFENCE_API_VERSION . '/?' . $this->makeAPIQueryString() . '&' . self::buildQuery(
|
33 |
array_merge(
|
35 |
$getParams
|
36 |
)), $postParams, $timeout);
|
37 |
if (!$json) {
|
38 |
+
throw new wfAPICallInvalidResponseException("We received an empty data response from the Wordfence scanning servers when calling the '$action' function.");
|
39 |
}
|
40 |
|
41 |
$dat = json_decode($json, true);
|
84 |
}
|
85 |
|
86 |
if (!is_array($dat)) {
|
87 |
+
throw new wfAPICallInvalidResponseException("We received a data structure that is not the expected array when contacting the Wordfence scanning servers and calling the '$action' function.");
|
88 |
}
|
89 |
if (is_array($dat) && isset($dat['errorMsg'])) {
|
90 |
+
throw new wfAPICallErrorResponseException($dat['errorMsg']);
|
91 |
}
|
92 |
return $dat;
|
93 |
}
|
118 |
|
119 |
if (is_wp_error($response)) {
|
120 |
$error_message = $response->get_error_message();
|
121 |
+
throw new wfAPICallFailedException("There was an " . ($error_message ? '' : 'unknown ') . "error connecting to the Wordfence scanning servers" . ($error_message ? ": $error_message" : '.'));
|
122 |
}
|
123 |
|
124 |
$dateHeader = @$response['headers']['date'];
|
140 |
}
|
141 |
|
142 |
if (200 != $this->lastHTTPStatus) {
|
143 |
+
throw new wfAPICallFailedException("The Wordfence scanning servers are currently unavailable. This may be for maintenance or a temporary outage. If this still occurs in an hour, please contact support. [$this->lastHTTPStatus]");
|
144 |
}
|
145 |
|
146 |
$content = wp_remote_retrieve_body($response);
|
193 |
return wp_http_supports(array('ssl'));
|
194 |
}
|
195 |
}
|
196 |
+
|
197 |
+
class wfAPICallSSLUnavailableException extends Exception {
|
198 |
+
}
|
199 |
+
|
200 |
+
class wfAPICallFailedException extends Exception {
|
201 |
+
}
|
202 |
+
|
203 |
+
class wfAPICallInvalidResponseException extends Exception {
|
204 |
+
}
|
205 |
+
|
206 |
+
class wfAPICallErrorResponseException extends Exception {
|
207 |
+
}
|
lib/wfConfig.php
CHANGED
@@ -1,5 +1,7 @@
|
|
1 |
<?php
|
2 |
class wfConfig {
|
|
|
|
|
3 |
const AUTOLOAD = 'yes';
|
4 |
const DONT_AUTOLOAD = 'no';
|
5 |
|
@@ -290,14 +292,28 @@ class wfConfig {
|
|
290 |
|
291 |
return $options;
|
292 |
}
|
293 |
-
|
294 |
-
|
295 |
-
|
296 |
-
|
297 |
-
|
298 |
-
|
299 |
-
|
300 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
301 |
}
|
302 |
private static function updateCachedOption($name, $val) {
|
303 |
$options = self::loadAllOptions();
|
1 |
<?php
|
2 |
class wfConfig {
|
3 |
+
const TABLE_EXISTS_OPTION = 'wordfence_installed';
|
4 |
+
|
5 |
const AUTOLOAD = 'yes';
|
6 |
const DONT_AUTOLOAD = 'no';
|
7 |
|
292 |
|
293 |
return $options;
|
294 |
}
|
295 |
+
|
296 |
+
/**
|
297 |
+
* Bases the table's existence on the option specified by wfConfig::TABLE_EXISTS_OPTION for performance. We only
|
298 |
+
* set that option just prior to deletion in the uninstall handler and after table creation in the install handler.
|
299 |
+
*/
|
300 |
+
public static function updateTableExists($change = null) {
|
301 |
+
if ($change !== null) {
|
302 |
+
self::$tableExists = !!$change;
|
303 |
+
update_option(wfConfig::TABLE_EXISTS_OPTION, self::$tableExists);
|
304 |
+
return;
|
305 |
+
}
|
306 |
+
|
307 |
+
self::$tableExists = true;
|
308 |
+
$optionValue = get_option(wfConfig::TABLE_EXISTS_OPTION, null);
|
309 |
+
if ($optionValue === null) { //No value, set an initial one
|
310 |
+
global $wpdb;
|
311 |
+
self::updateTableExists(!!$wpdb->get_col($wpdb->prepare('SELECT TABLE_NAME FROM information_schema.TABLES WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME=%s', self::table())));
|
312 |
+
return;
|
313 |
+
}
|
314 |
+
if (!$optionValue) {
|
315 |
+
self::$tableExists = false;
|
316 |
+
}
|
317 |
}
|
318 |
private static function updateCachedOption($name, $val) {
|
319 |
$options = self::loadAllOptions();
|
lib/wfCredentialsController.php
CHANGED
@@ -95,6 +95,13 @@ class wfCredentialsController {
|
|
95 |
delete_transient($key);
|
96 |
}
|
97 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
98 |
public static function hasPreviousLoginFromIP($user, $ip) {
|
99 |
global $wpdb;
|
100 |
$table_wfLogins = wfDB::networkTable('wfLogins');
|
@@ -110,8 +117,19 @@ class wfCredentialsController {
|
|
110 |
}
|
111 |
|
112 |
$lastAdminLogin = wfConfig::get_ser('lastAdminLogin');
|
113 |
-
if (is_array($lastAdminLogin) && isset($lastAdminLogin['userID']) &&
|
114 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
115 |
}
|
116 |
|
117 |
return false;
|
95 |
delete_transient($key);
|
96 |
}
|
97 |
|
98 |
+
/**
|
99 |
+
* Returns whether or not we've seen a successful login from $ip for the given user.
|
100 |
+
*
|
101 |
+
* @param WP_User $user
|
102 |
+
* @param string $ip
|
103 |
+
* @return bool
|
104 |
+
*/
|
105 |
public static function hasPreviousLoginFromIP($user, $ip) {
|
106 |
global $wpdb;
|
107 |
$table_wfLogins = wfDB::networkTable('wfLogins');
|
117 |
}
|
118 |
|
119 |
$lastAdminLogin = wfConfig::get_ser('lastAdminLogin');
|
120 |
+
if (is_array($lastAdminLogin) && isset($lastAdminLogin['userID']) && isset($lastAdminLogin['IP'])) {
|
121 |
+
if ($lastAdminLogin['userID'] == $id && wfUtils::inet_pton($lastAdminLogin['IP']) == wfUtils::inet_pton($ip)) {
|
122 |
+
return true;
|
123 |
+
}
|
124 |
+
return false;
|
125 |
+
}
|
126 |
+
|
127 |
+
//Final check -- if the IP recorded at plugin activation matches, let it through. This is __only__ checked when we don't have any other record of an admin login.
|
128 |
+
$activatingIP = wfConfig::get('activatingIP');
|
129 |
+
if (wfUtils::isValidIP($activatingIP)) {
|
130 |
+
if (wfUtils::inet_pton($activatingIP) == wfUtils::inet_pton($ip)) {
|
131 |
+
return true;
|
132 |
+
}
|
133 |
}
|
134 |
|
135 |
return false;
|
lib/wfDiagnostic.php
CHANGED
@@ -377,9 +377,9 @@ class wfDiagnostic
|
|
377 |
if (!function_exists('openssl_verify') || !defined('OPENSSL_VERSION_NUMBER') || !defined('OPENSSL_VERSION_TEXT')) {
|
378 |
return false;
|
379 |
}
|
380 |
-
$compare =
|
381 |
return array(
|
382 |
-
'test' => $compare
|
383 |
'message' => OPENSSL_VERSION_TEXT,
|
384 |
);
|
385 |
}
|
377 |
if (!function_exists('openssl_verify') || !defined('OPENSSL_VERSION_NUMBER') || !defined('OPENSSL_VERSION_TEXT')) {
|
378 |
return false;
|
379 |
}
|
380 |
+
$compare = wfVersionCheckController::shared()->checkOpenSSLVersion();
|
381 |
return array(
|
382 |
+
'test' => $compare == wfVersionCheckController::VERSION_COMPATIBLE,
|
383 |
'message' => OPENSSL_VERSION_TEXT,
|
384 |
);
|
385 |
}
|
lib/wfIssues.php
CHANGED
@@ -28,6 +28,13 @@ class wfIssues {
|
|
28 |
const SCAN_FAILED_DURATION_REACHED = 'duration';
|
29 |
const SCAN_FAILED_VERSION_CHANGE = 'versionchange';
|
30 |
const SCAN_FAILED_FORK_FAILED = 'forkfailed';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
31 |
|
32 |
private $db = false;
|
33 |
|
@@ -42,6 +49,10 @@ class wfIssues {
|
|
42 |
public $totalWarningIssues = 0;
|
43 |
public $totalIgnoredIssues = 0;
|
44 |
|
|
|
|
|
|
|
|
|
45 |
public static function statusPrep(){
|
46 |
wfConfig::set_ser('wfStatusStartMsgs', array());
|
47 |
wordfence::status(10, 'info', "SUM_PREP:Preparing a new scan.");
|
@@ -125,12 +136,22 @@ class wfIssues {
|
|
125 |
}
|
126 |
}
|
127 |
|
|
|
|
|
|
|
|
|
|
|
128 |
$recordedFailure = wfConfig::get('lastScanFailureType');
|
129 |
switch ($recordedFailure) {
|
130 |
case self::SCAN_FAILED_GENERAL:
|
131 |
case self::SCAN_FAILED_DURATION_REACHED:
|
132 |
case self::SCAN_FAILED_VERSION_CHANGE:
|
133 |
case self::SCAN_FAILED_FORK_FAILED:
|
|
|
|
|
|
|
|
|
|
|
134 |
return $recordedFailure;
|
135 |
}
|
136 |
|
@@ -437,6 +458,9 @@ class wfIssues {
|
|
437 |
}
|
438 |
}
|
439 |
$issueList[$i]['issueIDX'] = $i;
|
|
|
|
|
|
|
440 |
}
|
441 |
}
|
442 |
return $ret; //array of lists of issues by status
|
28 |
const SCAN_FAILED_DURATION_REACHED = 'duration';
|
29 |
const SCAN_FAILED_VERSION_CHANGE = 'versionchange';
|
30 |
const SCAN_FAILED_FORK_FAILED = 'forkfailed';
|
31 |
+
const SCAN_FAILED_CALLBACK_TEST_FAILED = 'callbackfailed';
|
32 |
+
const SCAN_FAILED_START_TIMEOUT = 'starttimeout';
|
33 |
+
|
34 |
+
const SCAN_FAILED_API_SSL_UNAVAILABLE = 'sslunavailable';
|
35 |
+
const SCAN_FAILED_API_CALL_FAILED = 'apifailed';
|
36 |
+
const SCAN_FAILED_API_INVALID_RESPONSE = 'apiinvalid';
|
37 |
+
const SCAN_FAILED_API_ERROR_RESPONSE = 'apierror';
|
38 |
|
39 |
private $db = false;
|
40 |
|
49 |
public $totalWarningIssues = 0;
|
50 |
public $totalIgnoredIssues = 0;
|
51 |
|
52 |
+
public static function validIssueTypes() {
|
53 |
+
return array('checkHowGetIPs', 'checkSpamIP', 'commentBadURL', 'configReadable', 'coreUnknown', 'database', 'diskSpace', 'dnsChange', 'easyPassword', 'file', 'geoipSupport', 'knownfile', 'optionBadURL', 'postBadTitle', 'postBadURL', 'publiclyAccessible', 'spamvertizeCheck', 'suspiciousAdminUsers', 'timelimit', 'wfPluginAbandoned', 'wfPluginRemoved', 'wfPluginUpgrade', 'wfPluginVulnerable', 'wfThemeUpgrade', 'wfUpgrade', 'wpscan_directoryList', 'wpscan_fullPathDiscl');
|
54 |
+
}
|
55 |
+
|
56 |
public static function statusPrep(){
|
57 |
wfConfig::set_ser('wfStatusStartMsgs', array());
|
58 |
wordfence::status(10, 'info', "SUM_PREP:Preparing a new scan.");
|
136 |
}
|
137 |
}
|
138 |
|
139 |
+
$scanStartAttempt = wfConfig::get('scanStartAttempt', 0);
|
140 |
+
if ($scanStartAttempt && time() - $scanStartAttempt > WORDFENCE_SCAN_START_FAILURE_THRESHOLD) {
|
141 |
+
return self::SCAN_FAILED_START_TIMEOUT;
|
142 |
+
}
|
143 |
+
|
144 |
$recordedFailure = wfConfig::get('lastScanFailureType');
|
145 |
switch ($recordedFailure) {
|
146 |
case self::SCAN_FAILED_GENERAL:
|
147 |
case self::SCAN_FAILED_DURATION_REACHED:
|
148 |
case self::SCAN_FAILED_VERSION_CHANGE:
|
149 |
case self::SCAN_FAILED_FORK_FAILED:
|
150 |
+
case self::SCAN_FAILED_CALLBACK_TEST_FAILED:
|
151 |
+
case self::SCAN_FAILED_API_SSL_UNAVAILABLE:
|
152 |
+
case self::SCAN_FAILED_API_CALL_FAILED:
|
153 |
+
case self::SCAN_FAILED_API_INVALID_RESPONSE:
|
154 |
+
case self::SCAN_FAILED_API_ERROR_RESPONSE:
|
155 |
return $recordedFailure;
|
156 |
}
|
157 |
|
458 |
}
|
459 |
}
|
460 |
$issueList[$i]['issueIDX'] = $i;
|
461 |
+
if (isset($issueList[$i]['data']['cType'])) {
|
462 |
+
$issueList[$i]['data']['ucType'] = ucwords($issueList[$i]['data']['cType']);
|
463 |
+
}
|
464 |
}
|
465 |
}
|
466 |
return $ret; //array of lists of issues by status
|
lib/wfLog.php
CHANGED
@@ -686,16 +686,21 @@ class wfLog {
|
|
686 |
$this->tagRequestForBlock($reason);
|
687 |
|
688 |
if (wfConfig::get('alertOn_block')) {
|
689 |
-
|
|
|
|
|
|
|
|
|
|
|
690 |
}
|
691 |
-
wordfence::status(2, 'info',
|
692 |
}
|
693 |
else if ($action == 'throttle') { //Rate limited - throttle
|
694 |
$secsToGo = wfBlock::rateLimitThrottleDuration();
|
695 |
wfBlock::createRateThrottle($reason, $IP, $secsToGo);
|
696 |
wfActivityReport::logBlockedIP($IP, null, 'throttle');
|
697 |
|
698 |
-
wordfence::status(2, 'info',
|
699 |
wfConfig::inc('totalIPsThrottled');
|
700 |
}
|
701 |
$this->do503($secsToGo, $reason);
|
686 |
$this->tagRequestForBlock($reason);
|
687 |
|
688 |
if (wfConfig::get('alertOn_block')) {
|
689 |
+
$message = sprintf(__('Wordfence has blocked IP address %s.', 'wordfence'), $IP) . "\n";
|
690 |
+
$message .= sprintf(__('The reason is: "%s".', 'wordfence'), $reason);
|
691 |
+
if ($secsToGo > 0) {
|
692 |
+
$message .= "\n" . sprintf(__('The duration of the block is %s.', 'wordfence'), wfUtils::makeDuration($secsToGo, true));
|
693 |
+
}
|
694 |
+
wordfence::alert(sprintf(__('Blocking IP %s', 'wordfence'), $IP), $message, $IP);
|
695 |
}
|
696 |
+
wordfence::status(2, 'info', sprintf(__('Blocking IP %s. %s', 'wordfence'), $IP, $reason));
|
697 |
}
|
698 |
else if ($action == 'throttle') { //Rate limited - throttle
|
699 |
$secsToGo = wfBlock::rateLimitThrottleDuration();
|
700 |
wfBlock::createRateThrottle($reason, $IP, $secsToGo);
|
701 |
wfActivityReport::logBlockedIP($IP, null, 'throttle');
|
702 |
|
703 |
+
wordfence::status(2, 'info', sprintf(__('Throttling IP %s. %s', 'wordfence'), $IP, $reason));
|
704 |
wfConfig::inc('totalIPsThrottled');
|
705 |
}
|
706 |
$this->do503($secsToGo, $reason);
|
lib/wfScan.php
CHANGED
@@ -54,6 +54,7 @@ class wfScan {
|
|
54 |
}
|
55 |
$scanController = new wfScanner($scanMode);
|
56 |
|
|
|
57 |
$isFork = ($_GET['isFork'] == '1' ? true : false);
|
58 |
|
59 |
if(! $isFork){
|
@@ -82,85 +83,88 @@ class wfScan {
|
|
82 |
@error_reporting(E_ALL);
|
83 |
wfUtils::iniSet('display_errors','On');
|
84 |
self::status(4, 'info', "Setting up scanRunning and starting scan");
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
$delay = -1;
|
102 |
-
$isScheduled = false;
|
103 |
-
$originalScanStart = wfConfig::get('originalScheduledScanStart', 0);
|
104 |
-
$lastScanStart = wfConfig::get('lastScheduledScanStart', 0);
|
105 |
-
$minimumFrequency = ($scanController->schedulingMode() == wfScanner::SCAN_SCHEDULING_MODE_MANUAL ? 1800 : 43200);
|
106 |
-
if ($lastScanStart && (time() - $lastScanStart) < $minimumFrequency) {
|
107 |
-
$isScheduled = true;
|
108 |
-
|
109 |
-
if ($originalScanStart > 0) {
|
110 |
-
$delay = max($lastScanStart - $originalScanStart, 0);
|
111 |
}
|
112 |
}
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
if ($scanController->schedulingMode() == wfScanner::SCAN_SCHEDULING_MODE_AUTOMATIC && $isScheduled) {
|
126 |
-
if (isset($response['defer'])) {
|
127 |
-
$defer = (int) $response['defer'];
|
128 |
-
wordfence::status(2, 'info', "Deferring scheduled scan by " . wfUtils::makeDuration($defer));
|
129 |
-
wfConfig::set('lastScheduledScanStart', 0);
|
130 |
-
wfConfig::set('lastScanCompleted', 'ok');
|
131 |
-
wfConfig::set('lastScanFailureType', false);
|
132 |
-
wfConfig::set_ser('wfStatusStartMsgs', array());
|
133 |
-
$scanController->recordLastScanTime();
|
134 |
-
$i = new wfIssues();
|
135 |
-
wfScanEngine::refreshScanNotification($i);
|
136 |
-
wfScanner::shared()->scheduleSingleScan(time() + $defer, $originalScanStart);
|
137 |
-
wfUtils::clearScanLock();
|
138 |
-
exit();
|
139 |
}
|
140 |
}
|
141 |
|
142 |
-
|
143 |
-
$
|
|
|
144 |
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
151 |
}
|
152 |
-
|
153 |
-
try {
|
154 |
$scan->go();
|
155 |
}
|
156 |
-
catch (wfScanEngineDurationLimitException $e) {
|
157 |
wfUtils::clearScanLock();
|
158 |
$peakMemory = self::logPeakMemory();
|
159 |
self::status(2, 'info', "Wordfence used " . wfUtils::formatBytes($peakMemory - self::$peakMemAtStart) . " of memory for scan. Server peak memory usage was: " . wfUtils::formatBytes($peakMemory));
|
160 |
self::status(2, 'error', "Scan terminated with error: " . $e->getMessage());
|
161 |
exit();
|
162 |
}
|
163 |
-
catch (wfScanEngineCoreVersionChangeException $e) {
|
164 |
wfUtils::clearScanLock();
|
165 |
$peakMemory = self::logPeakMemory();
|
166 |
self::status(2, 'info', "Wordfence used " . wfUtils::formatBytes($peakMemory - self::$peakMemAtStart) . " of memory for scan. Server peak memory usage was: " . wfUtils::formatBytes($peakMemory));
|
@@ -175,7 +179,47 @@ class wfScan {
|
|
175 |
|
176 |
exit();
|
177 |
}
|
178 |
-
catch (
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
179 |
wfUtils::clearScanLock();
|
180 |
self::status(2, 'error', "Scan terminated with error: " . $e->getMessage());
|
181 |
self::status(10, 'info', "SUM_KILLED:Previous scan terminated with an error. See below.");
|
54 |
}
|
55 |
$scanController = new wfScanner($scanMode);
|
56 |
|
57 |
+
wfConfig::remove('scanStartAttempt');
|
58 |
$isFork = ($_GET['isFork'] == '1' ? true : false);
|
59 |
|
60 |
if(! $isFork){
|
83 |
@error_reporting(E_ALL);
|
84 |
wfUtils::iniSet('display_errors','On');
|
85 |
self::status(4, 'info', "Setting up scanRunning and starting scan");
|
86 |
+
try {
|
87 |
+
if ($isFork) {
|
88 |
+
$scan = wfConfig::get_ser('wfsd_engine', false, false);
|
89 |
+
if ($scan) {
|
90 |
+
self::status(4, 'info', "Got a true deserialized value back from 'wfsd_engine' with type: " . gettype($scan));
|
91 |
+
wfConfig::set('wfsd_engine', '', wfConfig::DONT_AUTOLOAD);
|
92 |
+
}
|
93 |
+
else {
|
94 |
+
self::status(2, 'error', "Scan can't continue - stored data not found after a fork. Got type: " . gettype($scan));
|
95 |
+
wfConfig::set('wfsd_engine', '', wfConfig::DONT_AUTOLOAD);
|
96 |
+
wfConfig::set('lastScanCompleted', __('Scan can\'t continue - stored data not found after a fork.', 'wordfence'));
|
97 |
+
wfConfig::set('lastScanFailureType', wfIssues::SCAN_FAILED_FORK_FAILED);
|
98 |
+
wfUtils::clearScanLock();
|
99 |
+
self::status(2, 'error', "Scan terminated with error: " . __('Scan can\'t continue - stored data not found after a fork.', 'wordfence'));
|
100 |
+
self::status(10, 'info', "SUM_KILLED:Previous scan terminated with an error. See below.");
|
101 |
+
exit();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
102 |
}
|
103 |
}
|
104 |
+
else {
|
105 |
+
$delay = -1;
|
106 |
+
$isScheduled = false;
|
107 |
+
$originalScanStart = wfConfig::get('originalScheduledScanStart', 0);
|
108 |
+
$lastScanStart = wfConfig::get('lastScheduledScanStart', 0);
|
109 |
+
$minimumFrequency = ($scanController->schedulingMode() == wfScanner::SCAN_SCHEDULING_MODE_MANUAL ? 1800 : 43200);
|
110 |
+
if ($lastScanStart && (time() - $lastScanStart) < $minimumFrequency) {
|
111 |
+
$isScheduled = true;
|
112 |
+
|
113 |
+
if ($originalScanStart > 0) {
|
114 |
+
$delay = max($lastScanStart - $originalScanStart, 0);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
115 |
}
|
116 |
}
|
117 |
|
118 |
+
wfIssues::statusPrep(); //Re-initializes all status counters
|
119 |
+
$scanController->resetStages();
|
120 |
+
$scanController->resetSummaryItems();
|
121 |
|
122 |
+
if ($scanMode != wfScanner::SCAN_TYPE_QUICK) {
|
123 |
+
wordfence::status(1, 'info', "Contacting Wordfence to initiate scan");
|
124 |
+
$wp_version = wfUtils::getWPVersion();
|
125 |
+
$apiKey = wfConfig::get('apiKey');
|
126 |
+
$api = new wfAPI($apiKey, $wp_version);
|
127 |
+
$response = $api->call('log_scan', array(), array('delay' => $delay, 'scheduled' => (int) $isScheduled, 'mode' => wfConfig::get('schedMode')/*, 'forcedefer' => 1*/));
|
128 |
+
|
129 |
+
if ($scanController->schedulingMode() == wfScanner::SCAN_SCHEDULING_MODE_AUTOMATIC && $isScheduled) {
|
130 |
+
if (isset($response['defer'])) {
|
131 |
+
$defer = (int) $response['defer'];
|
132 |
+
wordfence::status(2, 'info', "Deferring scheduled scan by " . wfUtils::makeDuration($defer));
|
133 |
+
wfConfig::set('lastScheduledScanStart', 0);
|
134 |
+
wfConfig::set('lastScanCompleted', 'ok');
|
135 |
+
wfConfig::set('lastScanFailureType', false);
|
136 |
+
wfConfig::set_ser('wfStatusStartMsgs', array());
|
137 |
+
$scanController->recordLastScanTime();
|
138 |
+
$i = new wfIssues();
|
139 |
+
wfScanEngine::refreshScanNotification($i);
|
140 |
+
wfScanner::shared()->scheduleSingleScan(time() + $defer, $originalScanStart);
|
141 |
+
wfUtils::clearScanLock();
|
142 |
+
exit();
|
143 |
+
}
|
144 |
+
}
|
145 |
+
|
146 |
+
$malwarePrefixesHash = (isset($response['malwarePrefixes']) ? $response['malwarePrefixes'] : '');
|
147 |
+
$coreHashesHash = (isset($response['coreHashes']) ? $response['coreHashes'] : '');
|
148 |
+
|
149 |
+
$scan = new wfScanEngine($malwarePrefixesHash, $coreHashesHash, $scanMode);
|
150 |
+
$scan->deleteNewIssues();
|
151 |
+
}
|
152 |
+
else {
|
153 |
+
wordfence::status(1, 'info', "Initiating quick scan");
|
154 |
+
$scan = new wfScanEngine('', '', $scanMode);
|
155 |
+
}
|
156 |
}
|
157 |
+
|
|
|
158 |
$scan->go();
|
159 |
}
|
160 |
+
catch (wfScanEngineDurationLimitException $e) { //User error set in wfScanEngine
|
161 |
wfUtils::clearScanLock();
|
162 |
$peakMemory = self::logPeakMemory();
|
163 |
self::status(2, 'info', "Wordfence used " . wfUtils::formatBytes($peakMemory - self::$peakMemAtStart) . " of memory for scan. Server peak memory usage was: " . wfUtils::formatBytes($peakMemory));
|
164 |
self::status(2, 'error', "Scan terminated with error: " . $e->getMessage());
|
165 |
exit();
|
166 |
}
|
167 |
+
catch (wfScanEngineCoreVersionChangeException $e) { //User error set in wfScanEngine
|
168 |
wfUtils::clearScanLock();
|
169 |
$peakMemory = self::logPeakMemory();
|
170 |
self::status(2, 'info', "Wordfence used " . wfUtils::formatBytes($peakMemory - self::$peakMemAtStart) . " of memory for scan. Server peak memory usage was: " . wfUtils::formatBytes($peakMemory));
|
179 |
|
180 |
exit();
|
181 |
}
|
182 |
+
catch (wfAPICallSSLUnavailableException $e) {
|
183 |
+
wfConfig::set('lastScanCompleted', $e->getMessage());
|
184 |
+
wfConfig::set('lastScanFailureType', wfIssues::SCAN_FAILED_API_SSL_UNAVAILABLE);
|
185 |
+
|
186 |
+
wfUtils::clearScanLock();
|
187 |
+
$peakMemory = self::logPeakMemory();
|
188 |
+
self::status(2, 'info', "Wordfence used " . wfUtils::formatBytes($peakMemory - self::$peakMemAtStart) . " of memory for scan. Server peak memory usage was: " . wfUtils::formatBytes($peakMemory));
|
189 |
+
self::status(2, 'error', "Scan terminated with error: " . $e->getMessage());
|
190 |
+
exit();
|
191 |
+
}
|
192 |
+
catch (wfAPICallFailedException $e) {
|
193 |
+
wfConfig::set('lastScanCompleted', $e->getMessage());
|
194 |
+
wfConfig::set('lastScanFailureType', wfIssues::SCAN_FAILED_API_CALL_FAILED);
|
195 |
+
|
196 |
+
wfUtils::clearScanLock();
|
197 |
+
$peakMemory = self::logPeakMemory();
|
198 |
+
self::status(2, 'info', "Wordfence used " . wfUtils::formatBytes($peakMemory - self::$peakMemAtStart) . " of memory for scan. Server peak memory usage was: " . wfUtils::formatBytes($peakMemory));
|
199 |
+
self::status(2, 'error', "Scan terminated with error: " . $e->getMessage());
|
200 |
+
exit();
|
201 |
+
}
|
202 |
+
catch (wfAPICallInvalidResponseException $e) {
|
203 |
+
wfConfig::set('lastScanCompleted', $e->getMessage());
|
204 |
+
wfConfig::set('lastScanFailureType', wfIssues::SCAN_FAILED_API_INVALID_RESPONSE);
|
205 |
+
|
206 |
+
wfUtils::clearScanLock();
|
207 |
+
$peakMemory = self::logPeakMemory();
|
208 |
+
self::status(2, 'info', "Wordfence used " . wfUtils::formatBytes($peakMemory - self::$peakMemAtStart) . " of memory for scan. Server peak memory usage was: " . wfUtils::formatBytes($peakMemory));
|
209 |
+
self::status(2, 'error', "Scan terminated with error: " . $e->getMessage());
|
210 |
+
exit();
|
211 |
+
}
|
212 |
+
catch (wfAPICallErrorResponseException $e) {
|
213 |
+
wfConfig::set('lastScanCompleted', $e->getMessage());
|
214 |
+
wfConfig::set('lastScanFailureType', wfIssues::SCAN_FAILED_API_ERROR_RESPONSE);
|
215 |
+
|
216 |
+
wfUtils::clearScanLock();
|
217 |
+
$peakMemory = self::logPeakMemory();
|
218 |
+
self::status(2, 'info', "Wordfence used " . wfUtils::formatBytes($peakMemory - self::$peakMemAtStart) . " of memory for scan. Server peak memory usage was: " . wfUtils::formatBytes($peakMemory));
|
219 |
+
self::status(2, 'error', "Scan terminated with error: " . $e->getMessage());
|
220 |
+
exit();
|
221 |
+
}
|
222 |
+
catch (Exception $e) {
|
223 |
wfUtils::clearScanLock();
|
224 |
self::status(2, 'error', "Scan terminated with error: " . $e->getMessage());
|
225 |
self::status(10, 'info', "SUM_KILLED:Previous scan terminated with an error. See below.");
|
lib/wfScanEngine.php
CHANGED
@@ -230,6 +230,19 @@ class wfScanEngine {
|
|
230 |
wfScanEngine::refreshScanNotification($this->i);
|
231 |
throw $e;
|
232 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
233 |
catch (Exception $e) {
|
234 |
if ($e->getCode() != wfScanEngine::SCAN_MANUALLY_KILLED) {
|
235 |
wfConfig::set('lastScanCompleted', $e->getMessage());
|
@@ -1950,43 +1963,82 @@ class wfScanEngine {
|
|
1950 |
}
|
1951 |
$timeout = self::getMaxExecutionTime() - 2; //2 seconds shorter than max execution time which ensures that only 2 HTTP processes are ever occupied
|
1952 |
$testURL = admin_url('admin-ajax.php?action=wordfence_testAjax');
|
1953 |
-
if(!
|
1954 |
-
|
1955 |
-
|
1956 |
-
|
1957 |
-
|
1958 |
-
|
|
|
1959 |
));
|
|
|
|
|
|
|
|
|
|
|
1960 |
wordfence::status(4, 'info', "Test result of scan start URL fetch: " . var_export($testResult, true));
|
1961 |
}
|
|
|
1962 |
$cronKey = wfUtils::bigRandomHex();
|
1963 |
wfConfig::set('currentCronKey', time() . ',' . $cronKey);
|
1964 |
-
if
|
1965 |
//ajax requests can be sent by the server to itself
|
1966 |
$cronURL = 'admin-ajax.php?action=wordfence_doScan&isFork=' . ($isFork ? '1' : '0') . '&scanMode=' . $scanMode . '&cronKey=' . $cronKey;
|
1967 |
$cronURL = admin_url($cronURL);
|
1968 |
$headers = array('Referer' => false/*, 'Cookie' => 'XDEBUG_SESSION=1'*/);
|
1969 |
wordfence::status(4, 'info', "Starting cron with normal ajax at URL $cronURL");
|
1970 |
-
|
1971 |
-
|
1972 |
-
'
|
1973 |
-
|
1974 |
-
|
1975 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1976 |
wordfence::status(4, 'info', "Scan process ended after forking.");
|
1977 |
-
}
|
|
|
1978 |
$cronURL = admin_url('admin-ajax.php');
|
1979 |
$cronURL = preg_replace('/^(https?:\/\/)/i', '$1noc1.wordfence.com/scanp/', $cronURL);
|
1980 |
$cronURL .= '?action=wordfence_doScan&isFork=' . ($isFork ? '1' : '0') . '&scanMode=' . $scanMode . '&cronKey=' . $cronKey;
|
1981 |
$headers = array();
|
1982 |
wordfence::status(4, 'info', "Starting cron via proxy at URL $cronURL");
|
1983 |
-
|
1984 |
-
|
1985 |
-
'
|
1986 |
-
|
1987 |
-
|
1988 |
-
|
1989 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1990 |
wordfence::status(4, 'info', "Scan process ended after forking.");
|
1991 |
}
|
1992 |
return false; //No error
|
@@ -2442,3 +2494,5 @@ class wfScanEngineDurationLimitException extends Exception {
|
|
2442 |
|
2443 |
class wfScanEngineCoreVersionChangeException extends Exception {
|
2444 |
}
|
|
|
|
230 |
wfScanEngine::refreshScanNotification($this->i);
|
231 |
throw $e;
|
232 |
}
|
233 |
+
catch (wfScanEngineTestCallbackFailedException $e) {
|
234 |
+
wfConfig::set('lastScanCompleted', $e->getMessage());
|
235 |
+
wfConfig::set('lastScanFailureType', wfIssues::SCAN_FAILED_CALLBACK_TEST_FAILED);
|
236 |
+
$this->scanController->recordLastScanTime();
|
237 |
+
|
238 |
+
$this->recordMetric('scan', 'duration', (time() - $this->startTime));
|
239 |
+
$this->recordMetric('scan', 'memory', wfConfig::get('wfPeakMemory', 0, false));
|
240 |
+
$this->recordMetric('scan', 'failure', $e->getMessage());
|
241 |
+
$this->submitMetrics();
|
242 |
+
|
243 |
+
wfScanEngine::refreshScanNotification($this->i);
|
244 |
+
throw $e;
|
245 |
+
}
|
246 |
catch (Exception $e) {
|
247 |
if ($e->getCode() != wfScanEngine::SCAN_MANUALLY_KILLED) {
|
248 |
wfConfig::set('lastScanCompleted', $e->getMessage());
|
1963 |
}
|
1964 |
$timeout = self::getMaxExecutionTime() - 2; //2 seconds shorter than max execution time which ensures that only 2 HTTP processes are ever occupied
|
1965 |
$testURL = admin_url('admin-ajax.php?action=wordfence_testAjax');
|
1966 |
+
if (!wfConfig::get('startScansRemotely', false)) {
|
1967 |
+
try {
|
1968 |
+
$testResult = wp_remote_post($testURL, array(
|
1969 |
+
'timeout' => $timeout,
|
1970 |
+
'blocking' => true,
|
1971 |
+
'sslverify' => false,
|
1972 |
+
'headers' => array()
|
1973 |
));
|
1974 |
+
}
|
1975 |
+
catch (Exception $e) {
|
1976 |
+
//Fall through to the remote start test below
|
1977 |
+
}
|
1978 |
+
|
1979 |
wordfence::status(4, 'info', "Test result of scan start URL fetch: " . var_export($testResult, true));
|
1980 |
}
|
1981 |
+
|
1982 |
$cronKey = wfUtils::bigRandomHex();
|
1983 |
wfConfig::set('currentCronKey', time() . ',' . $cronKey);
|
1984 |
+
if ((!wfConfig::get('startScansRemotely', false)) && (!is_wp_error($testResult)) && (is_array($testResult) || $testResult instanceof ArrayAccess) && strstr($testResult['body'], 'WFSCANTESTOK') !== false) {
|
1985 |
//ajax requests can be sent by the server to itself
|
1986 |
$cronURL = 'admin-ajax.php?action=wordfence_doScan&isFork=' . ($isFork ? '1' : '0') . '&scanMode=' . $scanMode . '&cronKey=' . $cronKey;
|
1987 |
$cronURL = admin_url($cronURL);
|
1988 |
$headers = array('Referer' => false/*, 'Cookie' => 'XDEBUG_SESSION=1'*/);
|
1989 |
wordfence::status(4, 'info', "Starting cron with normal ajax at URL $cronURL");
|
1990 |
+
|
1991 |
+
try {
|
1992 |
+
wfConfig::set('scanStartAttempt', time());
|
1993 |
+
$response = wp_remote_get($cronURL, array(
|
1994 |
+
'timeout' => 0.01,
|
1995 |
+
'blocking' => false,
|
1996 |
+
'sslverify' => false,
|
1997 |
+
'headers' => $headers
|
1998 |
+
));
|
1999 |
+
}
|
2000 |
+
catch (Exception $e) {
|
2001 |
+
wfConfig::set('lastScanCompleted', $e->getMessage());
|
2002 |
+
wfConfig::set('lastScanFailureType', wfIssues::SCAN_FAILED_CALLBACK_TEST_FAILED);
|
2003 |
+
return false;
|
2004 |
+
}
|
2005 |
+
|
2006 |
+
if (is_wp_error($response)) {
|
2007 |
+
$error_message = $response->get_error_message();
|
2008 |
+
wfConfig::set('lastScanCompleted', "There was an " . ($error_message ? '' : 'unknown ') . "error starting the scan" . ($error_message ? ": $error_message" : '.'));
|
2009 |
+
wfConfig::set('lastScanFailureType', wfIssues::SCAN_FAILED_CALLBACK_TEST_FAILED);
|
2010 |
+
}
|
2011 |
+
|
2012 |
wordfence::status(4, 'info', "Scan process ended after forking.");
|
2013 |
+
}
|
2014 |
+
else {
|
2015 |
$cronURL = admin_url('admin-ajax.php');
|
2016 |
$cronURL = preg_replace('/^(https?:\/\/)/i', '$1noc1.wordfence.com/scanp/', $cronURL);
|
2017 |
$cronURL .= '?action=wordfence_doScan&isFork=' . ($isFork ? '1' : '0') . '&scanMode=' . $scanMode . '&cronKey=' . $cronKey;
|
2018 |
$headers = array();
|
2019 |
wordfence::status(4, 'info', "Starting cron via proxy at URL $cronURL");
|
2020 |
+
|
2021 |
+
try {
|
2022 |
+
wfConfig::set('scanStartAttempt', time());
|
2023 |
+
$response = wp_remote_get($cronURL, array(
|
2024 |
+
'timeout' => 0.01,
|
2025 |
+
'blocking' => false,
|
2026 |
+
'sslverify' => false,
|
2027 |
+
'headers' => $headers
|
2028 |
+
));
|
2029 |
+
}
|
2030 |
+
catch (Exception $e) {
|
2031 |
+
wfConfig::set('lastScanCompleted', $e->getMessage());
|
2032 |
+
wfConfig::set('lastScanFailureType', wfIssues::SCAN_FAILED_CALLBACK_TEST_FAILED);
|
2033 |
+
return false;
|
2034 |
+
}
|
2035 |
+
|
2036 |
+
if (is_wp_error($response)) {
|
2037 |
+
$error_message = $response->get_error_message();
|
2038 |
+
wfConfig::set('lastScanCompleted', "There was an " . ($error_message ? '' : 'unknown ') . "error starting the scan" . ($error_message ? ": $error_message" : '.'));
|
2039 |
+
wfConfig::set('lastScanFailureType', wfIssues::SCAN_FAILED_CALLBACK_TEST_FAILED);
|
2040 |
+
}
|
2041 |
+
|
2042 |
wordfence::status(4, 'info', "Scan process ended after forking.");
|
2043 |
}
|
2044 |
return false; //No error
|
2494 |
|
2495 |
class wfScanEngineCoreVersionChangeException extends Exception {
|
2496 |
}
|
2497 |
+
class wfScanEngineTestCallbackFailedException extends Exception {
|
2498 |
+
}
|
lib/wfSupportController.php
CHANGED
@@ -17,6 +17,10 @@ class wfSupportController {
|
|
17 |
|
18 |
const ITEM_WIDGET_LOCAL_ATTACKS = 'widget-local-attacks';
|
19 |
|
|
|
|
|
|
|
|
|
20 |
const ITEM_DASHBOARD = 'dashboard';
|
21 |
const ITEM_DASHBOARD_STATUS_FIREWALL = 'dashboard-status-firewall';
|
22 |
const ITEM_DASHBOARD_STATUS_SCAN = 'dashboard-status-scan';
|
@@ -125,6 +129,7 @@ class wfSupportController {
|
|
125 |
const ITEM_SCAN_OPTION_CUSTOM_MALWARE_SIGNATURES = 'scan-option-custom-malware-signatures';
|
126 |
const ITEM_SCAN_TIME_LIMIT = 'scan-time-limit';
|
127 |
const ITEM_SCAN_FAILS = 'scan-fails';
|
|
|
128 |
const ITEM_SCAN_BULK_DELETE_WARNING = 'scan-bulk-delete-warning';
|
129 |
const ITEM_SCAN_SCHEDULING = 'scan-scheduling';
|
130 |
const ITEM_SCAN_RESULT_PUBLIC_CONFIG = 'scan-result-public-config';
|
@@ -177,6 +182,10 @@ class wfSupportController {
|
|
177 |
|
178 |
case self::ITEM_WIDGET_LOCAL_ATTACKS:
|
179 |
|
|
|
|
|
|
|
|
|
180 |
case self::ITEM_DASHBOARD:
|
181 |
case self::ITEM_DASHBOARD_STATUS_FIREWALL:
|
182 |
case self::ITEM_DASHBOARD_STATUS_SCAN:
|
@@ -254,6 +263,7 @@ class wfSupportController {
|
|
254 |
case self::ITEM_SCAN_STATUS_REPUTATION:
|
255 |
case self::ITEM_SCAN_TIME_LIMIT:
|
256 |
case self::ITEM_SCAN_FAILS:
|
|
|
257 |
case self::ITEM_SCAN_BULK_DELETE_WARNING:
|
258 |
case self::ITEM_SCAN_SCHEDULING:
|
259 |
case self::ITEM_SCAN_OPTION_CHECK_SITE_BLACKLISTED:
|
17 |
|
18 |
const ITEM_WIDGET_LOCAL_ATTACKS = 'widget-local-attacks';
|
19 |
|
20 |
+
const ITEM_VERSION_WORDPRESS = 'version-wordpress';
|
21 |
+
const ITEM_VERSION_PHP = 'version-php';
|
22 |
+
const ITEM_VERSION_OPENSSL = 'version-ssl';
|
23 |
+
|
24 |
const ITEM_DASHBOARD = 'dashboard';
|
25 |
const ITEM_DASHBOARD_STATUS_FIREWALL = 'dashboard-status-firewall';
|
26 |
const ITEM_DASHBOARD_STATUS_SCAN = 'dashboard-status-scan';
|
129 |
const ITEM_SCAN_OPTION_CUSTOM_MALWARE_SIGNATURES = 'scan-option-custom-malware-signatures';
|
130 |
const ITEM_SCAN_TIME_LIMIT = 'scan-time-limit';
|
131 |
const ITEM_SCAN_FAILS = 'scan-fails';
|
132 |
+
const ITEM_SCAN_FAILED_START = 'scan-failed-start';
|
133 |
const ITEM_SCAN_BULK_DELETE_WARNING = 'scan-bulk-delete-warning';
|
134 |
const ITEM_SCAN_SCHEDULING = 'scan-scheduling';
|
135 |
const ITEM_SCAN_RESULT_PUBLIC_CONFIG = 'scan-result-public-config';
|
182 |
|
183 |
case self::ITEM_WIDGET_LOCAL_ATTACKS:
|
184 |
|
185 |
+
case self::ITEM_VERSION_WORDPRESS:
|
186 |
+
case self::ITEM_VERSION_PHP:
|
187 |
+
case self::ITEM_VERSION_OPENSSL:
|
188 |
+
|
189 |
case self::ITEM_DASHBOARD:
|
190 |
case self::ITEM_DASHBOARD_STATUS_FIREWALL:
|
191 |
case self::ITEM_DASHBOARD_STATUS_SCAN:
|
263 |
case self::ITEM_SCAN_STATUS_REPUTATION:
|
264 |
case self::ITEM_SCAN_TIME_LIMIT:
|
265 |
case self::ITEM_SCAN_FAILS:
|
266 |
+
case self::ITEM_SCAN_FAILED_START:
|
267 |
case self::ITEM_SCAN_BULK_DELETE_WARNING:
|
268 |
case self::ITEM_SCAN_SCHEDULING:
|
269 |
case self::ITEM_SCAN_OPTION_CHECK_SITE_BLACKLISTED:
|
lib/wfUtils.php
CHANGED
@@ -2411,45 +2411,6 @@ class wfUtils {
|
|
2411 |
}
|
2412 |
return new DateTime($timestring);
|
2413 |
}
|
2414 |
-
|
2415 |
-
/**
|
2416 |
-
* Returns whether or not the OpenSSL version is before, after, or equal to the equivalent text version string.
|
2417 |
-
*
|
2418 |
-
* @param string $compareVersion
|
2419 |
-
* @param int $openSSLVersion A version number in the format OpenSSL uses.
|
2420 |
-
* @return bool|int Returns -1 if $compareVersion is earlier, 0 if equal, 1 if later, and false if not a valid version string.
|
2421 |
-
*/
|
2422 |
-
public static function openssl_version_compare($compareVersion, $openSSLVersion = OPENSSL_VERSION_NUMBER) {
|
2423 |
-
if (preg_match('/^(\d+)\.(\d+)\.(\d+)([a-z]?)/i', $compareVersion, $matches)) {
|
2424 |
-
$primary = 0; $major = 0; $minor = 0; $fixLetterIndex = 0;
|
2425 |
-
if (isset($matches[1])) { $primary = (int) $matches[1]; }
|
2426 |
-
if (isset($matches[2])) { $major = (int) $matches[2]; }
|
2427 |
-
if (isset($matches[3])) { $minor = (int) $matches[3]; }
|
2428 |
-
if (isset($matches[4])) { $fixLetterIndex = strpos('abcdefghijklmnopqrstuvwxyz', strtolower($matches[1])) + 1; }
|
2429 |
-
|
2430 |
-
$compareOpenSSLVersion = self::openssl_make_version($primary, $major, $minor, $fixLetterIndex, 0);
|
2431 |
-
if ($compareOpenSSLVersion < $openSSLVersion) { return -1; }
|
2432 |
-
else if ($compareOpenSSLVersion == $openSSLVersion) { return 0; }
|
2433 |
-
return 1;
|
2434 |
-
}
|
2435 |
-
|
2436 |
-
return false;
|
2437 |
-
}
|
2438 |
-
|
2439 |
-
/**
|
2440 |
-
* Builds a number that can be compared to OPENSSL_VERSION_NUMBER from the parameters given. This is a modified
|
2441 |
-
* version of the macro in the OpenSSL source.
|
2442 |
-
*
|
2443 |
-
* @param int $primary The '1' in 1.0.2g.
|
2444 |
-
* @param int $major The '0' in 1.0.2g.
|
2445 |
-
* @param int $minor The '2' in 1.0.2g.
|
2446 |
-
* @param int $fixLetterIndex The 'g' in 1.0.2g.
|
2447 |
-
* @param int $patch
|
2448 |
-
* @return int
|
2449 |
-
*/
|
2450 |
-
public static function openssl_make_version($primary, $major, $minor, $fixLetterIndex = 0, $patch = 0) {
|
2451 |
-
return ((($primary & 0xff) << 28) + (($major & 0xff) << 20) + (($minor & 0xff) << 12) + (($fixLetterIndex & 0xff) << 4) + $patch);
|
2452 |
-
}
|
2453 |
}
|
2454 |
|
2455 |
// GeoIP lib uses these as well
|
2411 |
}
|
2412 |
return new DateTime($timestring);
|
2413 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2414 |
}
|
2415 |
|
2416 |
// GeoIP lib uses these as well
|
lib/wfVersionCheckController.php
ADDED
@@ -0,0 +1,291 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class wfVersionCheckController {
|
4 |
+
const VERSION_COMPATIBLE = 'compatible';
|
5 |
+
const VERSION_DEPRECATED = 'deprecated';
|
6 |
+
const VERSION_UNSUPPORTED = 'unsupported';
|
7 |
+
|
8 |
+
const PHP_DEPRECATING = '5.3.0'; //When greater than PHP_MINIMUM, will issue a discontinuing warning the first time we check it and find a version less than this (also applies to the other similar constant pairs)
|
9 |
+
const PHP_MINIMUM = '5.2.0'; //The currently supported minimum
|
10 |
+
|
11 |
+
const OPENSSL_DEPRECATING = '1.0.1';
|
12 |
+
const OPENSSL_MINIMUM = '1.0.1';
|
13 |
+
|
14 |
+
const WORDPRESS_DEPRECATING = '3.9.0';
|
15 |
+
const WORDPRESS_MINIMUM = '3.9.0';
|
16 |
+
|
17 |
+
public static function shared() {
|
18 |
+
static $_shared = false;
|
19 |
+
if ($_shared === false) {
|
20 |
+
$_shared = new wfVersionCheckController();
|
21 |
+
}
|
22 |
+
return $_shared;
|
23 |
+
}
|
24 |
+
|
25 |
+
/**
|
26 |
+
* Returns whether or not all version checks are successful. If any check returns a value other than VERSION_COMPATIBLE, this returns false.
|
27 |
+
*
|
28 |
+
* @return bool
|
29 |
+
*/
|
30 |
+
public function checkVersions() {
|
31 |
+
return ($this->checkPHPVersion() == self::VERSION_COMPATIBLE) && ($this->checkOpenSSLVersion() == self::VERSION_COMPATIBLE) && ($this->checkWordPressVersion() == self::VERSION_COMPATIBLE);
|
32 |
+
}
|
33 |
+
|
34 |
+
/**
|
35 |
+
* Does the same thing as checkVersions but also triggers display of the corresponding warnings.
|
36 |
+
*
|
37 |
+
* @return bool
|
38 |
+
*/
|
39 |
+
public function checkVersionsAndWarn() {
|
40 |
+
//PHP
|
41 |
+
$php = $this->checkPHPVersion();
|
42 |
+
if ($php == self::VERSION_DEPRECATED) {
|
43 |
+
$this->_alertEmail(
|
44 |
+
'phpVersionCheckDeprecationEmail_' . self::PHP_DEPRECATING,
|
45 |
+
__('PHP version too old', 'wordfence'),
|
46 |
+
sprintf(__('Your site is using a PHP version (%s) that will no longer be supported by Wordfence in an upcoming release and needs to be updated. We recommend using the newest version of PHP 7.x or 5.6 but will currently support PHP versions as old as %s. Version checks are run regularly, so if you have successfully updated, you can dismiss this notice or check that the update has taken effect later.', 'wordfence'), phpversion(), self::PHP_DEPRECATING) . ' ' . sprintf(__('Learn More: %s', 'wordfence'), wfSupportController::esc_supportURL(wfSupportController::ITEM_VERSION_PHP))
|
47 |
+
);
|
48 |
+
|
49 |
+
$this->_adminNotice(
|
50 |
+
'phpVersionCheckDeprecationNotice_' . self::PHP_DEPRECATING,
|
51 |
+
'phpVersionCheck',
|
52 |
+
sprintf(__('<strong>WARNING: </strong> Your site is using a PHP version (%s) that will no longer be supported by Wordfence in an upcoming release and needs to be updated. We recommend using the newest version of PHP 7.x or 5.6 but will currently support PHP versions as old as %s. Version checks are run regularly, so if you have successfully updated, you can dismiss this notice or check that the update has taken effect later.', 'wordfence'), phpversion(), self::PHP_DEPRECATING) . ' <a href="' . wfSupportController::esc_supportURL(wfSupportController::ITEM_VERSION_PHP) . '" target="_blank" rel="noopener noreferrer">' . __('Learn More', 'wordfence') . '</a>'
|
53 |
+
);
|
54 |
+
|
55 |
+
return false;
|
56 |
+
}
|
57 |
+
else if ($php == self::VERSION_UNSUPPORTED) {
|
58 |
+
$this->_alertEmail(
|
59 |
+
'phpVersionCheckUnsupportedEmail_' . self::PHP_MINIMUM,
|
60 |
+
__('PHP version too old', 'wordfence'),
|
61 |
+
sprintf(__('Your site is using a PHP version (%s) that is no longer supported by Wordfence and needs to be updated. We recommend using the newest version of PHP 7.x or 5.6 but will currently support PHP versions as old as %s. Version checks are run regularly, so if you have successfully updated, you can dismiss this notice or check that the update has taken effect later.', 'wordfence'), phpversion(), self::PHP_DEPRECATING) . ' ' . sprintf(__('Learn More: %s', 'wordfence'), wfSupportController::esc_supportURL(wfSupportController::ITEM_VERSION_PHP))
|
62 |
+
);
|
63 |
+
|
64 |
+
$this->_adminNotice(
|
65 |
+
'phpVersionCheckUnsupportedNotice_' . self::PHP_MINIMUM,
|
66 |
+
'phpVersionCheck',
|
67 |
+
sprintf(__('<strong>WARNING: </strong> Your site is using a PHP version (%s) that is no longer supported by Wordfence and needs to be updated. We recommend using the newest version of PHP 7.x or 5.6 but will currently support PHP versions as old as %s. Version checks are run regularly, so if you have successfully updated, you can dismiss this notice or check that the update has taken effect later.', 'wordfence'), phpversion(), self::PHP_DEPRECATING) . ' <a href="' . wfSupportController::esc_supportURL(wfSupportController::ITEM_VERSION_PHP) . '" target="_blank" rel="noopener noreferrer">' . __('Learn More', 'wordfence') . '</a>'
|
68 |
+
);
|
69 |
+
|
70 |
+
return false;
|
71 |
+
}
|
72 |
+
else {
|
73 |
+
wfAdminNoticeQueue::removeAdminNotice(false, 'phpVersionCheck');
|
74 |
+
}
|
75 |
+
|
76 |
+
//OpenSSL
|
77 |
+
$openssl = $this->checkOpenSSLVersion();
|
78 |
+
if ($openssl == self::VERSION_DEPRECATED) {
|
79 |
+
$this->_alertEmail(
|
80 |
+
'opensslVersionCheckDeprecationEmail_' . self::OPENSSL_DEPRECATING,
|
81 |
+
__('OpenSSL version too old', 'wordfence'),
|
82 |
+
sprintf(__('Your site is using an OpenSSL version (%s) that will no longer be supported by Wordfence in an upcoming release and needs to be updated. We recommend using the newest version of OpenSSL but will currently support OpenSSL versions as old as %s. Version checks are run regularly, so if you have successfully updated, you can dismiss this notice or check that the update has taken effect later.', 'wordfence'), self::openssl_make_text_version(), self::OPENSSL_DEPRECATING) . ' ' . sprintf(__('Learn More: %s', 'wordfence'), wfSupportController::esc_supportURL(wfSupportController::ITEM_VERSION_OPENSSL))
|
83 |
+
);
|
84 |
+
|
85 |
+
$this->_adminNotice(
|
86 |
+
'opensslVersionCheckDeprecationNotice_' . self::OPENSSL_DEPRECATING,
|
87 |
+
'opensslVersionCheck',
|
88 |
+
sprintf(__('<strong>WARNING: </strong> Your site is using an OpenSSL version (%s) that will no longer be supported by Wordfence in an upcoming release and needs to be updated. We recommend using the newest version of OpenSSL but will currently support OpenSSL versions as old as %s. Version checks are run regularly, so if you have successfully updated, you can dismiss this notice or check that the update has taken effect later.', 'wordfence'), self::openssl_make_text_version(), self::OPENSSL_DEPRECATING) . ' <a href="' . wfSupportController::esc_supportURL(wfSupportController::ITEM_VERSION_OPENSSL) . '" target="_blank" rel="noopener noreferrer">' . __('Learn More', 'wordfence') . '</a>'
|
89 |
+
);
|
90 |
+
|
91 |
+
return false;
|
92 |
+
}
|
93 |
+
else if ($openssl == self::VERSION_UNSUPPORTED) {
|
94 |
+
$this->_alertEmail(
|
95 |
+
'opensslVersionCheckUnsupportedEmail_' . self::PHP_MINIMUM,
|
96 |
+
__('OpenSSL version too old', 'wordfence'),
|
97 |
+
sprintf(__('Your site is using an OpenSSL version (%s) that is no longer supported by Wordfence and needs to be updated. We recommend using the newest version of OpenSSL but will currently support OpenSSL versions as old as %s. Version checks are run regularly, so if you have successfully updated, you can dismiss this notice or check that the update has taken effect later.', 'wordfence'), self::openssl_make_text_version(), self::OPENSSL_DEPRECATING) . ' ' . sprintf(__('Learn More: %s', 'wordfence'), wfSupportController::esc_supportURL(wfSupportController::ITEM_VERSION_OPENSSL))
|
98 |
+
);
|
99 |
+
|
100 |
+
$this->_adminNotice(
|
101 |
+
'opensslVersionCheckUnsupportedNotice_' . self::PHP_MINIMUM,
|
102 |
+
'opensslVersionCheck',
|
103 |
+
sprintf(__('<strong>WARNING: </strong> Your site is using an OpenSSL version (%s) that is no longer supported by Wordfence and needs to be updated. We recommend using the newest version of OpenSSL but will currently support OpenSSL versions as old as %s. Version checks are run regularly, so if you have successfully updated, you can dismiss this notice or check that the update has taken effect later.', 'wordfence'), self::openssl_make_text_version(), self::OPENSSL_DEPRECATING) . ' <a href="' . wfSupportController::esc_supportURL(wfSupportController::ITEM_VERSION_OPENSSL) . '" target="_blank" rel="noopener noreferrer">' . __('Learn More', 'wordfence') . '</a>'
|
104 |
+
);
|
105 |
+
|
106 |
+
return false;
|
107 |
+
}
|
108 |
+
else {
|
109 |
+
wfAdminNoticeQueue::removeAdminNotice(false, 'opensslVersionCheck');
|
110 |
+
}
|
111 |
+
|
112 |
+
//WordPress
|
113 |
+
$wordpress = $this->checkWordPressVersion();
|
114 |
+
if ($wordpress == self::VERSION_DEPRECATED) {
|
115 |
+
require(ABSPATH . 'wp-includes/version.php'); /** @var string $wp_version */
|
116 |
+
|
117 |
+
$this->_alertEmail(
|
118 |
+
'wordpressVersionCheckDeprecationEmail_' . self::WORDPRESS_DEPRECATING,
|
119 |
+
__('WordPress version too old', 'wordfence'),
|
120 |
+
sprintf(__('Your site is using a WordPress version (%s) that will no longer be supported by Wordfence in an upcoming release and needs to be updated. We recommend using the newest version of WordPress but will currently support WordPress versions as old as %s. Version checks are run regularly, so if you have successfully updated, you can dismiss this notice or check that the update has taken effect later.', 'wordfence'), $wp_version, self::WORDPRESS_DEPRECATING) . ' ' . sprintf(__('Learn More: %s', 'wordfence'), wfSupportController::esc_supportURL(wfSupportController::ITEM_VERSION_WORDPRESS))
|
121 |
+
);
|
122 |
+
|
123 |
+
$this->_adminNotice(
|
124 |
+
'wordpressVersionCheckDeprecationNotice_' . self::WORDPRESS_DEPRECATING,
|
125 |
+
'wordpressVersionCheck',
|
126 |
+
sprintf(__('<strong>WARNING: </strong> Your site is using a WordPress version (%s) that will no longer be supported by Wordfence in an upcoming release and needs to be updated. We recommend using the newest version of WordPress but will currently support WordPress versions as old as %s. Version checks are run regularly, so if you have successfully updated, you can dismiss this notice or check that the update has taken effect later.', 'wordfence'), $wp_version, self::WORDPRESS_DEPRECATING) . ' <a href="' . wfSupportController::esc_supportURL(wfSupportController::ITEM_VERSION_WORDPRESS) . '" target="_blank" rel="noopener noreferrer">' . __('Learn More', 'wordfence') . '</a>'
|
127 |
+
);
|
128 |
+
|
129 |
+
return false;
|
130 |
+
}
|
131 |
+
else if ($wordpress == self::VERSION_UNSUPPORTED) {
|
132 |
+
require(ABSPATH . 'wp-includes/version.php'); /** @var string $wp_version */
|
133 |
+
|
134 |
+
$this->_alertEmail(
|
135 |
+
'wordpressVersionCheckUnsupportedEmail_' . self::WORDPRESS_MINIMUM,
|
136 |
+
__('WordPress version too old', 'wordfence'),
|
137 |
+
sprintf(__('Your site is using a WordPress version (%s) that is no longer supported by Wordfence and needs to be updated. We recommend using the newest version of WordPress but will currently support WordPress versions as old as %s. Version checks are run regularly, so if you have successfully updated, you can dismiss this notice or check that the update has taken effect later.', 'wordfence'), $wp_version, self::WORDPRESS_DEPRECATING) . ' ' . sprintf(__('Learn More: %s', 'wordfence'), wfSupportController::esc_supportURL(wfSupportController::ITEM_VERSION_WORDPRESS))
|
138 |
+
);
|
139 |
+
|
140 |
+
$this->_adminNotice(
|
141 |
+
'wordpressVersionCheckUnsupportedNotice_' . self::WORDPRESS_MINIMUM,
|
142 |
+
'wordpressVersionCheck',
|
143 |
+
sprintf(__('<strong>WARNING: </strong> Your site is using a WordPress version (%s) that is no longer supported by Wordfence and needs to be updated. We recommend using the newest version of WordPress but will currently support WordPress versions as old as %s. Version checks are run regularly, so if you have successfully updated, you can dismiss this notice or check that the update has taken effect later.', 'wordfence'), $wp_version, self::WORDPRESS_DEPRECATING) . ' <a href="' . wfSupportController::esc_supportURL(wfSupportController::ITEM_VERSION_WORDPRESS) . '" target="_blank" rel="noopener noreferrer">' . __('Learn More', 'wordfence') . '</a>'
|
144 |
+
);
|
145 |
+
|
146 |
+
return false;
|
147 |
+
}
|
148 |
+
else {
|
149 |
+
wfAdminNoticeQueue::removeAdminNotice(false, 'wordpressVersionCheck');
|
150 |
+
}
|
151 |
+
|
152 |
+
return true;
|
153 |
+
}
|
154 |
+
|
155 |
+
private function _alertEmail($checkKey, $title, $body) {
|
156 |
+
if (!wfConfig::get($checkKey)) {
|
157 |
+
wordfence::alert($title, $body, wfUtils::getIP());
|
158 |
+
wfConfig::set($checkKey, true);
|
159 |
+
}
|
160 |
+
}
|
161 |
+
|
162 |
+
private function _adminNotice($checkKey, $noticeKey, $message) {
|
163 |
+
if (!wfConfig::get($checkKey)) {
|
164 |
+
wfAdminNoticeQueue::addAdminNotice(wfAdminNotice::SEVERITY_CRITICAL, $message, $noticeKey);
|
165 |
+
wfConfig::set($checkKey, true);
|
166 |
+
}
|
167 |
+
}
|
168 |
+
|
169 |
+
/**
|
170 |
+
* Returns whether or not the PHP version meets our minimum requirement or is a version being deprecated.
|
171 |
+
*
|
172 |
+
* @return string One of the VERSION_ constants.
|
173 |
+
*/
|
174 |
+
public function checkPHPVersion() {
|
175 |
+
if (version_compare(phpversion(), self::PHP_DEPRECATING, '>=')) {
|
176 |
+
return self::VERSION_COMPATIBLE;
|
177 |
+
}
|
178 |
+
|
179 |
+
if (self::PHP_DEPRECATING != self::PHP_MINIMUM && version_compare(phpversion(), self::PHP_MINIMUM, '>=')) {
|
180 |
+
return self::VERSION_DEPRECATED;
|
181 |
+
}
|
182 |
+
|
183 |
+
return self::VERSION_UNSUPPORTED;
|
184 |
+
}
|
185 |
+
|
186 |
+
/**
|
187 |
+
* Returns whether or not the OpenSSL version meets our minimum requirement or is a version being deprecated.
|
188 |
+
*
|
189 |
+
* @return string One of the VERSION_ constants.
|
190 |
+
*/
|
191 |
+
public function checkOpenSSLVersion() {
|
192 |
+
if (self::openssl_version_compare(self::OPENSSL_DEPRECATING) <= 0) {
|
193 |
+
return self::VERSION_COMPATIBLE;
|
194 |
+
}
|
195 |
+
|
196 |
+
if (self::OPENSSL_DEPRECATING != self::OPENSSL_MINIMUM && self::openssl_version_compare(self::OPENSSL_MINIMUM) <= 0) {
|
197 |
+
return self::VERSION_DEPRECATED;
|
198 |
+
}
|
199 |
+
|
200 |
+
return self::VERSION_UNSUPPORTED;
|
201 |
+
}
|
202 |
+
|
203 |
+
/**
|
204 |
+
* Returns whether or not the WordPress version meets our minimum requirement or is a version being deprecated.
|
205 |
+
*
|
206 |
+
* @return string One of the VERSION_ constants.
|
207 |
+
*/
|
208 |
+
public function checkWordPressVersion() {
|
209 |
+
require(ABSPATH . 'wp-includes/version.php'); /** @var string $wp_version */
|
210 |
+
|
211 |
+
if (version_compare($wp_version, self::WORDPRESS_DEPRECATING, '>=')) {
|
212 |
+
return self::VERSION_COMPATIBLE;
|
213 |
+
}
|
214 |
+
|
215 |
+
if (self::WORDPRESS_DEPRECATING != self::WORDPRESS_MINIMUM && version_compare($wp_version, self::WORDPRESS_MINIMUM, '>=')) {
|
216 |
+
return self::VERSION_DEPRECATED;
|
217 |
+
}
|
218 |
+
|
219 |
+
return self::VERSION_UNSUPPORTED;
|
220 |
+
}
|
221 |
+
|
222 |
+
/**
|
223 |
+
* Utility Functions
|
224 |
+
*/
|
225 |
+
|
226 |
+
/**
|
227 |
+
* Returns whether or not the OpenSSL version is before, after, or equal to the equivalent text version string.
|
228 |
+
*
|
229 |
+
* @param string $compareVersion
|
230 |
+
* @param int $openSSLVersion A version number in the format OpenSSL uses.
|
231 |
+
* @return bool|int Returns -1 if $compareVersion is earlier, 0 if equal, 1 if later, and false if not a valid version string.
|
232 |
+
*/
|
233 |
+
public static function openssl_version_compare($compareVersion, $openSSLVersion = OPENSSL_VERSION_NUMBER) {
|
234 |
+
if (preg_match('/^(\d+)\.(\d+)\.(\d+)([a-z]?)/i', $compareVersion, $matches)) {
|
235 |
+
$primary = 0; $major = 0; $minor = 0; $fixLetterIndex = 0;
|
236 |
+
if (isset($matches[1])) { $primary = (int) $matches[1]; }
|
237 |
+
if (isset($matches[2])) { $major = (int) $matches[2]; }
|
238 |
+
if (isset($matches[3])) { $minor = (int) $matches[3]; }
|
239 |
+
if (isset($matches[4])) { $fixLetterIndex = strpos('abcdefghijklmnopqrstuvwxyz', strtolower($matches[1])) + 1; }
|
240 |
+
|
241 |
+
$compareOpenSSLVersion = self::openssl_make_number_version($primary, $major, $minor, $fixLetterIndex, 0);
|
242 |
+
if ($compareOpenSSLVersion < $openSSLVersion) { return -1; }
|
243 |
+
else if ($compareOpenSSLVersion == $openSSLVersion) { return 0; }
|
244 |
+
return 1;
|
245 |
+
}
|
246 |
+
|
247 |
+
return false;
|
248 |
+
}
|
249 |
+
|
250 |
+
/**
|
251 |
+
* Builds a number that can be compared to OPENSSL_VERSION_NUMBER from the parameters given. This is a modified
|
252 |
+
* version of the macro in the OpenSSL source.
|
253 |
+
*
|
254 |
+
* @param int $primary The '1' in 1.0.2g.
|
255 |
+
* @param int $major The '0' in 1.0.2g.
|
256 |
+
* @param int $minor The '2' in 1.0.2g.
|
257 |
+
* @param int $fixLetterIndex The 'g' in 1.0.2g.
|
258 |
+
* @param int $patch
|
259 |
+
* @return int
|
260 |
+
*/
|
261 |
+
public static function openssl_make_number_version($primary, $major, $minor, $fixLetterIndex = 0, $patch = 0) {
|
262 |
+
return ((($primary & 0xff) << 28) + (($major & 0xff) << 20) + (($minor & 0xff) << 12) + (($fixLetterIndex & 0xff) << 4) + $patch);
|
263 |
+
}
|
264 |
+
|
265 |
+
/**
|
266 |
+
* Builds a text version of the OpenSSL version from a number-formatted one.
|
267 |
+
*
|
268 |
+
* @param int $number
|
269 |
+
* @return string
|
270 |
+
*/
|
271 |
+
public static function openssl_make_text_version($number = OPENSSL_VERSION_NUMBER) {
|
272 |
+
$primary = (($number >> 28) & 0xff);
|
273 |
+
$major = (($number >> 20) & 0xff);
|
274 |
+
$minor = (($number >> 12) & 0xff);
|
275 |
+
$fix = (($number >> 4) & 0xff);
|
276 |
+
$patch = ($number & 0xf); //Not currently handled -- would be values like alpha, beta, rc1
|
277 |
+
|
278 |
+
$alphabet = str_split('abcdefghijklmnopqrstuvwxyz');
|
279 |
+
$fixLetters = '';
|
280 |
+
while ($fix > 26) {
|
281 |
+
$fixLetters .= 'z';
|
282 |
+
$fix -= 26;
|
283 |
+
}
|
284 |
+
if (array_key_exists($fix - 1, $alphabet)) {
|
285 |
+
$fixLetters .= $alphabet[$fix - 1];
|
286 |
+
}
|
287 |
+
|
288 |
+
$version = "{$primary}.{$major}.{$minor}{$fixLetters}";
|
289 |
+
return $version;
|
290 |
+
}
|
291 |
+
}
|
lib/wordfenceClass.php
CHANGED
@@ -36,6 +36,7 @@ require_once(dirname(__FILE__) . '/wfImportExportController.php');
|
|
36 |
require_once(dirname(__FILE__) . '/wfOnboardingController.php');
|
37 |
require_once(dirname(__FILE__) . '/wfSupportController.php');
|
38 |
require_once(dirname(__FILE__) . '/wfCredentialsController.php');
|
|
|
39 |
require_once(dirname(__FILE__) . '/wfDateLocalization.php');
|
40 |
require_once(dirname(__FILE__) . '/wfAdminNoticeQueue.php');
|
41 |
|
@@ -65,6 +66,11 @@ class wordfence {
|
|
65 |
public static $commentSpamItems = array();
|
66 |
public static function installPlugin(){
|
67 |
self::runInstall();
|
|
|
|
|
|
|
|
|
|
|
68 |
//Used by MU code below
|
69 |
update_option('wordfenceActivated', 1);
|
70 |
}
|
@@ -102,9 +108,9 @@ class wordfence {
|
|
102 |
}
|
103 |
|
104 |
if(wfConfig::get('deleteTablesOnDeact')){
|
|
|
105 |
$schema = new wfSchema();
|
106 |
$schema->dropAll();
|
107 |
-
wfConfig::updateTableExists();
|
108 |
foreach(array('wordfence_version', 'wordfenceActivated') as $opt){
|
109 |
if (is_multisite() && function_exists('delete_network_option')) {
|
110 |
delete_network_option(null, $opt);
|
@@ -171,6 +177,8 @@ class wordfence {
|
|
171 |
}
|
172 |
}
|
173 |
}
|
|
|
|
|
174 |
}
|
175 |
private static function keyAlert($msg){
|
176 |
self::alert($msg, $msg . " To ensure uninterrupted Premium Wordfence protection on your site,\nplease renew your API key by visiting http://www.wordfence.com/ Sign in, go to your dashboard,\nselect the key about to expire and click the button to renew that API key.", false);
|
@@ -187,6 +195,7 @@ class wordfence {
|
|
187 |
try {
|
188 |
$keyType = wfAPI::KEY_TYPE_FREE;
|
189 |
$keyData = $api->call('ping_api_key', array(), array('supportHash' => wfConfig::get('supportHash', '')));
|
|
|
190 |
if (isset($keyData['_isPaidKey'])) {
|
191 |
$keyType = wfConfig::get('keyType');
|
192 |
}
|
@@ -248,6 +257,7 @@ class wordfence {
|
|
248 |
}
|
249 |
catch(Exception $e){
|
250 |
wordfence::status(4, 'error', "Could not verify Wordfence API Key: " . $e->getMessage());
|
|
|
251 |
}
|
252 |
|
253 |
$wfdb = new wfDB();
|
@@ -403,6 +413,8 @@ class wordfence {
|
|
403 |
public static function _completeCoreUpdateNotification() {
|
404 |
//This approach is here because WP Core updates run in a different sequence than plugin/theme updates, so we have to defer the running of the notification update sequence by an extra page load
|
405 |
delete_site_transient('wordfence_updating_notifications');
|
|
|
|
|
406 |
}
|
407 |
public static function runInstall(){
|
408 |
if(self::$runInstallCalled){ return; }
|
@@ -428,6 +440,7 @@ class wordfence {
|
|
428 |
|
429 |
$schema = new wfSchema();
|
430 |
$schema->createAll(); //if not exists
|
|
|
431 |
|
432 |
/** @var wpdb $wpdb */
|
433 |
global $wpdb;
|
@@ -1014,6 +1027,11 @@ SQL
|
|
1014 |
|
1015 |
//Install new schedule. If schedule config is blank it will install the default 'auto' schedule.
|
1016 |
wfScanner::shared()->scheduleScans();
|
|
|
|
|
|
|
|
|
|
|
1017 |
|
1018 |
//Must be the final line
|
1019 |
}
|
@@ -1104,6 +1122,7 @@ SQL
|
|
1104 |
add_action('wordfence_daily_cron', 'wordfence::dailyCron');
|
1105 |
add_action('wordfence_daily_autoUpdate', 'wfConfig::autoUpdate');
|
1106 |
add_action('wordfence_hourly_cron', 'wordfence::hourlyCron');
|
|
|
1107 |
add_action('plugins_loaded', 'wordfence::veryFirstAction');
|
1108 |
add_action('init', 'wordfence::initAction');
|
1109 |
//add_action('admin_bar_menu', 'wordfence::admin_bar_menu', 99);
|
@@ -1485,7 +1504,11 @@ SQL
|
|
1485 |
wfBlock::createLockout($reason, $IP, wfBlock::lockoutDuration(), time(), time(), 1);
|
1486 |
self::getLog()->tagRequestForLockout($reason);
|
1487 |
if (wfConfig::get('alertOn_loginLockout')) {
|
1488 |
-
|
|
|
|
|
|
|
|
|
1489 |
}
|
1490 |
}
|
1491 |
|
@@ -1936,7 +1959,7 @@ SQL
|
|
1936 |
if (isset($_POST['wordfence_authFactor']) && $_POST['wordfence_authFactor'] && $twoFactorRecord) { //User authenticated with name and password, 2FA code ready to check
|
1937 |
$userID = $userDat->ID;
|
1938 |
|
1939 |
-
if (get_class($authUser) == 'WP_User' && $authUser->ID == $userID) {
|
1940 |
//Do nothing. This is the code path the old method of including the code in the password field will take -- since we already have a valid $authUser, skip the nonce verification portion
|
1941 |
}
|
1942 |
else if (isset($_POST['wordfence_twoFactorNonce'])) {
|
@@ -1976,7 +1999,7 @@ SQL
|
|
1976 |
//Everything's good, let the sign in continue
|
1977 |
}
|
1978 |
else {
|
1979 |
-
if (get_class($authUser) == 'WP_User' && $authUser->ID == $userID) { //Using the old method of appending the code to the password
|
1980 |
if ($mode == 'authenticator') {
|
1981 |
remove_action('login_errors', 'limit_login_fixup_error_messages'); //We're forced to do this because limit-login-attempts does not have any allowances for legitimate error messages
|
1982 |
self::$authError = new WP_Error('twofactor_invalid', __('<strong>INVALID CODE</strong>: Please sign in again and add a space, the letters <code>wf</code>, and the code from your authenticator app to the end of your password (e.g., <code>wf123456</code>).'));
|
@@ -2081,7 +2104,7 @@ SQL
|
|
2081 |
delete_user_meta($userDat->ID, '_wf_twoFactorNonceTime');
|
2082 |
$authUser = $userDat; //Log in as the user we saved in the wp_authenticate action
|
2083 |
}
|
2084 |
-
else if (get_class($authUser) == 'WP_User') { //User authenticated with name and password, prompt for the 2FA code
|
2085 |
//Verify at least one administrator has 2FA enabled
|
2086 |
$requireAdminTwoFactor = $hasActivatedTwoFactorUser && wfConfig::get('loginSec_requireAdminTwoFactor');
|
2087 |
|
@@ -2346,7 +2369,7 @@ SQL
|
|
2346 |
require('wfLockedOut.php');
|
2347 |
}
|
2348 |
set_transient($tKey, $tries, wfConfig::get('loginSec_countFailMins') * 60);
|
2349 |
-
} else if(get_class($authUser) == 'WP_User'){
|
2350 |
delete_transient($tKey); //reset counter on success
|
2351 |
}
|
2352 |
}
|
@@ -2404,7 +2427,7 @@ SQL
|
|
2404 |
}
|
2405 |
|
2406 |
try {
|
2407 |
-
$response = wp_remote_post(WORDFENCE_HACKATTEMPT_URL . 'multipleHackAttempts/?k=' . rawurlencode(wfConfig::get('apiKey')) . '&t=brute', array(
|
2408 |
'timeout' => 1,
|
2409 |
'user-agent' => "Wordfence.com UA " . (defined('WORDFENCE_VERSION') ? WORDFENCE_VERSION : '[Unknown version]'),
|
2410 |
'body' => 'IPs=' . rawurlencode(json_encode($toSend)),
|
@@ -2476,7 +2499,7 @@ SQL
|
|
2476 |
$toSend = array_values($toSend);
|
2477 |
|
2478 |
try {
|
2479 |
-
$response = wp_remote_post(WORDFENCE_HACKATTEMPT_URL . 'multipleHackAttempts/?k=' . rawurlencode(wfConfig::get('apiKey')) . '&t=brute', array(
|
2480 |
'timeout' => 1,
|
2481 |
'user-agent' => "Wordfence.com UA " . (defined('WORDFENCE_VERSION') ? WORDFENCE_VERSION : '[Unknown version]'),
|
2482 |
'body' => 'IPs=' . rawurlencode(json_encode($toSend)),
|
@@ -2532,7 +2555,7 @@ SQL
|
|
2532 |
}
|
2533 |
|
2534 |
try {
|
2535 |
-
$result = wp_remote_get(WORDFENCE_HACKATTEMPT_URL . 'hackAttempt/?k=' . rawurlencode(wfConfig::get('apiKey')) .
|
2536 |
'&IP=' . rawurlencode(filter_var($IP, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) ? wfUtils::inet_aton($IP) : wfUtils::inet_pton($IP)) .
|
2537 |
'&t=' . rawurlencode($hitType) .
|
2538 |
'&type=' . $endpointType,
|
@@ -3007,7 +3030,20 @@ SQL
|
|
3007 |
//This ensures that if the scan crashes for some reason, the schedule will hold.
|
3008 |
wfScanner::shared()->scheduleScans();
|
3009 |
|
3010 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3011 |
}
|
3012 |
public static function ajax_saveCountryBlocking_callback(){
|
3013 |
if(! wfConfig::get('isPaid')){
|
@@ -3037,6 +3073,67 @@ SQL
|
|
3037 |
$content .= date(DATE_RFC822, $r['ctime'] + $timeOffset) . '::' . sprintf('%.4f', $r['ctime']) . ':' . $r['level'] . ':' . $r['type'] . '::' . wp_kses_data( (string) $r['msg']) . "\n";
|
3038 |
}
|
3039 |
$content .= "\n\n";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3040 |
|
3041 |
ob_start();
|
3042 |
phpinfo();
|
@@ -3782,6 +3879,7 @@ HTACCESS;
|
|
3782 |
wordfence::status(10, 'info', "SUM_KILLED:A request was received to stop the previous scan.");
|
3783 |
wfUtils::clearScanLock(); //Clear the lock now because there may not be a scan running to pick up the kill request and clear the lock
|
3784 |
wfScanEngine::requestKill();
|
|
|
3785 |
wfConfig::set('lastScanFailureType', false);
|
3786 |
return array(
|
3787 |
'ok' => 1,
|
@@ -3957,6 +4055,32 @@ HTACCESS;
|
|
3957 |
'buttonTitle' => __('Close', 'wordfence'),
|
3958 |
))->render();
|
3959 |
break;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3960 |
}
|
3961 |
|
3962 |
wfUtils::doNotCache();
|
@@ -3967,7 +4091,7 @@ HTACCESS;
|
|
3967 |
'currentScanID' => wfScanner::shared()->lastScanTime(),
|
3968 |
'signatureUpdateTime' => wfConfig::get('signatureUpdateTime'),
|
3969 |
'scanFailedHTML' => $scanFailedHTML,
|
3970 |
-
'scanStalled' => ($scanFailed == wfIssues::SCAN_FAILED_TIMEOUT ? 1 : 0),
|
3971 |
'scanRunning' => wfScanner::shared()->isRunning() ? 1 : 0,
|
3972 |
'scanStages' => $stages,
|
3973 |
'scanStats' => $stats,
|
36 |
require_once(dirname(__FILE__) . '/wfOnboardingController.php');
|
37 |
require_once(dirname(__FILE__) . '/wfSupportController.php');
|
38 |
require_once(dirname(__FILE__) . '/wfCredentialsController.php');
|
39 |
+
require_once(dirname(__FILE__) . '/wfVersionCheckController.php');
|
40 |
require_once(dirname(__FILE__) . '/wfDateLocalization.php');
|
41 |
require_once(dirname(__FILE__) . '/wfAdminNoticeQueue.php');
|
42 |
|
66 |
public static $commentSpamItems = array();
|
67 |
public static function installPlugin(){
|
68 |
self::runInstall();
|
69 |
+
|
70 |
+
if (get_current_user_id() > 0) {
|
71 |
+
wfConfig::set('activatingIP', wfUtils::getIP());
|
72 |
+
}
|
73 |
+
|
74 |
//Used by MU code below
|
75 |
update_option('wordfenceActivated', 1);
|
76 |
}
|
108 |
}
|
109 |
|
110 |
if(wfConfig::get('deleteTablesOnDeact')){
|
111 |
+
wfConfig::updateTableExists(false);
|
112 |
$schema = new wfSchema();
|
113 |
$schema->dropAll();
|
|
|
114 |
foreach(array('wordfence_version', 'wordfenceActivated') as $opt){
|
115 |
if (is_multisite() && function_exists('delete_network_option')) {
|
116 |
delete_network_option(null, $opt);
|
177 |
}
|
178 |
}
|
179 |
}
|
180 |
+
|
181 |
+
wfVersionCheckController::shared()->checkVersionsAndWarn();
|
182 |
}
|
183 |
private static function keyAlert($msg){
|
184 |
self::alert($msg, $msg . " To ensure uninterrupted Premium Wordfence protection on your site,\nplease renew your API key by visiting http://www.wordfence.com/ Sign in, go to your dashboard,\nselect the key about to expire and click the button to renew that API key.", false);
|
195 |
try {
|
196 |
$keyType = wfAPI::KEY_TYPE_FREE;
|
197 |
$keyData = $api->call('ping_api_key', array(), array('supportHash' => wfConfig::get('supportHash', '')));
|
198 |
+
wfConfig::set('useNoc3Secure', isset($keyData['n3']) ? wfUtils::truthyToBoolean($keyData['n3']) : false);
|
199 |
if (isset($keyData['_isPaidKey'])) {
|
200 |
$keyType = wfConfig::get('keyType');
|
201 |
}
|
257 |
}
|
258 |
catch(Exception $e){
|
259 |
wordfence::status(4, 'error', "Could not verify Wordfence API Key: " . $e->getMessage());
|
260 |
+
wfConfig::set('useNoc3Secure', false);
|
261 |
}
|
262 |
|
263 |
$wfdb = new wfDB();
|
413 |
public static function _completeCoreUpdateNotification() {
|
414 |
//This approach is here because WP Core updates run in a different sequence than plugin/theme updates, so we have to defer the running of the notification update sequence by an extra page load
|
415 |
delete_site_transient('wordfence_updating_notifications');
|
416 |
+
|
417 |
+
wfVersionCheckController::shared()->checkVersionsAndWarn();
|
418 |
}
|
419 |
public static function runInstall(){
|
420 |
if(self::$runInstallCalled){ return; }
|
440 |
|
441 |
$schema = new wfSchema();
|
442 |
$schema->createAll(); //if not exists
|
443 |
+
wfConfig::updateTableExists(true);
|
444 |
|
445 |
/** @var wpdb $wpdb */
|
446 |
global $wpdb;
|
1027 |
|
1028 |
//Install new schedule. If schedule config is blank it will install the default 'auto' schedule.
|
1029 |
wfScanner::shared()->scheduleScans();
|
1030 |
+
|
1031 |
+
//Check our minimum versions and generate the necessary warnings
|
1032 |
+
if (!wp_next_scheduled('wordfence_version_check')) {
|
1033 |
+
wp_schedule_single_event(time(), 'wordfence_version_check');
|
1034 |
+
}
|
1035 |
|
1036 |
//Must be the final line
|
1037 |
}
|
1122 |
add_action('wordfence_daily_cron', 'wordfence::dailyCron');
|
1123 |
add_action('wordfence_daily_autoUpdate', 'wfConfig::autoUpdate');
|
1124 |
add_action('wordfence_hourly_cron', 'wordfence::hourlyCron');
|
1125 |
+
add_action('wordfence_version_check', array(wfVersionCheckController::shared(), 'checkVersionsAndWarn'));
|
1126 |
add_action('plugins_loaded', 'wordfence::veryFirstAction');
|
1127 |
add_action('init', 'wordfence::initAction');
|
1128 |
//add_action('admin_bar_menu', 'wordfence::admin_bar_menu', 99);
|
1504 |
wfBlock::createLockout($reason, $IP, wfBlock::lockoutDuration(), time(), time(), 1);
|
1505 |
self::getLog()->tagRequestForLockout($reason);
|
1506 |
if (wfConfig::get('alertOn_loginLockout')) {
|
1507 |
+
$message = sprintf(__('A user with IP addr %s has been locked out from signing in or using the password recovery form for the following reason: %s.', 'wordfence'), $IP, $reason);
|
1508 |
+
if (wfBlock::lockoutDuration() > 0) {
|
1509 |
+
$message .= "\n" . sprintf(__('The duration of the lockout is %s.', 'wordfence'), wfUtils::makeDuration(wfBlock::lockoutDuration(), true));
|
1510 |
+
}
|
1511 |
+
wordfence::alert(__('User locked out from signing in', 'wordfence'), $message, $IP);
|
1512 |
}
|
1513 |
}
|
1514 |
|
1959 |
if (isset($_POST['wordfence_authFactor']) && $_POST['wordfence_authFactor'] && $twoFactorRecord) { //User authenticated with name and password, 2FA code ready to check
|
1960 |
$userID = $userDat->ID;
|
1961 |
|
1962 |
+
if (is_object($authUser) && get_class($authUser) == 'WP_User' && $authUser->ID == $userID) {
|
1963 |
//Do nothing. This is the code path the old method of including the code in the password field will take -- since we already have a valid $authUser, skip the nonce verification portion
|
1964 |
}
|
1965 |
else if (isset($_POST['wordfence_twoFactorNonce'])) {
|
1999 |
//Everything's good, let the sign in continue
|
2000 |
}
|
2001 |
else {
|
2002 |
+
if (is_object($authUser) && get_class($authUser) == 'WP_User' && $authUser->ID == $userID) { //Using the old method of appending the code to the password
|
2003 |
if ($mode == 'authenticator') {
|
2004 |
remove_action('login_errors', 'limit_login_fixup_error_messages'); //We're forced to do this because limit-login-attempts does not have any allowances for legitimate error messages
|
2005 |
self::$authError = new WP_Error('twofactor_invalid', __('<strong>INVALID CODE</strong>: Please sign in again and add a space, the letters <code>wf</code>, and the code from your authenticator app to the end of your password (e.g., <code>wf123456</code>).'));
|
2104 |
delete_user_meta($userDat->ID, '_wf_twoFactorNonceTime');
|
2105 |
$authUser = $userDat; //Log in as the user we saved in the wp_authenticate action
|
2106 |
}
|
2107 |
+
else if (is_object($authUser) && get_class($authUser) == 'WP_User') { //User authenticated with name and password, prompt for the 2FA code
|
2108 |
//Verify at least one administrator has 2FA enabled
|
2109 |
$requireAdminTwoFactor = $hasActivatedTwoFactorUser && wfConfig::get('loginSec_requireAdminTwoFactor');
|
2110 |
|
2369 |
require('wfLockedOut.php');
|
2370 |
}
|
2371 |
set_transient($tKey, $tries, wfConfig::get('loginSec_countFailMins') * 60);
|
2372 |
+
} else if(is_object($authUser) && get_class($authUser) == 'WP_User'){
|
2373 |
delete_transient($tKey); //reset counter on success
|
2374 |
}
|
2375 |
}
|
2427 |
}
|
2428 |
|
2429 |
try {
|
2430 |
+
$response = wp_remote_post((wfConfig::get('useNoc3Secure') ? WORDFENCE_HACKATTEMPT_URL_SEC : WORDFENCE_HACKATTEMPT_URL) . 'multipleHackAttempts/?k=' . rawurlencode(wfConfig::get('apiKey')) . '&t=brute', array(
|
2431 |
'timeout' => 1,
|
2432 |
'user-agent' => "Wordfence.com UA " . (defined('WORDFENCE_VERSION') ? WORDFENCE_VERSION : '[Unknown version]'),
|
2433 |
'body' => 'IPs=' . rawurlencode(json_encode($toSend)),
|
2499 |
$toSend = array_values($toSend);
|
2500 |
|
2501 |
try {
|
2502 |
+
$response = wp_remote_post((wfConfig::get('useNoc3Secure') ? WORDFENCE_HACKATTEMPT_URL_SEC : WORDFENCE_HACKATTEMPT_URL) . 'multipleHackAttempts/?k=' . rawurlencode(wfConfig::get('apiKey')) . '&t=brute', array(
|
2503 |
'timeout' => 1,
|
2504 |
'user-agent' => "Wordfence.com UA " . (defined('WORDFENCE_VERSION') ? WORDFENCE_VERSION : '[Unknown version]'),
|
2505 |
'body' => 'IPs=' . rawurlencode(json_encode($toSend)),
|
2555 |
}
|
2556 |
|
2557 |
try {
|
2558 |
+
$result = wp_remote_get((wfConfig::get('useNoc3Secure') ? WORDFENCE_HACKATTEMPT_URL_SEC : WORDFENCE_HACKATTEMPT_URL) . 'hackAttempt/?k=' . rawurlencode(wfConfig::get('apiKey')) .
|
2559 |
'&IP=' . rawurlencode(filter_var($IP, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) ? wfUtils::inet_aton($IP) : wfUtils::inet_pton($IP)) .
|
2560 |
'&t=' . rawurlencode($hitType) .
|
2561 |
'&type=' . $endpointType,
|
3030 |
//This ensures that if the scan crashes for some reason, the schedule will hold.
|
3031 |
wfScanner::shared()->scheduleScans();
|
3032 |
|
3033 |
+
try {
|
3034 |
+
wfScanEngine::startScan();
|
3035 |
+
}
|
3036 |
+
catch (wfScanEngineTestCallbackFailedException $e) {
|
3037 |
+
wfConfig::set('lastScanCompleted', $e->getMessage());
|
3038 |
+
wfConfig::set('lastScanFailureType', wfIssues::SCAN_FAILED_CALLBACK_TEST_FAILED);
|
3039 |
+
wfUtils::clearScanLock();
|
3040 |
+
}
|
3041 |
+
catch (Exception $e) {
|
3042 |
+
if ($e->getCode() != wfScanEngine::SCAN_MANUALLY_KILLED) {
|
3043 |
+
wfConfig::set('lastScanCompleted', $e->getMessage());
|
3044 |
+
wfConfig::set('lastScanFailureType', wfIssues::SCAN_FAILED_GENERAL);
|
3045 |
+
}
|
3046 |
+
}
|
3047 |
}
|
3048 |
public static function ajax_saveCountryBlocking_callback(){
|
3049 |
if(! wfConfig::get('isPaid')){
|
3073 |
$content .= date(DATE_RFC822, $r['ctime'] + $timeOffset) . '::' . sprintf('%.4f', $r['ctime']) . ':' . $r['level'] . ':' . $r['type'] . '::' . wp_kses_data( (string) $r['msg']) . "\n";
|
3074 |
}
|
3075 |
$content .= "\n\n";
|
3076 |
+
$content .= str_repeat('-', 80);
|
3077 |
+
$content .= "\n\n";
|
3078 |
+
|
3079 |
+
$content .= __('# Scan Issues', 'wordfence') . "\n\n";
|
3080 |
+
$issues = wfIssues::shared()->getIssues(0, 50, 0, 50);
|
3081 |
+
$issueCounts = array_merge(array('new' => 0, 'ignoreP' => 0, 'ignoreC' => 0), wfIssues::shared()->getIssueCounts());
|
3082 |
+
$issueTypes = wfIssues::validIssueTypes();
|
3083 |
+
|
3084 |
+
$content .= sprintf(__('## New Issues (%d total)', 'wordfence'), $issueCounts['new']) . "\n\n";
|
3085 |
+
if (isset($issues['new']) && count($issues['new'])) {
|
3086 |
+
foreach ($issues['new'] as $i) {
|
3087 |
+
if (!in_array($i['type'], $issueTypes)) {
|
3088 |
+
continue;
|
3089 |
+
}
|
3090 |
+
|
3091 |
+
$viewContent = '';
|
3092 |
+
try {
|
3093 |
+
$viewContent = wfView::create('scanner/issue-' . $i['type'], array('textOutput' => $i))->render();
|
3094 |
+
}
|
3095 |
+
catch (wfViewNotFoundException $e) {
|
3096 |
+
//Ignore -- should never happen since we validate the type
|
3097 |
+
}
|
3098 |
+
|
3099 |
+
if (!empty($viewContent)) {
|
3100 |
+
$content .= $viewContent . "\n\n";
|
3101 |
+
}
|
3102 |
+
}
|
3103 |
+
}
|
3104 |
+
else {
|
3105 |
+
$content .= __('No New Issues', 'wordfence') . "\n\n";
|
3106 |
+
}
|
3107 |
+
|
3108 |
+
$content .= str_repeat('-', 10);
|
3109 |
+
$content .= "\n\n";
|
3110 |
+
|
3111 |
+
$content .= sprintf(__('## Ignored Issues (%d total)', 'wordfence'), $issueCounts['ignoreP'] + $issueCounts['ignoreC']) . "\n\n";
|
3112 |
+
if (isset($issues['new']) && count($issues['new'])) {
|
3113 |
+
foreach ($issues['ignored'] as $i) {
|
3114 |
+
if (!in_array($i['type'], $issueTypes)) {
|
3115 |
+
continue;
|
3116 |
+
}
|
3117 |
+
|
3118 |
+
$viewContent = '';
|
3119 |
+
try {
|
3120 |
+
$viewContent = wfView::create('scanner/issue-' . $i['type'], array('textOutput' => $i))->render();
|
3121 |
+
}
|
3122 |
+
catch (wfViewNotFoundException $e) {
|
3123 |
+
//Ignore -- should never happen since we validate the type
|
3124 |
+
}
|
3125 |
+
|
3126 |
+
if (!empty($viewContent)) {
|
3127 |
+
$content .= $viewContent . "\n\n";
|
3128 |
+
}
|
3129 |
+
}
|
3130 |
+
}
|
3131 |
+
else {
|
3132 |
+
$content .= __('No Ignored Issues', 'wordfence') . "\n\n";
|
3133 |
+
}
|
3134 |
+
|
3135 |
+
$content .= str_repeat('-', 80);
|
3136 |
+
$content .= "\n\n";
|
3137 |
|
3138 |
ob_start();
|
3139 |
phpinfo();
|
3879 |
wordfence::status(10, 'info', "SUM_KILLED:A request was received to stop the previous scan.");
|
3880 |
wfUtils::clearScanLock(); //Clear the lock now because there may not be a scan running to pick up the kill request and clear the lock
|
3881 |
wfScanEngine::requestKill();
|
3882 |
+
wfConfig::remove('scanStartAttempt');
|
3883 |
wfConfig::set('lastScanFailureType', false);
|
3884 |
return array(
|
3885 |
'ok' => 1,
|
4055 |
'buttonTitle' => __('Close', 'wordfence'),
|
4056 |
))->render();
|
4057 |
break;
|
4058 |
+
case wfIssues::SCAN_FAILED_START_TIMEOUT:
|
4059 |
+
case wfIssues::SCAN_FAILED_CALLBACK_TEST_FAILED:
|
4060 |
+
$scanFailedHTML = wfView::create('scanner/scan-failed', array(
|
4061 |
+
'messageHTML' => __('The scan has failed to start. This is often because the site either cannot make outbound requests or is blocked from connecting to itself.', 'wordfence') . ' <a href="' . wfSupportController::esc_supportURL(wfSupportController::ITEM_SCAN_FAILED_START) . '" target="_blank" rel="noopener noreferrer">' . __('Click here for steps you can try.', 'wordfence') . '</a>',
|
4062 |
+
'buttonTitle' => __('Close', 'wordfence'),
|
4063 |
+
))->render();
|
4064 |
+
break;
|
4065 |
+
case wfIssues::SCAN_FAILED_API_SSL_UNAVAILABLE:
|
4066 |
+
$scanFailedHTML = wfView::create('scanner/scan-failed', array(
|
4067 |
+
'messageHTML' => __('Scans are not functional because SSL is unavailable.', 'wordfence'),
|
4068 |
+
'buttonTitle' => __('Close', 'wordfence'),
|
4069 |
+
))->render();
|
4070 |
+
break;
|
4071 |
+
case wfIssues::SCAN_FAILED_API_CALL_FAILED:
|
4072 |
+
$scanFailedHTML = wfView::create('scanner/scan-failed', array(
|
4073 |
+
'messageHTML' => __('The scan has failed because we were unable to contact the Wordfence servers. Some sites may need adjustments to run scans reliably.', 'wordfence') . ' <a href="' . wfSupportController::esc_supportURL(wfSupportController::ITEM_SCAN_FAILS) . '" target="_blank" rel="noopener noreferrer">' . __('Click here for steps you can try.', 'wordfence') . '</a>',
|
4074 |
+
'buttonTitle' => __('Close', 'wordfence'),
|
4075 |
+
))->render();
|
4076 |
+
break;
|
4077 |
+
case wfIssues::SCAN_FAILED_API_INVALID_RESPONSE:
|
4078 |
+
case wfIssues::SCAN_FAILED_API_ERROR_RESPONSE:
|
4079 |
+
$scanFailedHTML = wfView::create('scanner/scan-failed', array(
|
4080 |
+
'messageHTML' => __('The scan has failed because we received an unexpected response from the Wordfence servers. This may be a temporary error, though some sites may need adjustments to run scans reliably.', 'wordfence') . ' <a href="' . wfSupportController::esc_supportURL(wfSupportController::ITEM_SCAN_FAILS) . '" target="_blank" rel="noopener noreferrer">' . __('Click here for steps you can try.', 'wordfence') . '</a>',
|
4081 |
+
'buttonTitle' => __('Close', 'wordfence'),
|
4082 |
+
))->render();
|
4083 |
+
break;
|
4084 |
}
|
4085 |
|
4086 |
wfUtils::doNotCache();
|
4091 |
'currentScanID' => wfScanner::shared()->lastScanTime(),
|
4092 |
'signatureUpdateTime' => wfConfig::get('signatureUpdateTime'),
|
4093 |
'scanFailedHTML' => $scanFailedHTML,
|
4094 |
+
'scanStalled' => ($scanFailed == wfIssues::SCAN_FAILED_TIMEOUT || $scanFailed == wfIssues::SCAN_FAILED_START_TIMEOUT ? 1 : 0),
|
4095 |
'scanRunning' => wfScanner::shared()->isRunning() ? 1 : 0,
|
4096 |
'scanStages' => $stages,
|
4097 |
'scanStats' => $stats,
|
lib/wordfenceConstants.php
CHANGED
@@ -7,6 +7,7 @@ define('WORDFENCE_API_URL_BASE_NONSEC', WORDFENCE_API_URL_NONSEC . 'v' . WORDFEN
|
|
7 |
define('WORDFENCE_BREACH_URL_BASE_SEC', WORDFENCE_API_URL_SEC . 'passwords/');
|
8 |
define('WORDFENCE_BREACH_URL_BASE_NONSEC', WORDFENCE_API_URL_NONSEC . 'passwords/');
|
9 |
define('WORDFENCE_HACKATTEMPT_URL', 'http://noc3.wordfence.com/');
|
|
|
10 |
define('WORDFENCE_MAX_SCAN_LOCK_TIME', 86400); //Increased this from 10 mins to 1 day because very big scans run for a long time. Users can use kill.
|
11 |
define('WORDFENCE_DEFAULT_MAX_SCAN_TIME', 10800);
|
12 |
define('WORDFENCE_TRANSIENTS_TIMEOUT', 3600); //how long are items cached in seconds e.g. files downloaded for diffing
|
@@ -21,5 +22,6 @@ if (!defined('WORDFENCE_SCAN_ISSUES_PER_PAGE')) { define('WORDFENCE_SCAN_ISSUES_
|
|
21 |
if (!defined('WORDFENCE_BLOCKED_IPS_PER_PAGE')) { define('WORDFENCE_BLOCKED_IPS_PER_PAGE', 100); }
|
22 |
if (!defined('WORDFENCE_DISABLE_FILE_VIEWER')) { define('WORDFENCE_DISABLE_FILE_VIEWER', false); }
|
23 |
if (!defined('WORDFENCE_SCAN_FAILURE_THRESHOLD')) { define('WORDFENCE_SCAN_FAILURE_THRESHOLD', 300); }
|
|
|
24 |
if (!defined('WORDFENCE_PREFER_WP_HOME_FOR_WPML')) { define('WORDFENCE_PREFER_WP_HOME_FOR_WPML', false); } //When determining the unfiltered `home` and `siteurl` with WPML installed, use WP_HOME and WP_SITEURL if set instead of the database values
|
25 |
if (!defined('WORDFENCE_SCAN_MIN_EXECUTION_TIME')) { define('WORDFENCE_SCAN_MIN_EXECUTION_TIME', 8); }
|
7 |
define('WORDFENCE_BREACH_URL_BASE_SEC', WORDFENCE_API_URL_SEC . 'passwords/');
|
8 |
define('WORDFENCE_BREACH_URL_BASE_NONSEC', WORDFENCE_API_URL_NONSEC . 'passwords/');
|
9 |
define('WORDFENCE_HACKATTEMPT_URL', 'http://noc3.wordfence.com/');
|
10 |
+
define('WORDFENCE_HACKATTEMPT_URL_SEC', 'https://noc3.wordfence.com/');
|
11 |
define('WORDFENCE_MAX_SCAN_LOCK_TIME', 86400); //Increased this from 10 mins to 1 day because very big scans run for a long time. Users can use kill.
|
12 |
define('WORDFENCE_DEFAULT_MAX_SCAN_TIME', 10800);
|
13 |
define('WORDFENCE_TRANSIENTS_TIMEOUT', 3600); //how long are items cached in seconds e.g. files downloaded for diffing
|
22 |
if (!defined('WORDFENCE_BLOCKED_IPS_PER_PAGE')) { define('WORDFENCE_BLOCKED_IPS_PER_PAGE', 100); }
|
23 |
if (!defined('WORDFENCE_DISABLE_FILE_VIEWER')) { define('WORDFENCE_DISABLE_FILE_VIEWER', false); }
|
24 |
if (!defined('WORDFENCE_SCAN_FAILURE_THRESHOLD')) { define('WORDFENCE_SCAN_FAILURE_THRESHOLD', 300); }
|
25 |
+
if (!defined('WORDFENCE_SCAN_START_FAILURE_THRESHOLD')) { define('WORDFENCE_SCAN_START_FAILURE_THRESHOLD', 15); }
|
26 |
if (!defined('WORDFENCE_PREFER_WP_HOME_FOR_WPML')) { define('WORDFENCE_PREFER_WP_HOME_FOR_WPML', false); } //When determining the unfiltered `home` and `siteurl` with WPML installed, use WP_HOME and WP_SITEURL if set instead of the database values
|
27 |
if (!defined('WORDFENCE_SCAN_MIN_EXECUTION_TIME')) { define('WORDFENCE_SCAN_MIN_EXECUTION_TIME', 8); }
|
readme.txt
CHANGED
@@ -2,8 +2,9 @@
|
|
2 |
Contributors: mmaunder
|
3 |
Tags: security, firewall, malware scanner, web application firewall, antivirus, block hackers, country blocking, clean hacked site, blacklist, waf, login security
|
4 |
Requires at least: 3.9
|
|
|
5 |
Tested up to: 4.9.5
|
6 |
-
Stable tag: 7.1.
|
7 |
|
8 |
Secure your website with the most comprehensive WordPress security plugin. Firewall, malware scan, blocking, live traffic, login security & more.
|
9 |
|
@@ -167,6 +168,20 @@ Secure your website with Wordfence.
|
|
167 |
|
168 |
== Changelog ==
|
169 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
170 |
= 7.1.2 =
|
171 |
* Improvement: Added support for filtering the blocks list.
|
172 |
* Improvement: Added a flow for generating the WAF autoprepend file and retrieving the path for manual installations.
|
2 |
Contributors: mmaunder
|
3 |
Tags: security, firewall, malware scanner, web application firewall, antivirus, block hackers, country blocking, clean hacked site, blacklist, waf, login security
|
4 |
Requires at least: 3.9
|
5 |
+
Requires PHP: 5.2
|
6 |
Tested up to: 4.9.5
|
7 |
+
Stable tag: 7.1.3
|
8 |
|
9 |
Secure your website with the most comprehensive WordPress security plugin. Firewall, malware scan, blocking, live traffic, login security & more.
|
10 |
|
168 |
|
169 |
== Changelog ==
|
170 |
|
171 |
+
= 7.1.3 =
|
172 |
+
* Improvement: Improved the performance of our config table status check.
|
173 |
+
* Improvement: The IP address of the user activating Wordfence is now used by the breached password check until an admin successfully logs in.
|
174 |
+
* Improvement: Added several new error displays for scan failures to help diagnose and fix issues.
|
175 |
+
* Improvement: Added the block duration to alerts generated when an IP is blocked.
|
176 |
+
* Improvement: A text version of scan results is now included in the activity log email.
|
177 |
+
* Improvement: The WAF install/uninstall process no longer asks to backup files that do not exist.
|
178 |
+
* Change: Began a phased rollout of moving brute force queries to be https-only.
|
179 |
+
* Change: Added the initial deprecation notice for PHP 5.2.
|
180 |
+
* Change: Suppressed a script tag on the diagnostics page from being output in the email version.
|
181 |
+
* Fix: Addressed an issue where plugins that return a null user during authentication would cause a PHP notice to be logged.
|
182 |
+
* Fix: Fixed an issue where plugins that use non-standard version formatting could end up with a inaccurate vulnerability status.
|
183 |
+
* Fix: Added a workaround for web email clients that erroneously encode some URL characters (e.g., #).
|
184 |
+
|
185 |
= 7.1.2 =
|
186 |
* Improvement: Added support for filtering the blocks list.
|
187 |
* Improvement: Added a flow for generating the WAF autoprepend file and retrieving the path for manual installations.
|
views/blocking/block-list.php
CHANGED
@@ -8,7 +8,7 @@ if (!defined('WORDFENCE_VERSION')) { exit; }
|
|
8 |
<div class="wf-row">
|
9 |
<div class="wf-col-xs-12">
|
10 |
<div class="wf-flex-horizontal wf-flex-full-width wf-add-bottom-small">
|
11 |
-
<h3 class="wf-no-top wf-no-bottom"><?php printf(__('
|
12 |
<div class="wf-right">
|
13 |
<div class="wf-inline-block">
|
14 |
<ul class="wf-option wf-option-toggled-boolean-switch wf-option-no-spacing" data-option="displayAutomaticBlocks" data-enabled-value="1" data-disabled-value="0" data-original-value="<?php echo wfConfig::get('displayAutomaticBlocks') ? 1 : 0; ?>">
|
8 |
<div class="wf-row">
|
9 |
<div class="wf-col-xs-12">
|
10 |
<div class="wf-flex-horizontal wf-flex-full-width wf-add-bottom-small">
|
11 |
+
<h3 class="wf-no-top wf-no-bottom"><?php printf(__('Current blocks<span class="wf-hidden-xs"> for %s</span>', 'wordfence'), preg_replace('/^https?:\/\//i', '', wfUtils::wpSiteURL())); ?></h3>
|
12 |
<div class="wf-right">
|
13 |
<div class="wf-inline-block">
|
14 |
<ul class="wf-option wf-option-toggled-boolean-switch wf-option-no-spacing" data-option="displayAutomaticBlocks" data-enabled-value="1" data-disabled-value="0" data-original-value="<?php echo wfConfig::get('displayAutomaticBlocks') ? 1 : 0; ?>">
|
views/scanner/issue-base.php
CHANGED
@@ -11,7 +11,11 @@ if (!defined('WORDFENCE_VERSION')) { exit; }
|
|
11 |
* @var array $summaryControls An array of summary controls for the issue type.
|
12 |
* @var array $detailPairs An array of label/value pairs for the issue's detail data. If the entry should only be conditionally shown, the value may be an array of the format array(conditional, displayValue).
|
13 |
* @var array $detailControls An array of detail controls for the issue type.
|
|
|
|
|
14 |
*/
|
|
|
|
|
15 |
?>
|
16 |
<script type="text/x-jquery-template" id="issueTmpl_<?php echo $internalType; ?>">
|
17 |
<ul class="wf-issue wf-issue-<?php echo $internalType; ?> {{if severity == '1'}}wf-issue-severity-critical{{else}}wf-issue-severity-warning{{/if}}" data-issue-id="${id}" data-issue-type="<?php echo $internalType; ?>" data-issue-severity="${severity}" data-high-sensitivity="{{if (data.highSense == '1')}}1{{else}}0{{/if}}" data-beta-signatures="{{if (data.betaSigs == '1')}}1{{else}}0{{/if}}">
|
@@ -61,3 +65,102 @@ if (!defined('WORDFENCE_VERSION')) { exit; }
|
|
61 |
</li>
|
62 |
</ul>
|
63 |
</script>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
11 |
* @var array $summaryControls An array of summary controls for the issue type.
|
12 |
* @var array $detailPairs An array of label/value pairs for the issue's detail data. If the entry should only be conditionally shown, the value may be an array of the format array(conditional, displayValue).
|
13 |
* @var array $detailControls An array of detail controls for the issue type.
|
14 |
+
* @var array $textOutput If provided, used the content of the array to output plain text rather than the HTML template.
|
15 |
+
* @var array $textOutputDetailPairs An array of label/value pairs for the issue's detail data if outputting via text. If the entry should only be conditionally shown, the value may be an array of the format array(conditional, displayValue) where conditional is one or more keypaths that must all be truthy. It is preprocessed lightly for output: all values prefixed with $ will be treated as keypaths in the $textOutput array. If that is prefixed with ! for the conditional, its value will be inverted.
|
16 |
*/
|
17 |
+
|
18 |
+
if (!isset($textOutput) || !is_array($textOutput)):
|
19 |
?>
|
20 |
<script type="text/x-jquery-template" id="issueTmpl_<?php echo $internalType; ?>">
|
21 |
<ul class="wf-issue wf-issue-<?php echo $internalType; ?> {{if severity == '1'}}wf-issue-severity-critical{{else}}wf-issue-severity-warning{{/if}}" data-issue-id="${id}" data-issue-type="<?php echo $internalType; ?>" data-issue-severity="${severity}" data-high-sensitivity="{{if (data.highSense == '1')}}1{{else}}0{{/if}}" data-beta-signatures="{{if (data.betaSigs == '1')}}1{{else}}0{{/if}}">
|
65 |
</li>
|
66 |
</ul>
|
67 |
</script>
|
68 |
+
<?php else: ?>
|
69 |
+
<?php
|
70 |
+
echo '[' . $displayType . ($textOutput['status'] == 'ignoreP' || $textOutput['status'] == 'ignoreP' ? ', ' . __('Ignored', 'wordfence') : '') . ']' . "\n";
|
71 |
+
echo $textOutput['shortMsg'] . "\n";
|
72 |
+
echo sprintf(__('Issue Found: %s', 'wordfence'), $textOutput['displayTime']) . "\n";
|
73 |
+
echo sprintf(__('Severity: %s', 'wordfence'), $textOutput['severity'] == 1 ? __('Critical', 'wordfence') : __('Warning', 'wordfence')) . "\n";
|
74 |
+
foreach ($textOutputDetailPairs as $label => $value) {
|
75 |
+
if ($value === null) {
|
76 |
+
echo "\n";
|
77 |
+
continue;
|
78 |
+
}
|
79 |
+
|
80 |
+
unset($conditional);
|
81 |
+
if (is_array($value)) {
|
82 |
+
$conditional = $value[0];
|
83 |
+
if (!is_array($conditional)) {
|
84 |
+
$conditional = array($conditional);
|
85 |
+
}
|
86 |
+
$value = $value[1];
|
87 |
+
}
|
88 |
+
|
89 |
+
$allow = true;
|
90 |
+
if (isset($conditional)) {
|
91 |
+
foreach ($conditional as $test) {
|
92 |
+
if (!$allow) {
|
93 |
+
break;
|
94 |
+
}
|
95 |
+
|
96 |
+
if (preg_match('/^!?\$(\S+)/', $test, $matches)) {
|
97 |
+
$invert = (strpos($test, '!') === 0);
|
98 |
+
$components = explode('.', $matches[1]);
|
99 |
+
$tier = $textOutput;
|
100 |
+
foreach ($components as $index => $c) {
|
101 |
+
if (is_array($tier) && !isset($tier[$c])) {
|
102 |
+
if (!$invert) {
|
103 |
+
$allow = false;
|
104 |
+
}
|
105 |
+
break;
|
106 |
+
}
|
107 |
+
|
108 |
+
if ($index == count($components) - 1 && is_array($tier)) {
|
109 |
+
if ((!$tier[$c] && !$invert) || ($tier[$c] && $invert)) {
|
110 |
+
$allow = false;
|
111 |
+
}
|
112 |
+
break;
|
113 |
+
}
|
114 |
+
else if (!is_array($tier)) {
|
115 |
+
$allow = false;
|
116 |
+
break;
|
117 |
+
}
|
118 |
+
|
119 |
+
$tier = $tier[$c];
|
120 |
+
}
|
121 |
+
}
|
122 |
+
}
|
123 |
+
}
|
124 |
+
|
125 |
+
if (!$allow) {
|
126 |
+
continue;
|
127 |
+
}
|
128 |
+
|
129 |
+
if (preg_match_all('/(?<=^|\s)\$(\S+)(?=$|\s)/', $value, $matches, PREG_OFFSET_CAPTURE)) {
|
130 |
+
array_shift($matches);
|
131 |
+
$matches = $matches[0];
|
132 |
+
$matches = array_reverse($matches);
|
133 |
+
foreach ($matches as $m) {
|
134 |
+
$resolvedKeyPath = '';
|
135 |
+
$components = explode('.', $m[0]);
|
136 |
+
$tier = $textOutput;
|
137 |
+
foreach ($components as $index => $c) {
|
138 |
+
if (is_array($tier) && !isset($tier[$c])) {
|
139 |
+
$allow = false;
|
140 |
+
break 2;
|
141 |
+
}
|
142 |
+
|
143 |
+
if ($index == count($components) - 1 && is_array($tier)) {
|
144 |
+
$resolvedKeyPath = (string) $tier[$c];
|
145 |
+
break;
|
146 |
+
}
|
147 |
+
else if (!is_array($tier)) {
|
148 |
+
$allow = false;
|
149 |
+
break 2;
|
150 |
+
}
|
151 |
+
|
152 |
+
$tier = $tier[$c];
|
153 |
+
}
|
154 |
+
|
155 |
+
$value = substr($value, 0, $m[1] - 1) . strip_tags($resolvedKeyPath) . substr($value, $m[1] + strlen($m[0]));
|
156 |
+
}
|
157 |
+
}
|
158 |
+
|
159 |
+
if (!$allow) {
|
160 |
+
continue;
|
161 |
+
}
|
162 |
+
|
163 |
+
echo $label . ': ' . $value . "\n";
|
164 |
+
}
|
165 |
+
?>
|
166 |
+
<?php endif; ?>
|
views/scanner/issue-checkGSB.php
CHANGED
@@ -16,4 +16,10 @@ echo wfView::create('scanner/issue-base', array(
|
|
16 |
'detailControls' => array(
|
17 |
'<a href="#" class="wf-btn wf-btn-default wf-btn-callout-subtle wf-issue-control-mark-fixed">' . __('Mark as Fixed', 'wordfence') . '</a>',
|
18 |
),
|
|
|
|
|
|
|
|
|
|
|
|
|
19 |
))->render();
|
16 |
'detailControls' => array(
|
17 |
'<a href="#" class="wf-btn wf-btn-default wf-btn-callout-subtle wf-issue-control-mark-fixed">' . __('Mark as Fixed', 'wordfence') . '</a>',
|
18 |
),
|
19 |
+
'textOutput' => (isset($textOutput) ? $textOutput : null),
|
20 |
+
'textOutputDetailPairs' => array(
|
21 |
+
__('Bad URL', 'wordfence') => '$data.badURL',
|
22 |
+
null,
|
23 |
+
__('Details', 'wordfence') => '$longMsg',
|
24 |
+
),
|
25 |
))->render();
|
views/scanner/issue-checkHowGetIPs.php
CHANGED
@@ -15,4 +15,8 @@ echo wfView::create('scanner/issue-base', array(
|
|
15 |
'<a href="#" class="wf-btn wf-btn-default wf-btn-callout-subtle" onclick="WFAD.useRecommendedHowGetIPs(\'${id}\'); return false;">' . __('Use Recommended Value', 'wordfence') . '</a>',
|
16 |
'<a href="#" class="wf-btn wf-btn-default wf-btn-callout-subtle wf-issue-control-mark-fixed">' . __('Mark as Fixed', 'wordfence') . '</a>',
|
17 |
),
|
|
|
|
|
|
|
|
|
18 |
))->render();
|
15 |
'<a href="#" class="wf-btn wf-btn-default wf-btn-callout-subtle" onclick="WFAD.useRecommendedHowGetIPs(\'${id}\'); return false;">' . __('Use Recommended Value', 'wordfence') . '</a>',
|
16 |
'<a href="#" class="wf-btn wf-btn-default wf-btn-callout-subtle wf-issue-control-mark-fixed">' . __('Mark as Fixed', 'wordfence') . '</a>',
|
17 |
),
|
18 |
+
'textOutput' => (isset($textOutput) ? $textOutput : null),
|
19 |
+
'textOutputDetailPairs' => array(
|
20 |
+
__('Details', 'wordfence') => '$longMsg',
|
21 |
+
),
|
22 |
))->render();
|
views/scanner/issue-checkSpamIP.php
CHANGED
@@ -14,4 +14,8 @@ echo wfView::create('scanner/issue-base', array(
|
|
14 |
'detailControls' => array(
|
15 |
'<a href="#" class="wf-btn wf-btn-default wf-btn-callout-subtle wf-issue-control-mark-fixed">' . __('Mark as Fixed', 'wordfence') . '</a>',
|
16 |
),
|
|
|
|
|
|
|
|
|
17 |
))->render();
|
14 |
'detailControls' => array(
|
15 |
'<a href="#" class="wf-btn wf-btn-default wf-btn-callout-subtle wf-issue-control-mark-fixed">' . __('Mark as Fixed', 'wordfence') . '</a>',
|
16 |
),
|
17 |
+
'textOutput' => (isset($textOutput) ? $textOutput : null),
|
18 |
+
'textOutputDetailPairs' => array(
|
19 |
+
__('Details', 'wordfence') => '$longMsg',
|
20 |
+
),
|
21 |
))->render();
|
views/scanner/issue-commentBadURL.php
CHANGED
@@ -21,5 +21,17 @@ echo wfView::create('scanner/issue-base', array(
|
|
21 |
),
|
22 |
'detailControls' => array(
|
23 |
'<a href="#" class="wf-btn wf-btn-default wf-btn-callout-subtle wf-issue-control-mark-fixed">' . __('Mark as Fixed', 'wordfence') . '</a>',
|
24 |
-
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
25 |
))->render();
|
21 |
),
|
22 |
'detailControls' => array(
|
23 |
'<a href="#" class="wf-btn wf-btn-default wf-btn-callout-subtle wf-issue-control-mark-fixed">' . __('Mark as Fixed', 'wordfence') . '</a>',
|
24 |
+
),
|
25 |
+
'textOutput' => (isset($textOutput) ? $textOutput : null),
|
26 |
+
'textOutputDetailPairs' => array(
|
27 |
+
__('Author', 'wordfence') => '$data.author',
|
28 |
+
__('Bad URL', 'wordfence') => '$data.badURL',
|
29 |
+
__('Posted on', 'wordfence') => '$data.commentDate',
|
30 |
+
null,
|
31 |
+
__('Details', 'wordfence') => '$longMsg',
|
32 |
+
null,
|
33 |
+
__('Multisite Blog ID', 'wordfence') => array('$data.isMultisite', '$data.blog_id'),
|
34 |
+
__('Multisite Blog Domain', 'wordfence') => array('$data.isMultisite', '$data.domain'),
|
35 |
+
__('Multisite Blog Path', 'wordfence') => array('$data.isMultisite', '$data.path'),
|
36 |
+
),
|
37 |
))->render();
|
views/scanner/issue-configReadable.php
CHANGED
@@ -17,5 +17,11 @@ echo wfView::create('scanner/issue-base', array(
|
|
17 |
'{{if data.fileExists}}<a target="_blank" class="wf-btn wf-btn-default wf-btn-callout-subtle" rel="noopener noreferrer" href="${WFAD.makeViewFileLink(data.file)}">' . __('View File', 'wordfence') . '</a>{{/if}}',
|
18 |
'{{if data.canDelete}}<a href="#" class="wf-btn wf-btn-default wf-btn-callout-subtle wf-issue-control-delete-file">' . __('Delete File', 'wordfence') . '</a>{{/if}}',
|
19 |
'<a href="#" class="wf-btn wf-btn-default wf-btn-callout-subtle wf-issue-control-mark-fixed">' . __('Mark as Fixed', 'wordfence') . '</a>',
|
20 |
-
)
|
|
|
|
|
|
|
|
|
|
|
|
|
21 |
))->render();
|
17 |
'{{if data.fileExists}}<a target="_blank" class="wf-btn wf-btn-default wf-btn-callout-subtle" rel="noopener noreferrer" href="${WFAD.makeViewFileLink(data.file)}">' . __('View File', 'wordfence') . '</a>{{/if}}',
|
18 |
'{{if data.canDelete}}<a href="#" class="wf-btn wf-btn-default wf-btn-callout-subtle wf-issue-control-delete-file">' . __('Delete File', 'wordfence') . '</a>{{/if}}',
|
19 |
'<a href="#" class="wf-btn wf-btn-default wf-btn-callout-subtle wf-issue-control-mark-fixed">' . __('Mark as Fixed', 'wordfence') . '</a>',
|
20 |
+
),
|
21 |
+
'textOutput' => (isset($textOutput) ? $textOutput : null),
|
22 |
+
'textOutputDetailPairs' => array(
|
23 |
+
__('URL', 'wordfence') => '$data.url',
|
24 |
+
null,
|
25 |
+
__('Details', 'wordfence') => '$longMsg',
|
26 |
+
),
|
27 |
))->render();
|
views/scanner/issue-coreUnknown.php
CHANGED
@@ -13,5 +13,9 @@ echo wfView::create('scanner/issue-base', array(
|
|
13 |
'{{if data.fileExists}}<a target="_blank" class="wf-btn wf-btn-default wf-btn-callout-subtle" rel="noopener noreferrer" href="${WFAD.makeViewFileLink(data.file)}">' . __('View File', 'wordfence') . '</a>{{/if}}',
|
14 |
'{{if data.canDelete}}<a href="#" class="wf-btn wf-btn-default wf-btn-callout-subtle wf-issue-control-delete-file">' . __('Delete File', 'wordfence') . '</a>{{/if}}',
|
15 |
'<a href="#" class="wf-btn wf-btn-default wf-btn-callout-subtle wf-issue-control-mark-fixed">' . __('Mark as Fixed', 'wordfence') . '</a>',
|
16 |
-
)
|
|
|
|
|
|
|
|
|
17 |
))->render();
|
13 |
'{{if data.fileExists}}<a target="_blank" class="wf-btn wf-btn-default wf-btn-callout-subtle" rel="noopener noreferrer" href="${WFAD.makeViewFileLink(data.file)}">' . __('View File', 'wordfence') . '</a>{{/if}}',
|
14 |
'{{if data.canDelete}}<a href="#" class="wf-btn wf-btn-default wf-btn-callout-subtle wf-issue-control-delete-file">' . __('Delete File', 'wordfence') . '</a>{{/if}}',
|
15 |
'<a href="#" class="wf-btn wf-btn-default wf-btn-callout-subtle wf-issue-control-mark-fixed">' . __('Mark as Fixed', 'wordfence') . '</a>',
|
16 |
+
),
|
17 |
+
'textOutput' => (isset($textOutput) ? $textOutput : null),
|
18 |
+
'textOutputDetailPairs' => array(
|
19 |
+
__('Details', 'wordfence') => '$longMsg',
|
20 |
+
),
|
21 |
))->render();
|
views/scanner/issue-database.php
CHANGED
@@ -19,4 +19,11 @@ echo wfView::create('scanner/issue-base', array(
|
|
19 |
'{{if data.canDelete}}<a href="#" class="wf-btn wf-btn-default wf-btn-callout-subtle" onclick="WFAD.deleteDatabaseOption(\'${id}\'); return false;">' . __('Delete Option', 'wordfence') . '</a>{{/if}}',
|
20 |
'<a href="#" class="wf-btn wf-btn-default wf-btn-callout-subtle wf-issue-control-mark-fixed">' . __('Mark as Fixed', 'wordfence') . '</a>',
|
21 |
),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
22 |
))->render();
|
19 |
'{{if data.canDelete}}<a href="#" class="wf-btn wf-btn-default wf-btn-callout-subtle" onclick="WFAD.deleteDatabaseOption(\'${id}\'); return false;">' . __('Delete Option', 'wordfence') . '</a>{{/if}}',
|
20 |
'<a href="#" class="wf-btn wf-btn-default wf-btn-callout-subtle wf-issue-control-mark-fixed">' . __('Mark as Fixed', 'wordfence') . '</a>',
|
21 |
),
|
22 |
+
'textOutput' => (isset($textOutput) ? $textOutput : null),
|
23 |
+
'textOutputDetailPairs' => array(
|
24 |
+
__('Option Name', 'wordfence') => '$data.option_name',
|
25 |
+
__('Bad URL', 'wordfence') => '$data.badURL',
|
26 |
+
null,
|
27 |
+
__('Details', 'wordfence') => '$longMsg',
|
28 |
+
),
|
29 |
))->render();
|
views/scanner/issue-diskSpace.php
CHANGED
@@ -15,5 +15,11 @@ echo wfView::create('scanner/issue-base', array(
|
|
15 |
),
|
16 |
'detailControls' => array(
|
17 |
'<a href="#" class="wf-btn wf-btn-default wf-btn-callout-subtle wf-issue-control-mark-fixed">' . __('Mark as Fixed', 'wordfence') . '</a>',
|
18 |
-
)
|
|
|
|
|
|
|
|
|
|
|
|
|
19 |
))->render();
|
15 |
),
|
16 |
'detailControls' => array(
|
17 |
'<a href="#" class="wf-btn wf-btn-default wf-btn-callout-subtle wf-issue-control-mark-fixed">' . __('Mark as Fixed', 'wordfence') . '</a>',
|
18 |
+
),
|
19 |
+
'textOutput' => (isset($textOutput) ? $textOutput : null),
|
20 |
+
'textOutputDetailPairs' => array(
|
21 |
+
__('Space Remaining', 'wordfence') => '$data.spaceLeft',
|
22 |
+
null,
|
23 |
+
__('Details', 'wordfence') => '$longMsg',
|
24 |
+
),
|
25 |
))->render();
|
views/scanner/issue-dnsChange.php
CHANGED
@@ -16,5 +16,12 @@ echo wfView::create('scanner/issue-base', array(
|
|
16 |
),
|
17 |
'detailControls' => array(
|
18 |
'<a href="#" class="wf-btn wf-btn-default wf-btn-callout-subtle wf-issue-control-mark-fixed">' . __('Mark as Fixed', 'wordfence') . '</a>',
|
19 |
-
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
20 |
))->render();
|
16 |
),
|
17 |
'detailControls' => array(
|
18 |
'<a href="#" class="wf-btn wf-btn-default wf-btn-callout-subtle wf-issue-control-mark-fixed">' . __('Mark as Fixed', 'wordfence') . '</a>',
|
19 |
+
),
|
20 |
+
'textOutput' => (isset($textOutput) ? $textOutput : null),
|
21 |
+
'textOutputDetailPairs' => array(
|
22 |
+
__('Old DNS Records', 'wordfence') => '$data.oldDNS',
|
23 |
+
__('New DNS Records', 'wordfence') => '$data.newDNS',
|
24 |
+
null,
|
25 |
+
__('Details', 'wordfence') => '$longMsg',
|
26 |
+
),
|
27 |
))->render();
|
views/scanner/issue-easyPassword.php
CHANGED
@@ -17,5 +17,13 @@ echo wfView::create('scanner/issue-base', array(
|
|
17 |
),
|
18 |
'detailControls' => array(
|
19 |
'<a href="#" class="wf-btn wf-btn-default wf-btn-callout-subtle wf-issue-control-mark-fixed">' . __('Mark as Fixed', 'wordfence') . '</a>',
|
20 |
-
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
21 |
))->render();
|
17 |
),
|
18 |
'detailControls' => array(
|
19 |
'<a href="#" class="wf-btn wf-btn-default wf-btn-callout-subtle wf-issue-control-mark-fixed">' . __('Mark as Fixed', 'wordfence') . '</a>',
|
20 |
+
),
|
21 |
+
'textOutput' => (isset($textOutput) ? $textOutput : null),
|
22 |
+
'textOutputDetailPairs' => array(
|
23 |
+
__('Login Name', 'wordfence') => '$data.user_login',
|
24 |
+
__('User Email', 'wordfence') => '$data.user_email',
|
25 |
+
__('Full Name', 'wordfence') => '$data.first_name $data.last_name',
|
26 |
+
null,
|
27 |
+
__('Details', 'wordfence') => '$longMsg',
|
28 |
+
),
|
29 |
))->render();
|
views/scanner/issue-file.php
CHANGED
@@ -20,5 +20,15 @@ echo wfView::create('scanner/issue-base', array(
|
|
20 |
'{{if data.canDiff}}<a target="_blank" class="wf-btn wf-btn-default wf-btn-callout-subtle" rel="noopener noreferrer" href="${WFAD.makeDiffLink(data)}">' . __('View Differences', 'wordfence') . '</a>{{/if}}',
|
21 |
'{{if data.canDelete}}<a href="#" class="wf-btn wf-btn-default wf-btn-callout-subtle wf-issue-control-delete-file">' . __('Delete File', 'wordfence') . '</a>{{/if}}',
|
22 |
'<a href="#" class="wf-btn wf-btn-default wf-btn-callout-subtle wf-issue-control-mark-fixed">' . __('Mark as Fixed', 'wordfence') . '</a>',
|
23 |
-
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
24 |
))->render();
|
20 |
'{{if data.canDiff}}<a target="_blank" class="wf-btn wf-btn-default wf-btn-callout-subtle" rel="noopener noreferrer" href="${WFAD.makeDiffLink(data)}">' . __('View Differences', 'wordfence') . '</a>{{/if}}',
|
21 |
'{{if data.canDelete}}<a href="#" class="wf-btn wf-btn-default wf-btn-callout-subtle wf-issue-control-delete-file">' . __('Delete File', 'wordfence') . '</a>{{/if}}',
|
22 |
'<a href="#" class="wf-btn wf-btn-default wf-btn-callout-subtle wf-issue-control-mark-fixed">' . __('Mark as Fixed', 'wordfence') . '</a>',
|
23 |
+
),
|
24 |
+
'textOutput' => (isset($textOutput) ? $textOutput : null),
|
25 |
+
'textOutputDetailPairs' => array(
|
26 |
+
__('Filename', 'wordfence') => '$data.file',
|
27 |
+
__('File Type', 'wordfence') => '$data.ucType',
|
28 |
+
__('File Type', 'wordfence') => '$data.wpconfig',
|
29 |
+
__('File Type', 'wordfence') => array(array('!$data.ucType', '!$data.wpconfig'), 'Not a core, theme, or plugin file from wordpress.org'),
|
30 |
+
__('Bad URL', 'wordfence') => '$data.badURL',
|
31 |
+
null,
|
32 |
+
__('Details', 'wordfence') => '$longMsg',
|
33 |
+
),
|
34 |
))->render();
|
views/scanner/issue-geoipSupport.php
CHANGED
@@ -13,5 +13,9 @@ echo wfView::create('scanner/issue-base', array(
|
|
13 |
),
|
14 |
'detailControls' => array(
|
15 |
'<a href="#" class="wf-btn wf-btn-default wf-btn-callout-subtle wf-issue-control-mark-fixed">' . __('Mark as Fixed', 'wordfence') . '</a>',
|
16 |
-
)
|
|
|
|
|
|
|
|
|
17 |
))->render();
|
13 |
),
|
14 |
'detailControls' => array(
|
15 |
'<a href="#" class="wf-btn wf-btn-default wf-btn-callout-subtle wf-issue-control-mark-fixed">' . __('Mark as Fixed', 'wordfence') . '</a>',
|
16 |
+
),
|
17 |
+
'textOutput' => (isset($textOutput) ? $textOutput : null),
|
18 |
+
'textOutputDetailPairs' => array(
|
19 |
+
__('Details', 'wordfence') => '$longMsg',
|
20 |
+
),
|
21 |
))->render();
|
views/scanner/issue-knownfile.php
CHANGED
@@ -20,5 +20,14 @@ echo wfView::create('scanner/issue-base', array(
|
|
20 |
'{{if data.canDiff}}<a target="_blank" class="wf-btn wf-btn-default wf-btn-callout-subtle" rel="noopener noreferrer" href="${WFAD.makeDiffLink(data)}">' . __('View Differences', 'wordfence') . '</a>{{/if}}',
|
21 |
'{{if data.canDelete}}<a href="#" class="wf-btn wf-btn-default wf-btn-callout-subtle wf-issue-control-delete-file">' . __('Delete File', 'wordfence') . '</a>{{/if}}',
|
22 |
'<a href="#" class="wf-btn wf-btn-default wf-btn-callout-subtle wf-issue-control-mark-fixed">' . __('Mark as Fixed', 'wordfence') . '</a>',
|
23 |
-
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
24 |
))->render();
|
20 |
'{{if data.canDiff}}<a target="_blank" class="wf-btn wf-btn-default wf-btn-callout-subtle" rel="noopener noreferrer" href="${WFAD.makeDiffLink(data)}">' . __('View Differences', 'wordfence') . '</a>{{/if}}',
|
21 |
'{{if data.canDelete}}<a href="#" class="wf-btn wf-btn-default wf-btn-callout-subtle wf-issue-control-delete-file">' . __('Delete File', 'wordfence') . '</a>{{/if}}',
|
22 |
'<a href="#" class="wf-btn wf-btn-default wf-btn-callout-subtle wf-issue-control-mark-fixed">' . __('Mark as Fixed', 'wordfence') . '</a>',
|
23 |
+
),
|
24 |
+
'textOutput' => (isset($textOutput) ? $textOutput : null),
|
25 |
+
'textOutputDetailPairs' => array(
|
26 |
+
__('Filename', 'wordfence') => '$data.file',
|
27 |
+
__('File Type', 'wordfence') => '$data.ucType',
|
28 |
+
__('File Type', 'wordfence') => array('!$data.ucType', 'Not a core, theme, or plugin file from wordpress.org'),
|
29 |
+
__('Bad URL', 'wordfence') => '$data.badURL',
|
30 |
+
null,
|
31 |
+
__('Details', 'wordfence') => '$longMsg',
|
32 |
+
),
|
33 |
))->render();
|
views/scanner/issue-optionBadURL.php
CHANGED
@@ -21,4 +21,15 @@ echo wfView::create('scanner/issue-base', array(
|
|
21 |
'detailControls' => array(
|
22 |
'<a href="#" class="wf-btn wf-btn-default wf-btn-callout-subtle wf-issue-control-mark-fixed">' . __('Mark as Fixed', 'wordfence') . '</a>',
|
23 |
),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
24 |
))->render();
|
21 |
'detailControls' => array(
|
22 |
'<a href="#" class="wf-btn wf-btn-default wf-btn-callout-subtle wf-issue-control-mark-fixed">' . __('Mark as Fixed', 'wordfence') . '</a>',
|
23 |
),
|
24 |
+
'textOutput' => (isset($textOutput) ? $textOutput : null),
|
25 |
+
'textOutputDetailPairs' => array(
|
26 |
+
__('Option Name', 'wordfence') => '$data.optionKey',
|
27 |
+
__('Bad URL', 'wordfence') => '$data.badURL',
|
28 |
+
null,
|
29 |
+
__('Details', 'wordfence') => '$longMsg',
|
30 |
+
null,
|
31 |
+
__('Multisite Blog ID', 'wordfence') => array('$data.isMultisite', '$data.blog_id'),
|
32 |
+
__('Multisite Blog Domain', 'wordfence') => array('$data.isMultisite', '$data.domain'),
|
33 |
+
__('Multisite Blog Path', 'wordfence') => array('$data.isMultisite', '$data.path'),
|
34 |
+
),
|
35 |
))->render();
|
views/scanner/issue-postBadTitle.php
CHANGED
@@ -20,5 +20,16 @@ echo wfView::create('scanner/issue-base', array(
|
|
20 |
),
|
21 |
'detailControls' => array(
|
22 |
'<a href="#" class="wf-btn wf-btn-default wf-btn-callout-subtle wf-issue-control-mark-fixed">' . __('Mark as Fixed', 'wordfence') . '</a>',
|
23 |
-
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
24 |
))->render();
|
20 |
),
|
21 |
'detailControls' => array(
|
22 |
'<a href="#" class="wf-btn wf-btn-default wf-btn-callout-subtle wf-issue-control-mark-fixed">' . __('Mark as Fixed', 'wordfence') . '</a>',
|
23 |
+
),
|
24 |
+
'textOutput' => (isset($textOutput) ? $textOutput : null),
|
25 |
+
'textOutputDetailPairs' => array(
|
26 |
+
__('Title', 'wordfence') => '$data.postTitle',
|
27 |
+
__('Posted on', 'wordfence') => '$data.postDate',
|
28 |
+
null,
|
29 |
+
__('Details', 'wordfence') => '$longMsg',
|
30 |
+
null,
|
31 |
+
__('Multisite Blog ID', 'wordfence') => array('$data.isMultisite', '$data.blog_id'),
|
32 |
+
__('Multisite Blog Domain', 'wordfence') => array('$data.isMultisite', '$data.domain'),
|
33 |
+
__('Multisite Blog Path', 'wordfence') => array('$data.isMultisite', '$data.path'),
|
34 |
+
),
|
35 |
))->render();
|
views/scanner/issue-postBadURL.php
CHANGED
@@ -21,5 +21,17 @@ echo wfView::create('scanner/issue-base', array(
|
|
21 |
),
|
22 |
'detailControls' => array(
|
23 |
'<a href="#" class="wf-btn wf-btn-default wf-btn-callout-subtle wf-issue-control-mark-fixed">' . __('Mark as Fixed', 'wordfence') . '</a>',
|
24 |
-
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
25 |
))->render();
|
21 |
),
|
22 |
'detailControls' => array(
|
23 |
'<a href="#" class="wf-btn wf-btn-default wf-btn-callout-subtle wf-issue-control-mark-fixed">' . __('Mark as Fixed', 'wordfence') . '</a>',
|
24 |
+
),
|
25 |
+
'textOutput' => (isset($textOutput) ? $textOutput : null),
|
26 |
+
'textOutputDetailPairs' => array(
|
27 |
+
__('Title', 'wordfence') => '$data.postTitle',
|
28 |
+
__('Bad URL', 'wordfence') => '$data.badURL',
|
29 |
+
__('Posted on', 'wordfence') => '$data.postDate',
|
30 |
+
null,
|
31 |
+
__('Details', 'wordfence') => '$longMsg',
|
32 |
+
null,
|
33 |
+
__('Multisite Blog ID', 'wordfence') => array('$data.isMultisite', '$data.blog_id'),
|
34 |
+
__('Multisite Blog Domain', 'wordfence') => array('$data.isMultisite', '$data.domain'),
|
35 |
+
__('Multisite Blog Path', 'wordfence') => array('$data.isMultisite', '$data.path'),
|
36 |
+
),
|
37 |
))->render();
|
views/scanner/issue-publiclyAccessible.php
CHANGED
@@ -17,5 +17,11 @@ echo wfView::create('scanner/issue-base', array(
|
|
17 |
'{{if data.fileExists}}<a target="_blank" class="wf-btn wf-btn-default wf-btn-callout-subtle" rel="noopener noreferrer" href="${WFAD.makeViewFileLink(data.file)}">' . __('View File', 'wordfence') . '</a>{{/if}}',
|
18 |
'{{if data.canDelete}}<a href="#" class="wf-btn wf-btn-default wf-btn-callout-subtle wf-issue-control-delete-file">' . __('Delete File', 'wordfence') . '</a>{{/if}}',
|
19 |
'<a href="#" class="wf-btn wf-btn-default wf-btn-callout-subtle wf-issue-control-mark-fixed">' . __('Mark as Fixed', 'wordfence') . '</a>',
|
20 |
-
)
|
|
|
|
|
|
|
|
|
|
|
|
|
21 |
))->render();
|
17 |
'{{if data.fileExists}}<a target="_blank" class="wf-btn wf-btn-default wf-btn-callout-subtle" rel="noopener noreferrer" href="${WFAD.makeViewFileLink(data.file)}">' . __('View File', 'wordfence') . '</a>{{/if}}',
|
18 |
'{{if data.canDelete}}<a href="#" class="wf-btn wf-btn-default wf-btn-callout-subtle wf-issue-control-delete-file">' . __('Delete File', 'wordfence') . '</a>{{/if}}',
|
19 |
'<a href="#" class="wf-btn wf-btn-default wf-btn-callout-subtle wf-issue-control-mark-fixed">' . __('Mark as Fixed', 'wordfence') . '</a>',
|
20 |
+
),
|
21 |
+
'textOutput' => (isset($textOutput) ? $textOutput : null),
|
22 |
+
'textOutputDetailPairs' => array(
|
23 |
+
__('URL', 'wordfence') => '$data.url',
|
24 |
+
null,
|
25 |
+
__('Details', 'wordfence') => '$longMsg',
|
26 |
+
),
|
27 |
))->render();
|
views/scanner/issue-spamvertizeCheck.php
CHANGED
@@ -14,4 +14,8 @@ echo wfView::create('scanner/issue-base', array(
|
|
14 |
'detailControls' => array(
|
15 |
'<a href="#" class="wf-btn wf-btn-default wf-btn-callout-subtle wf-issue-control-mark-fixed">' . __('Mark as Fixed', 'wordfence') . '</a>',
|
16 |
),
|
|
|
|
|
|
|
|
|
17 |
))->render();
|
14 |
'detailControls' => array(
|
15 |
'<a href="#" class="wf-btn wf-btn-default wf-btn-callout-subtle wf-issue-control-mark-fixed">' . __('Mark as Fixed', 'wordfence') . '</a>',
|
16 |
),
|
17 |
+
'textOutput' => (isset($textOutput) ? $textOutput : null),
|
18 |
+
'textOutputDetailPairs' => array(
|
19 |
+
__('Details', 'wordfence') => '$longMsg',
|
20 |
+
),
|
21 |
))->render();
|
views/scanner/issue-suspiciousAdminUsers.php
CHANGED
@@ -15,5 +15,9 @@ echo wfView::create('scanner/issue-base', array(
|
|
15 |
'<a href="#" class="wf-btn wf-btn-default wf-btn-callout-subtle" onclick="WFAD.deleteAdminUser(\'${id}\'); return false;">' . __('Delete User', 'wordfence') . '</a>',
|
16 |
'<a href="#" class="wf-btn wf-btn-default wf-btn-callout-subtle" onclick="WFAD.revokeAdminUser(\'${id}\'); return false;">' . __('Revoke Capabilities', 'wordfence') . '</a>',
|
17 |
'<a href="#" class="wf-btn wf-btn-default wf-btn-callout-subtle wf-issue-control-mark-fixed">' . __('Mark as Fixed', 'wordfence') . '</a>',
|
18 |
-
)
|
|
|
|
|
|
|
|
|
19 |
))->render();
|
15 |
'<a href="#" class="wf-btn wf-btn-default wf-btn-callout-subtle" onclick="WFAD.deleteAdminUser(\'${id}\'); return false;">' . __('Delete User', 'wordfence') . '</a>',
|
16 |
'<a href="#" class="wf-btn wf-btn-default wf-btn-callout-subtle" onclick="WFAD.revokeAdminUser(\'${id}\'); return false;">' . __('Revoke Capabilities', 'wordfence') . '</a>',
|
17 |
'<a href="#" class="wf-btn wf-btn-default wf-btn-callout-subtle wf-issue-control-mark-fixed">' . __('Mark as Fixed', 'wordfence') . '</a>',
|
18 |
+
),
|
19 |
+
'textOutput' => (isset($textOutput) ? $textOutput : null),
|
20 |
+
'textOutputDetailPairs' => array(
|
21 |
+
__('Details', 'wordfence') => '$longMsg',
|
22 |
+
),
|
23 |
))->render();
|
views/scanner/issue-timelimit.php
CHANGED
@@ -13,5 +13,9 @@ echo wfView::create('scanner/issue-base', array(
|
|
13 |
),
|
14 |
'detailControls' => array(
|
15 |
'<a href="#" class="wf-btn wf-btn-default wf-btn-callout-subtle wf-issue-control-mark-fixed">' . __('Mark as Fixed', 'wordfence') . '</a>',
|
16 |
-
)
|
|
|
|
|
|
|
|
|
17 |
))->render();
|
13 |
),
|
14 |
'detailControls' => array(
|
15 |
'<a href="#" class="wf-btn wf-btn-default wf-btn-callout-subtle wf-issue-control-mark-fixed">' . __('Mark as Fixed', 'wordfence') . '</a>',
|
16 |
+
),
|
17 |
+
'textOutput' => (isset($textOutput) ? $textOutput : null),
|
18 |
+
'textOutputDetailPairs' => array(
|
19 |
+
__('Details', 'wordfence') => '$longMsg',
|
20 |
+
),
|
21 |
))->render();
|
views/scanner/issue-wfPluginAbandoned.php
CHANGED
@@ -22,5 +22,18 @@ echo wfView::create('scanner/issue-base', array(
|
|
22 |
'detailControls' => array(
|
23 |
'<a href="#" class="wf-btn wf-btn-default wf-btn-callout-subtle wf-issue-control-mark-fixed">' . __('Mark as Fixed', 'wordfence') . '</a>',
|
24 |
'<a href="' . esc_url(network_admin_url('plugins.php')) . '" class="wf-btn wf-btn-default wf-btn-callout-subtle wf-issue-control-manage-plugins">' . __('Manage Plugins', 'wordfence') . '</a>',
|
25 |
-
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
26 |
))->render();
|
22 |
'detailControls' => array(
|
23 |
'<a href="#" class="wf-btn wf-btn-default wf-btn-callout-subtle wf-issue-control-mark-fixed">' . __('Mark as Fixed', 'wordfence') . '</a>',
|
24 |
'<a href="' . esc_url(network_admin_url('plugins.php')) . '" class="wf-btn wf-btn-default wf-btn-callout-subtle wf-issue-control-manage-plugins">' . __('Manage Plugins', 'wordfence') . '</a>',
|
25 |
+
),
|
26 |
+
'textOutput' => (isset($textOutput) ? $textOutput : null),
|
27 |
+
'textOutputDetailPairs' => array(
|
28 |
+
__('Plugin Name', 'wordfence') => '$data.name',
|
29 |
+
__('Current Plugin Version', 'wordfence') => '$data.version',
|
30 |
+
__('Last Updated', 'wordfence') => '$data.dateUpdated',
|
31 |
+
null,
|
32 |
+
__('Details', 'wordfence') => '$longMsg',
|
33 |
+
__('Vulnerability Status', 'wordfence') => array('$data.vulnerable', __('Plugin has unpatched security issues.', 'wordfence')),
|
34 |
+
null,
|
35 |
+
__('Plugin URL', 'wordfence') => '$data.homepage',
|
36 |
+
__('Repository URL', 'wordfence') => '$data.wpURL',
|
37 |
+
__('Vulnerability Information', 'wordfence') => '$data.vulnerabilityLink',
|
38 |
+
),
|
39 |
))->render();
|
views/scanner/issue-wfPluginRemoved.php
CHANGED
@@ -20,6 +20,16 @@ echo wfView::create('scanner/issue-base', array(
|
|
20 |
'detailControls' => array(
|
21 |
'<a href="#" class="wf-btn wf-btn-default wf-btn-callout-subtle wf-issue-control-mark-fixed">' . __('Mark as Fixed', 'wordfence') . '</a>',
|
22 |
'<a href="' . esc_url(network_admin_url('plugins.php')) . '" class="wf-btn wf-btn-default wf-btn-callout-subtle wf-issue-control-manage-plugins">' . __('Manage Plugins', 'wordfence') . '</a>',
|
23 |
-
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
24 |
))->render();
|
25 |
|
20 |
'detailControls' => array(
|
21 |
'<a href="#" class="wf-btn wf-btn-default wf-btn-callout-subtle wf-issue-control-mark-fixed">' . __('Mark as Fixed', 'wordfence') . '</a>',
|
22 |
'<a href="' . esc_url(network_admin_url('plugins.php')) . '" class="wf-btn wf-btn-default wf-btn-callout-subtle wf-issue-control-manage-plugins">' . __('Manage Plugins', 'wordfence') . '</a>',
|
23 |
+
),
|
24 |
+
'textOutput' => (isset($textOutput) ? $textOutput : null),
|
25 |
+
'textOutputDetailPairs' => array(
|
26 |
+
__('Plugin Name', 'wordfence') => '$data.Name',
|
27 |
+
__('Current Plugin Version', 'wordfence') => '$data.Version',
|
28 |
+
null,
|
29 |
+
__('Details', 'wordfence') => '$longMsg',
|
30 |
+
null,
|
31 |
+
__('Plugin URL', 'wordfence') => '$data.PluginURI',
|
32 |
+
__('Vulnerability Information', 'wordfence') => '$data.vulnerabilityLink',
|
33 |
+
),
|
34 |
))->render();
|
35 |
|
views/scanner/issue-wfPluginUpgrade.php
CHANGED
@@ -22,5 +22,18 @@ echo wfView::create('scanner/issue-base', array(
|
|
22 |
'detailControls' => array(
|
23 |
'<a href="#" class="wf-btn wf-btn-default wf-btn-callout-subtle wf-issue-control-mark-fixed">' . __('Mark as Fixed', 'wordfence') . '</a>',
|
24 |
'<a href="' . esc_url(network_admin_url('update-core.php')) . '" class="wf-btn wf-btn-default wf-btn-callout-subtle wf-issue-control-view-updates">' . __('View Updates', 'wordfence') . '</a>',
|
25 |
-
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
26 |
))->render();
|
22 |
'detailControls' => array(
|
23 |
'<a href="#" class="wf-btn wf-btn-default wf-btn-callout-subtle wf-issue-control-mark-fixed">' . __('Mark as Fixed', 'wordfence') . '</a>',
|
24 |
'<a href="' . esc_url(network_admin_url('update-core.php')) . '" class="wf-btn wf-btn-default wf-btn-callout-subtle wf-issue-control-view-updates">' . __('View Updates', 'wordfence') . '</a>',
|
25 |
+
),
|
26 |
+
'textOutput' => (isset($textOutput) ? $textOutput : null),
|
27 |
+
'textOutputDetailPairs' => array(
|
28 |
+
__('Plugin Name', 'wordfence') => '$data.Name',
|
29 |
+
__('Current Plugin Version', 'wordfence') => '$data.Version',
|
30 |
+
__('New Plugin Version', 'wordfence') => '$data.newVersion',
|
31 |
+
null,
|
32 |
+
__('Details', 'wordfence') => '$longMsg',
|
33 |
+
__('Vulnerability Status', 'wordfence') => array('$data.vulnerable', __('Update includes security-related fixes.', 'wordfence')),
|
34 |
+
null,
|
35 |
+
__('Plugin URL', 'wordfence') => '$data.PluginURI',
|
36 |
+
__('Repository URL', 'wordfence') => '$data.wpURL',
|
37 |
+
__('Vulnerability Information', 'wordfence') => '$data.vulnerabilityLink',
|
38 |
+
),
|
39 |
))->render();
|
views/scanner/issue-wfPluginVulnerable.php
CHANGED
@@ -21,5 +21,16 @@ echo wfView::create('scanner/issue-base', array(
|
|
21 |
'detailControls' => array(
|
22 |
'<a href="#" class="wf-btn wf-btn-default wf-btn-callout-subtle wf-issue-control-mark-fixed">' . __('Mark as Fixed', 'wordfence') . '</a>',
|
23 |
'<a href="' . esc_url(network_admin_url('plugins.php')) . '" class="wf-btn wf-btn-default wf-btn-callout-subtle wf-issue-control-manage-plugins">' . __('Manage Plugins', 'wordfence') . '</a>',
|
24 |
-
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
25 |
))->render();
|
21 |
'detailControls' => array(
|
22 |
'<a href="#" class="wf-btn wf-btn-default wf-btn-callout-subtle wf-issue-control-mark-fixed">' . __('Mark as Fixed', 'wordfence') . '</a>',
|
23 |
'<a href="' . esc_url(network_admin_url('plugins.php')) . '" class="wf-btn wf-btn-default wf-btn-callout-subtle wf-issue-control-manage-plugins">' . __('Manage Plugins', 'wordfence') . '</a>',
|
24 |
+
),
|
25 |
+
'textOutput' => (isset($textOutput) ? $textOutput : null),
|
26 |
+
'textOutputDetailPairs' => array(
|
27 |
+
__('Plugin Name', 'wordfence') => '$data.Name',
|
28 |
+
__('Current Plugin Version', 'wordfence') => '$data.Version',
|
29 |
+
null,
|
30 |
+
__('Details', 'wordfence') => '$longMsg',
|
31 |
+
null,
|
32 |
+
__('Plugin URL', 'wordfence') => '$data.PluginURI',
|
33 |
+
__('Repository URL', 'wordfence') => '$data.wpURL',
|
34 |
+
__('Vulnerability Information', 'wordfence') => '$data.vulnerabilityLink',
|
35 |
+
),
|
36 |
))->render();
|
views/scanner/issue-wfThemeUpgrade.php
CHANGED
@@ -21,5 +21,17 @@ echo wfView::create('scanner/issue-base', array(
|
|
21 |
'detailControls' => array(
|
22 |
'<a href="#" class="wf-btn wf-btn-default wf-btn-callout-subtle wf-issue-control-mark-fixed">' . __('Mark as Fixed', 'wordfence') . '</a>',
|
23 |
'<a href="' . esc_url(network_admin_url('update-core.php')) . '" class="wf-btn wf-btn-default wf-btn-callout-subtle wf-issue-control-view-updates">' . __('View Updates', 'wordfence') . '</a>',
|
24 |
-
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
25 |
))->render();
|
21 |
'detailControls' => array(
|
22 |
'<a href="#" class="wf-btn wf-btn-default wf-btn-callout-subtle wf-issue-control-mark-fixed">' . __('Mark as Fixed', 'wordfence') . '</a>',
|
23 |
'<a href="' . esc_url(network_admin_url('update-core.php')) . '" class="wf-btn wf-btn-default wf-btn-callout-subtle wf-issue-control-view-updates">' . __('View Updates', 'wordfence') . '</a>',
|
24 |
+
),
|
25 |
+
'textOutput' => (isset($textOutput) ? $textOutput : null),
|
26 |
+
'textOutputDetailPairs' => array(
|
27 |
+
__('Theme Name', 'wordfence') => '$data.name',
|
28 |
+
__('Current Theme Version', 'wordfence') => '$data.version',
|
29 |
+
__('New Theme Version', 'wordfence') => '$data.newVersion',
|
30 |
+
null,
|
31 |
+
__('Details', 'wordfence') => '$longMsg',
|
32 |
+
__('Vulnerability Status', 'wordfence') => array('$data.vulnerable', __('Update includes security-related fixes.', 'wordfence')),
|
33 |
+
null,
|
34 |
+
__('Theme URL', 'wordfence') => '$data.URL',
|
35 |
+
__('Vulnerability Information', 'wordfence') => '$data.vulnerabilityLink',
|
36 |
+
),
|
37 |
))->render();
|
views/scanner/issue-wfUpgrade.php
CHANGED
@@ -19,5 +19,15 @@ echo wfView::create('scanner/issue-base', array(
|
|
19 |
'detailControls' => array(
|
20 |
'<a href="#" class="wf-btn wf-btn-default wf-btn-callout-subtle wf-issue-control-mark-fixed">' . __('Mark as Fixed', 'wordfence') . '</a>',
|
21 |
'<a href="' . esc_url(network_admin_url('update-core.php')) . '" class="wf-btn wf-btn-default wf-btn-callout-subtle wf-issue-control-view-updates">' . __('View Updates', 'wordfence') . '</a>',
|
22 |
-
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
23 |
))->render();
|
19 |
'detailControls' => array(
|
20 |
'<a href="#" class="wf-btn wf-btn-default wf-btn-callout-subtle wf-issue-control-mark-fixed">' . __('Mark as Fixed', 'wordfence') . '</a>',
|
21 |
'<a href="' . esc_url(network_admin_url('update-core.php')) . '" class="wf-btn wf-btn-default wf-btn-callout-subtle wf-issue-control-view-updates">' . __('View Updates', 'wordfence') . '</a>',
|
22 |
+
),
|
23 |
+
'textOutput' => (isset($textOutput) ? $textOutput : null),
|
24 |
+
'textOutputDetailPairs' => array(
|
25 |
+
__('Current WordPress Version', 'wordfence') => '$data.currentVersion',
|
26 |
+
__('New WordPress Version', 'wordfence') => '$data.newVersion',
|
27 |
+
null,
|
28 |
+
__('Details', 'wordfence') => '$longMsg',
|
29 |
+
__('Vulnerability Status', 'wordfence') => array('$data.vulnerable', __('Update includes security-related fixes.', 'wordfence')),
|
30 |
+
null,
|
31 |
+
__('Vulnerability Information', 'wordfence') => '$data.vulnerabilityLink',
|
32 |
+
),
|
33 |
))->render();
|
views/scanner/issue-wpscan_directoryList.php
CHANGED
@@ -17,5 +17,11 @@ echo wfView::create('scanner/issue-base', array(
|
|
17 |
'{{if data.fileExists}}<a target="_blank" class="wf-btn wf-btn-default wf-btn-callout-subtle" rel="noopener noreferrer" href="${WFAD.makeViewFileLink(data.file)}">' . __('View File', 'wordfence') . '</a>{{/if}}',
|
18 |
'{{if data.canDelete}}<a href="#" class="wf-btn wf-btn-default wf-btn-callout-subtle" onclick="WFAD.deleteFile(\'${id}\'); return false;">' . __('Delete File', 'wordfence') . '</a>{{/if}}',
|
19 |
'<a href="#" class="wf-btn wf-btn-default wf-btn-callout-subtle" onclick="WFAD.updateIssueStatus(\'${id}\', \'delete\'); return false;">' . __('Mark as Fixed', 'wordfence') . '</a>',
|
20 |
-
)
|
|
|
|
|
|
|
|
|
|
|
|
|
21 |
))->render();
|
17 |
'{{if data.fileExists}}<a target="_blank" class="wf-btn wf-btn-default wf-btn-callout-subtle" rel="noopener noreferrer" href="${WFAD.makeViewFileLink(data.file)}">' . __('View File', 'wordfence') . '</a>{{/if}}',
|
18 |
'{{if data.canDelete}}<a href="#" class="wf-btn wf-btn-default wf-btn-callout-subtle" onclick="WFAD.deleteFile(\'${id}\'); return false;">' . __('Delete File', 'wordfence') . '</a>{{/if}}',
|
19 |
'<a href="#" class="wf-btn wf-btn-default wf-btn-callout-subtle" onclick="WFAD.updateIssueStatus(\'${id}\', \'delete\'); return false;">' . __('Mark as Fixed', 'wordfence') . '</a>',
|
20 |
+
),
|
21 |
+
'textOutput' => (isset($textOutput) ? $textOutput : null),
|
22 |
+
'textOutputDetailPairs' => array(
|
23 |
+
__('URL', 'wordfence') => '$data.url',
|
24 |
+
null,
|
25 |
+
__('Details', 'wordfence') => '$longMsg',
|
26 |
+
),
|
27 |
))->render();
|
views/scanner/issue-wpscan_fullPathDiscl.php
CHANGED
@@ -17,5 +17,11 @@ echo wfView::create('scanner/issue-base', array(
|
|
17 |
'{{if data.fileExists}}<a target="_blank" class="wf-btn wf-btn-default wf-btn-callout-subtle" rel="noopener noreferrer" href="${WFAD.makeViewFileLink(data.file)}">' . __('View File', 'wordfence') . '</a>{{/if}}',
|
18 |
'{{if data.canDelete}}<a href="#" class="wf-btn wf-btn-default wf-btn-callout-subtle" onclick="WFAD.deleteFile(\'${id}\'); return false;">' . __('Delete File', 'wordfence') . '</a>{{/if}}',
|
19 |
'<a href="#" class="wf-btn wf-btn-default wf-btn-callout-subtle" onclick="WFAD.updateIssueStatus(\'${id}\', \'delete\'); return false;">' . __('Mark as Fixed', 'wordfence') . '</a>',
|
20 |
-
)
|
|
|
|
|
|
|
|
|
|
|
|
|
21 |
))->render();
|
17 |
'{{if data.fileExists}}<a target="_blank" class="wf-btn wf-btn-default wf-btn-callout-subtle" rel="noopener noreferrer" href="${WFAD.makeViewFileLink(data.file)}">' . __('View File', 'wordfence') . '</a>{{/if}}',
|
18 |
'{{if data.canDelete}}<a href="#" class="wf-btn wf-btn-default wf-btn-callout-subtle" onclick="WFAD.deleteFile(\'${id}\'); return false;">' . __('Delete File', 'wordfence') . '</a>{{/if}}',
|
19 |
'<a href="#" class="wf-btn wf-btn-default wf-btn-callout-subtle" onclick="WFAD.updateIssueStatus(\'${id}\', \'delete\'); return false;">' . __('Mark as Fixed', 'wordfence') . '</a>',
|
20 |
+
),
|
21 |
+
'textOutput' => (isset($textOutput) ? $textOutput : null),
|
22 |
+
'textOutputDetailPairs' => array(
|
23 |
+
__('URL', 'wordfence') => '$data.url',
|
24 |
+
null,
|
25 |
+
__('Details', 'wordfence') => '$longMsg',
|
26 |
+
),
|
27 |
))->render();
|
views/scanner/scan-failed.php
CHANGED
@@ -18,7 +18,7 @@ if (!defined('WORDFENCE_VERSION')) { exit; }
|
|
18 |
<h4><?php _e('Scan Failed', 'wordfence'); ?></h4>
|
19 |
<p><?php echo $messageHTML; ?></p>
|
20 |
</li>
|
21 |
-
<li class="wf-right">
|
22 |
<a href="#" class="wf-btn wf-btn-default wf-btn-callout-subtle" onclick="WFAD.killScan(); return false;"><?php echo $buttonTitle; ?></a>
|
23 |
</li>
|
24 |
</ul>
|
18 |
<h4><?php _e('Scan Failed', 'wordfence'); ?></h4>
|
19 |
<p><?php echo $messageHTML; ?></p>
|
20 |
</li>
|
21 |
+
<li class="wf-right wf-padding-add-left">
|
22 |
<a href="#" class="wf-btn wf-btn-default wf-btn-callout-subtle" onclick="WFAD.killScan(); return false;"><?php echo $buttonTitle; ?></a>
|
23 |
</li>
|
24 |
</ul>
|
views/waf/options-group-basic-firewall.php
CHANGED
@@ -333,8 +333,15 @@ if (!isset($collapseable)) {
|
|
333 |
}
|
334 |
}
|
335 |
|
|
|
336 |
$('.wf-waf-backups').hide();
|
337 |
-
$(
|
|
|
|
|
|
|
|
|
|
|
|
|
338 |
|
339 |
if (nginxNotice.length) { //Install only
|
340 |
if (el.val() == 'nginx') {
|
@@ -405,7 +412,7 @@ if (!isset($collapseable)) {
|
|
405 |
});
|
406 |
|
407 |
if (window.location.hash) {
|
408 |
-
var hashes =
|
409 |
for (var i = 0; i < hashes.length; i++) {
|
410 |
if (hashes[i] == 'configureAutoPrepend') {
|
411 |
$('#wf-waf-install').trigger('click');
|
@@ -419,7 +426,7 @@ if (!isset($collapseable)) {
|
|
419 |
}
|
420 |
|
421 |
$(window).on('hashchange', function () {
|
422 |
-
var hashes =
|
423 |
for (var i = 0; i < hashes.length; i++) {
|
424 |
if (hashes[i] == 'configureAutoPrepend') {
|
425 |
$('#wf-waf-install').trigger('click');
|
333 |
}
|
334 |
}
|
335 |
|
336 |
+
var identifier = '.wf-waf-backups-' + el.val().replace(/[^a-z0-9\-]/i, '');
|
337 |
$('.wf-waf-backups').hide();
|
338 |
+
$(identifier).show();
|
339 |
+
if ($(identifier).find('.wf-waf-backup-file-list').children().length > 0) {
|
340 |
+
$('.wf-waf-download-instructions').show();
|
341 |
+
}
|
342 |
+
else {
|
343 |
+
$('.wf-waf-download-instructions').hide();
|
344 |
+
}
|
345 |
|
346 |
if (nginxNotice.length) { //Install only
|
347 |
if (el.val() == 'nginx') {
|
412 |
});
|
413 |
|
414 |
if (window.location.hash) {
|
415 |
+
var hashes = WFAD.parseHashes();
|
416 |
for (var i = 0; i < hashes.length; i++) {
|
417 |
if (hashes[i] == 'configureAutoPrepend') {
|
418 |
$('#wf-waf-install').trigger('click');
|
426 |
}
|
427 |
|
428 |
$(window).on('hashchange', function () {
|
429 |
+
var hashes = WFAD.parseHashes();
|
430 |
for (var i = 0; i < hashes.length; i++) {
|
431 |
if (hashes[i] == 'configureAutoPrepend') {
|
432 |
$('#wf-waf-install').trigger('click');
|
views/waf/waf-install.php
CHANGED
@@ -71,13 +71,21 @@ if (!defined('WORDFENCE_VERSION')) { exit; }
|
|
71 |
$class = preg_replace('/[^a-z0-9\-]/i', '', $optionValue);
|
72 |
$helper = new wfWAFAutoPrependHelper($optionValue, null);
|
73 |
$backups = $helper->getFilesNeededForBackup();
|
74 |
-
$
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
75 |
?>
|
76 |
<div class="wf-waf-backups wf-waf-backups-<?php echo $class; ?>" style="display: none;" data-backups="<?php echo esc_attr($jsonBackups); ?>">
|
77 |
-
<?php if (count($
|
78 |
<ul class="wf-waf-backup-file-list">
|
79 |
<?php
|
80 |
-
foreach ($
|
81 |
echo '<li><a class="wf-btn wf-btn-default wf-waf-backup-download" data-backup-index="' . $index . '" href="' .
|
82 |
esc_url(add_query_arg(array(
|
83 |
'downloadBackup' => 1,
|
@@ -93,7 +101,7 @@ if (!defined('WORDFENCE_VERSION')) { exit; }
|
|
93 |
</div>
|
94 |
<div class="wf-modal-footer">
|
95 |
<ul class="wf-flex-horizontal wf-flex-full-width">
|
96 |
-
<li><?php _e('Once you have downloaded the files, click Continue to complete the setup.', 'wordfence'); ?></li>
|
97 |
<li class="wf-right"><a href="#" class="wf-btn wf-btn-primary wf-btn-callout-subtle wf-disabled" id="wf-waf-install-continue"><?php _e('Continue', 'wordfence'); ?></a></li>
|
98 |
</ul>
|
99 |
</div>
|
71 |
$class = preg_replace('/[^a-z0-9\-]/i', '', $optionValue);
|
72 |
$helper = new wfWAFAutoPrependHelper($optionValue, null);
|
73 |
$backups = $helper->getFilesNeededForBackup();
|
74 |
+
$filteredBackups = array();
|
75 |
+
foreach ($backups as $index => $backup) {
|
76 |
+
if (!file_exists($backup)) {
|
77 |
+
continue;
|
78 |
+
}
|
79 |
+
|
80 |
+
$filteredBackups[$index] = $backup;
|
81 |
+
}
|
82 |
+
$jsonBackups = json_encode(array_map('basename', $filteredBackups));
|
83 |
?>
|
84 |
<div class="wf-waf-backups wf-waf-backups-<?php echo $class; ?>" style="display: none;" data-backups="<?php echo esc_attr($jsonBackups); ?>">
|
85 |
+
<?php if (count($filteredBackups)): ?><p><?php _e('Please download a backup of the following files before we make the necessary changes:', 'wordfence'); ?></p><?php endif; ?>
|
86 |
<ul class="wf-waf-backup-file-list">
|
87 |
<?php
|
88 |
+
foreach ($filteredBackups as $index => $backup) {
|
89 |
echo '<li><a class="wf-btn wf-btn-default wf-waf-backup-download" data-backup-index="' . $index . '" href="' .
|
90 |
esc_url(add_query_arg(array(
|
91 |
'downloadBackup' => 1,
|
101 |
</div>
|
102 |
<div class="wf-modal-footer">
|
103 |
<ul class="wf-flex-horizontal wf-flex-full-width">
|
104 |
+
<li class="wf-waf-download-instructions"><?php _e('Once you have downloaded the files, click Continue to complete the setup.', 'wordfence'); ?></li>
|
105 |
<li class="wf-right"><a href="#" class="wf-btn wf-btn-primary wf-btn-callout-subtle wf-disabled" id="wf-waf-install-continue"><?php _e('Continue', 'wordfence'); ?></a></li>
|
106 |
</ul>
|
107 |
</div>
|
views/waf/waf-uninstall.php
CHANGED
@@ -58,7 +58,6 @@ if (!defined('WORDFENCE_VERSION')) { exit; }
|
|
58 |
<select name='serverConfiguration' id='wf-waf-server-config'>
|
59 |
<?php echo $wafPrependOptions; ?>
|
60 |
</select>
|
61 |
-
<p><?php _e('Please download a backup of the following files before we make the necessary changes:', 'wordfence'); ?></p>
|
62 |
<?php
|
63 |
$adminURL = network_admin_url('admin.php?page=WordfenceWAF&subpage=waf_options&action=removeAutoPrepend');
|
64 |
$wfnonce = wp_create_nonce('wfWAFRemoveAutoPrepend');
|
@@ -67,12 +66,21 @@ if (!defined('WORDFENCE_VERSION')) { exit; }
|
|
67 |
$class = preg_replace('/[^a-z0-9\-]/i', '', $optionValue);
|
68 |
$helper = new wfWAFAutoPrependHelper($optionValue, null);
|
69 |
$backups = $helper->getFilesNeededForBackup();
|
70 |
-
$
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
71 |
?>
|
72 |
<div class="wf-waf-backups wf-waf-backups-<?php echo $class; ?>" style="display: none;" data-backups="<?php echo esc_attr($jsonBackups); ?>">
|
|
|
73 |
<ul class="wf-waf-backup-file-list">
|
74 |
<?php
|
75 |
-
foreach ($
|
76 |
echo '<li><a class="wf-btn wf-btn-default wf-waf-backup-download" data-backup-index="' . $index . '" href="' .
|
77 |
esc_url(add_query_arg(array(
|
78 |
'downloadBackup' => 1,
|
@@ -89,7 +97,7 @@ if (!defined('WORDFENCE_VERSION')) { exit; }
|
|
89 |
</div>
|
90 |
<div class="wf-modal-footer">
|
91 |
<ul class="wf-flex-horizontal wf-flex-full-width">
|
92 |
-
<li><?php _e('Once you have downloaded the files, click Continue to complete uninstallation.', 'wordfence'); ?></li>
|
93 |
<li class="wf-right"><a href="#" class="wf-btn wf-btn-primary wf-btn-callout-subtle wf-disabled" id="wf-waf-uninstall-continue"><?php _e('Continue', 'wordfence'); ?></a></li>
|
94 |
</ul>
|
95 |
</div>
|
58 |
<select name='serverConfiguration' id='wf-waf-server-config'>
|
59 |
<?php echo $wafPrependOptions; ?>
|
60 |
</select>
|
|
|
61 |
<?php
|
62 |
$adminURL = network_admin_url('admin.php?page=WordfenceWAF&subpage=waf_options&action=removeAutoPrepend');
|
63 |
$wfnonce = wp_create_nonce('wfWAFRemoveAutoPrepend');
|
66 |
$class = preg_replace('/[^a-z0-9\-]/i', '', $optionValue);
|
67 |
$helper = new wfWAFAutoPrependHelper($optionValue, null);
|
68 |
$backups = $helper->getFilesNeededForBackup();
|
69 |
+
$filteredBackups = array();
|
70 |
+
foreach ($backups as $index => $backup) {
|
71 |
+
if (!file_exists($backup)) {
|
72 |
+
continue;
|
73 |
+
}
|
74 |
+
|
75 |
+
$filteredBackups[$index] = $backup;
|
76 |
+
}
|
77 |
+
$jsonBackups = json_encode(array_map('basename', $filteredBackups));
|
78 |
?>
|
79 |
<div class="wf-waf-backups wf-waf-backups-<?php echo $class; ?>" style="display: none;" data-backups="<?php echo esc_attr($jsonBackups); ?>">
|
80 |
+
<?php if (count($filteredBackups)): ?><p><?php _e('Please download a backup of the following files before we make the necessary changes:', 'wordfence'); ?></p><?php endif; ?>
|
81 |
<ul class="wf-waf-backup-file-list">
|
82 |
<?php
|
83 |
+
foreach ($filteredBackups as $index => $backup) {
|
84 |
echo '<li><a class="wf-btn wf-btn-default wf-waf-backup-download" data-backup-index="' . $index . '" href="' .
|
85 |
esc_url(add_query_arg(array(
|
86 |
'downloadBackup' => 1,
|
97 |
</div>
|
98 |
<div class="wf-modal-footer">
|
99 |
<ul class="wf-flex-horizontal wf-flex-full-width">
|
100 |
+
<li class="wf-waf-download-instructions"><?php _e('Once you have downloaded the files, click Continue to complete uninstallation.', 'wordfence'); ?></li>
|
101 |
<li class="wf-right"><a href="#" class="wf-btn wf-btn-primary wf-btn-callout-subtle wf-disabled" id="wf-waf-uninstall-continue"><?php _e('Continue', 'wordfence'); ?></a></li>
|
102 |
</ul>
|
103 |
</div>
|
wordfence.php
CHANGED
@@ -4,15 +4,15 @@ 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: 7.1.
|
8 |
Author URI: http://www.wordfence.com/
|
9 |
Network: true
|
10 |
*/
|
11 |
if(defined('WP_INSTALLING') && WP_INSTALLING){
|
12 |
return;
|
13 |
}
|
14 |
-
define('WORDFENCE_VERSION', '7.1.
|
15 |
-
define('WORDFENCE_BUILD_NUMBER', '
|
16 |
define('WORDFENCE_BASENAME', function_exists('plugin_basename') ? plugin_basename(__FILE__) :
|
17 |
basename(dirname(__FILE__)) . '/' . basename(__FILE__));
|
18 |
|
4 |
Plugin URI: http://www.wordfence.com/
|
5 |
Description: Wordfence Security - Anti-virus, Firewall and Malware Scan
|
6 |
Author: Wordfence
|
7 |
+
Version: 7.1.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', '7.1.3');
|
15 |
+
define('WORDFENCE_BUILD_NUMBER', '1523983877');
|
16 |
define('WORDFENCE_BASENAME', function_exists('plugin_basename') ? plugin_basename(__FILE__) :
|
17 |
basename(dirname(__FILE__)) . '/' . basename(__FILE__));
|
18 |
|