Merged in feature/from-pantheon (pull request #16)
code from pantheon * code from pantheon
This commit is contained in:
228
wp/wp-content/plugins/wordfence/views/waf/debug.php
Normal file
228
wp/wp-content/plugins/wordfence/views/waf/debug.php
Normal file
@@ -0,0 +1,228 @@
|
||||
<?php
|
||||
|
||||
if (!defined('WORDFENCE_VERSION')) { exit; }
|
||||
|
||||
/** @var wfRequestModel $hit */
|
||||
/** @var stdClass $hitData */
|
||||
|
||||
$title = sprintf('Debugging #%d as False Positive', $hit->id);
|
||||
|
||||
$fields = array(
|
||||
'URL' => $hit->URL,
|
||||
'Timestamp' => date('r', $hit->ctime),
|
||||
'IP' => wfUtils::inet_ntop($hit->IP),
|
||||
'Status Code' => $hit->statusCode,
|
||||
'User Agent' => $hit->UA,
|
||||
'Referer' => $hit->referer,
|
||||
);
|
||||
|
||||
if (isset($hitData->fullRequest)) {
|
||||
$requestString = base64_decode($hitData->fullRequest);
|
||||
$request = wfWAFRequest::parseString($requestString);
|
||||
} else {
|
||||
$request = new wfWAFRequest();
|
||||
$request->setAuth(array());
|
||||
$request->setBody(array());
|
||||
$request->setCookies(array());
|
||||
$request->setFileNames(array());
|
||||
$request->setFiles(array());
|
||||
$request->setHeaders(array());
|
||||
$request->setHost('');
|
||||
$request->setIp('');
|
||||
$request->setMethod('GET');
|
||||
$request->setPath('');
|
||||
$request->setProtocol('http');
|
||||
$request->setQueryString(array());
|
||||
$request->setTimestamp('');
|
||||
$request->setUri('');
|
||||
|
||||
$headers = array();
|
||||
$urlPieces = parse_url($hit->URL);
|
||||
if ($urlPieces) {
|
||||
if (array_key_exists('scheme', $urlPieces)) {
|
||||
$request->setProtocol($urlPieces['scheme']);
|
||||
}
|
||||
if (array_key_exists('host', $urlPieces)) {
|
||||
$request->setHost($urlPieces['host']);
|
||||
$headers['Host'] = $urlPieces['host'];
|
||||
}
|
||||
$uri = '/';
|
||||
if (array_key_exists('path', $urlPieces)) {
|
||||
$request->setPath($urlPieces['path']);
|
||||
$uri = $urlPieces['path'];
|
||||
}
|
||||
if (array_key_exists('query', $urlPieces)) {
|
||||
$uri .= '?' . $urlPieces['query'];
|
||||
parse_str($urlPieces['query'], $query);
|
||||
$request->setQueryString($query);
|
||||
}
|
||||
$request->setUri($uri);
|
||||
}
|
||||
$headers['User-Agent'] = $hit->UA;
|
||||
$headers['Referer'] = $hit->referer;
|
||||
$request->setHeaders($headers);
|
||||
|
||||
preg_match('/request\.([a-z]+)(?:\[(.*?)\](.*?))?/i', $hitData->paramKey, $matches);
|
||||
if ($matches) {
|
||||
switch ($matches[1]) {
|
||||
case 'body':
|
||||
$request->setMethod('POST');
|
||||
parse_str("$matches[2]$matches[3]", $body);
|
||||
$request->setBody($body);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$request->setIP(wfUtils::inet_ntop($hit->IP));
|
||||
$request->setTimestamp($hit->ctime);
|
||||
|
||||
|
||||
$waf = wfWAF::getInstance();
|
||||
$waf->setRequest($request);
|
||||
|
||||
$result = '<strong class="ok">Passed</strong>';
|
||||
$failedRules = array();
|
||||
try {
|
||||
$waf->runRules();
|
||||
} catch (wfWAFAllowException $e) {
|
||||
$result = '<strong class="ok">Allowlisted</strong>';
|
||||
} catch (wfWAFBlockException $e) {
|
||||
$result = '<strong class="error">Blocked</strong>';
|
||||
$failedRules = $waf->getFailedRules();
|
||||
} catch (wfWAFBlockSQLiException $e) {
|
||||
$result = '<strong class="error">Blocked For SQLi</strong>';
|
||||
$failedRules = $waf->getFailedRules();
|
||||
} catch (wfWAFBlockXSSException $e) {
|
||||
$result = '<strong class="error">Blocked For XSS</strong>';
|
||||
$failedRules = $waf->getFailedRules();
|
||||
}
|
||||
|
||||
?>
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title><?php echo esc_html($title) ?></title>
|
||||
<link rel="stylesheet" href="<?php echo wfUtils::getBaseURL() . wfUtils::versionedAsset('css/main.css'); ?>">
|
||||
<link rel="stylesheet" href="<?php echo wfLicense::current()->getStylesheet(); ?>">
|
||||
<style>
|
||||
html {
|
||||
font-family: "Open Sans", Helvetica, Arial, sans-serif;
|
||||
}
|
||||
h1, h2, h3, h4, h5 {
|
||||
margin: 20px 0px 8px;
|
||||
}
|
||||
pre, p {
|
||||
margin: 8px 0px 20px;
|
||||
}
|
||||
pre.request-debug {
|
||||
padding: 12px;
|
||||
background: #fafafa;
|
||||
border: 1px solid #999999;
|
||||
overflow: auto;
|
||||
}
|
||||
pre.request-debug em {
|
||||
font-style: normal;
|
||||
padding: 1px;
|
||||
border: 1px solid #ffb463;
|
||||
background-color: #ffffe0;
|
||||
border-radius: 2px;
|
||||
}
|
||||
pre.request-debug strong {
|
||||
border: 1px solid #ff4a35;
|
||||
background-color: #ffefe7;
|
||||
margin: 1px;
|
||||
}
|
||||
.ok {
|
||||
color: #00c000;
|
||||
}
|
||||
.error {
|
||||
color: #ff4a35;
|
||||
}
|
||||
#wrapper {
|
||||
max-width: 1060px;
|
||||
margin: 0px auto;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="wrapper">
|
||||
<h1><?php echo esc_html($title) ?></h1>
|
||||
|
||||
<table class="wf-striped-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th colspan="2">Request Details</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<?php foreach ($fields as $label => $value): ?>
|
||||
<tr>
|
||||
<td><?php echo esc_html($label) ?>:</td>
|
||||
<td><?php echo esc_html($value) ?></td>
|
||||
</tr>
|
||||
<?php endforeach ?>
|
||||
</table>
|
||||
|
||||
<h4>HTTP Request: <?php echo $result ?></h4>
|
||||
<?php if (!isset($hitData->fullRequest)): ?>
|
||||
<em style="font-size: 14px;">This is a reconstruction of the request using what was flagged by the WAF.
|
||||
Full requests are only stored when <code>WFWAF_DEBUG</code> is enabled.</em>
|
||||
<?php endif ?>
|
||||
<pre class="request-debug"><?php
|
||||
$paramKey = wp_hash(uniqid('param', true));
|
||||
$matchKey = wp_hash(uniqid('match', true));
|
||||
|
||||
$template = array(
|
||||
"[$paramKey]" => '<em>',
|
||||
"[/$paramKey]" => '</em>',
|
||||
"[$matchKey]" => '<strong>',
|
||||
"[/$matchKey]" => '</strong>',
|
||||
);
|
||||
$highlightParamFormat = "[$paramKey]%s[/$paramKey]";
|
||||
$highlightMatchFormat = "[$matchKey]%s[/$matchKey]";
|
||||
$requestOut = esc_html($request->highlightFailedParams($failedRules, $highlightParamFormat, $highlightMatchFormat));
|
||||
|
||||
echo str_replace(array_keys($template), $template, $requestOut) ?></pre>
|
||||
|
||||
<?php if ($failedRules): ?>
|
||||
<h4>Failed Rules</h4>
|
||||
<table class="wf-striped-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>Category</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php
|
||||
foreach ($failedRules as $paramKey => $categories) {
|
||||
foreach ($categories as $categoryKey => $failed) {
|
||||
foreach ($failed as $failedRule) {
|
||||
/** @var wfWAFRule $rule */
|
||||
$rule = $failedRule['rule'];
|
||||
printf("<tr><td>%d</td><td>%s</td></tr>", $rule->getRuleID(), $rule->getDescription());
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<?php endif ?>
|
||||
|
||||
<p>
|
||||
<button type="button" id="run-waf-rules">Run Through WAF Rules</button>
|
||||
</p>
|
||||
|
||||
<script>
|
||||
document.getElementById('run-waf-rules').onclick = function() {
|
||||
document.location.href = document.location.href;
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,90 @@
|
||||
<?php
|
||||
if (!defined('WORDFENCE_VERSION')) { exit; }
|
||||
/**
|
||||
* Presents the firewall status.
|
||||
*
|
||||
* Expects $firewall and $dashboard to be defined.
|
||||
*
|
||||
* @var wfFirewall $firewall The firewall state.
|
||||
* @var wfDashboard $dashboard Dashboard statistics.
|
||||
*/
|
||||
?>
|
||||
<ul class="wf-block-list wf-block-list-horizontal">
|
||||
<?php if ($firewall->firewallMode() == 'enabled' && $firewall->ruleMode() == wfFirewall::RULE_MODE_PREMIUM): ?>
|
||||
<li>
|
||||
<div class="wf-block-labeled-value wf-waf-status wf-waf-status-full-enabled">
|
||||
<div class="wf-block-labeled-value-label"><?php
|
||||
switch (wfLicense::current()->getType()) {
|
||||
case wfLicense::TYPE_RESPONSE:
|
||||
esc_html_e('Wordfence Firewall & Response License Enabled', 'wordfence');
|
||||
break;
|
||||
case wfLicense::TYPE_CARE:
|
||||
esc_html_e('Wordfence Firewall & Care License Enabled', 'wordfence');
|
||||
break;
|
||||
default:
|
||||
esc_html_e('Wordfence Firewall & Premium Enabled', 'wordfence');
|
||||
break;
|
||||
}
|
||||
?></div>
|
||||
</div>
|
||||
</li>
|
||||
<?php else: ?>
|
||||
<li>
|
||||
<?php if ($firewall->firewallMode() == wfFirewall::FIREWALL_MODE_DISABLED): ?>
|
||||
<div class="wf-waf-status-disabled">
|
||||
<p><h3><?php esc_html_e('Wordfence Firewall Deactivated', 'wordfence'); ?></h3></p>
|
||||
<p><?php esc_html_e('The Wordfence Web Application Firewall is a PHP-based, application-level firewall that filters out malicious requests to your site. It is designed to run at the beginning of WordPress\' initialization to filter any attacks before plugins or themes can run any potentially vulnerable code.', 'wordfence'); ?></p>
|
||||
<p>
|
||||
<a class="wf-btn wf-btn-primary wf-btn-callout-subtle" href="#" target="_blank" rel="noopener noreferrer" id="waf-top-enable-firewall" role="button"><?php esc_html_e('Enable Firewall', 'wordfence'); ?><span class="screen-reader-text"> (<?php esc_html_e('opens in new tab', 'wordfence') ?>)</span></a>
|
||||
<script type="application/javascript">
|
||||
(function($) {
|
||||
$(function() {
|
||||
$('#waf-top-enable-firewall').on('click', function(e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
WFAD.setOption('wafStatus', 'enabled', function() {
|
||||
window.location.reload(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
})(jQuery);
|
||||
</script>
|
||||
</p>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<?php if ($firewall->firewallMode() == wfFirewall::FIREWALL_MODE_ENABLED): ?>
|
||||
<div class="wf-block-labeled-value wf-waf-status wf-waf-status-<?php echo esc_attr($firewall->firewallMode()); ?>">
|
||||
<div class="wf-block-labeled-value-value"><i class="wf-fa wf-fa-check" aria-hidden="true"></i></div>
|
||||
<div class="wf-block-labeled-value-label"><?php esc_html_e('Wordfence Firewall Activated', 'wordfence'); ?></div>
|
||||
</div>
|
||||
<?php elseif ($firewall->firewallMode() == wfFirewall::FIREWALL_MODE_LEARNING): ?>
|
||||
<div>
|
||||
<?php
|
||||
$learningMode = $firewall->learningModeStatus();
|
||||
if (function_exists('network_admin_url') && is_multisite()) { $optionsURL = network_admin_url('admin.php?page=WordfenceWAF&subpage=waf_options'); }
|
||||
else { $optionsURL = admin_url('admin.php?page=WordfenceWAF&subpage=waf_options'); }
|
||||
?>
|
||||
<p><h3><?php echo ($learningMode === true ? esc_html__('Learning Mode Enabled', 'wordfence') : esc_html(sprintf(/* translators: Localized date. */ __('Learning Mode Until %s', 'wordfence'), wfUtils::formatLocalTime(get_option('date_format'), $learningMode)))); ?></h3></p>
|
||||
<p><?php echo wp_kses(__('<i class="wf-fa wf-fa-lightbulb-o wf-tip" aria-hidden="true"></i> When you first install the Wordfence Web Application Firewall, it will be in learning mode. This allows Wordfence to learn about your site so that we can understand how to protect it and how to allow normal visitors through the firewall. We recommend you let Wordfence learn for a week before you enable the firewall.', 'wordfence'), array('i'=>array('class'=>array()))); ?></p>
|
||||
<p><a class="wf-btn wf-btn-primary wf-btn-callout-subtle" href="<?php echo esc_url($optionsURL); ?>"><?php esc_html_e('Manage Firewall', 'wordfence'); ?></a> <a class="wf-btn wf-btn-callout-subtle wf-btn-default" href="<?php echo wfSupportController::esc_supportURL(wfSupportController::ITEM_FIREWALL_WAF); ?>" target="_blank" rel="noopener noreferrer"><?php esc_html_e('Learn More', 'wordfence'); ?><span class="screen-reader-text"> (<?php esc_html_e('opens in new tab', 'wordfence') ?>)</span></a></p>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<?php endif; ?>
|
||||
</li>
|
||||
<li>
|
||||
<?php if ($firewall->ruleMode() == wfFirewall::RULE_MODE_COMMUNITY): ?>
|
||||
<div>
|
||||
<p><h3><?php esc_html_e('Premium Protection Disabled', 'wordfence'); ?></h3></p>
|
||||
<p><?php esc_html_e('As a free Wordfence user, you are currently using the Community version of the Threat Defense Feed. Premium users are protected by additional firewall rules and malware signatures. Upgrade to Premium today to improve your protection.', 'wordfence'); ?></p>
|
||||
<p><a class="wf-btn wf-btn-primary wf-btn-callout-subtle" href="https://www.wordfence.com/gnl1wafUpgrade/wordfence-signup/#premium-order-form" target="_blank" rel="noopener noreferrer"><?php esc_html_e('Upgrade to Premium', 'wordfence'); ?></a> <a class="wf-btn wf-btn-callout-subtle wf-btn-default" href="https://www.wordfence.com/gnl1wafLearn/wordfence-signup/" target="_blank" rel="noopener noreferrer"><?php esc_html_e('Learn More', 'wordfence'); ?><span class="screen-reader-text"> (<?php esc_html_e('opens in new tab', 'wordfence') ?>)</span></a></p>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<div class="wf-block-labeled-value wf-protection-status wf-protection-status-<?php echo esc_attr($firewall->ruleMode()); ?>">
|
||||
<div class="wf-block-labeled-value-value"><i class="wf-fa wf-fa-check" aria-hidden="true"></i></div>
|
||||
<div class="wf-block-labeled-value-label"><?php esc_html_e('Premium Protection Enabled', 'wordfence'); ?></div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</li>
|
||||
<?php endif; ?>
|
||||
</ul>
|
||||
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
if (!defined('WORDFENCE_VERSION')) { exit; }
|
||||
/**
|
||||
* Presents a rate limit option with popup menus for limit value and action selections.
|
||||
*
|
||||
* Expects $rateOptionName, $rateOptions, $rateValue, $actionOptionName, $actionOptions, $actionValue, and $title to be defined. $helpLink may also be defined.
|
||||
*
|
||||
* @var string $rateOptionName The option name for the rate portion.
|
||||
* @var array $rateOptions An array of the possible values for $rateOptionName. The array is of the format array(array('value' => <the internal value>, 'label' => <a display label>), ...)
|
||||
* @var string $rateValue The current value of $rateOptionName.
|
||||
* @var int $lowValue The value below which the false positive warning should begin showing
|
||||
* @var string $actionOptionName The option name for the rate portion.
|
||||
* @var array $actionOptions An array of the possible values for $actionOptionName. The array is of the format array(array('value' => <the internal value>, 'label' => <a display label>), ...)
|
||||
* @var string $actionValue The current value of $actionOptionName.
|
||||
* @var string $title The title shown for the option.
|
||||
* @var string $helpLink If defined, the link to the corresponding external help page.
|
||||
* @var bool $premium If defined, the option will be tagged as premium only and not allow its value to change for free users.
|
||||
*/
|
||||
|
||||
$rateID = 'wf-option-' . preg_replace('/[^a-z0-9]/i', '-', $rateOptionName);
|
||||
$actionID = 'wf-option-' . preg_replace('/[^a-z0-9]/i', '-', $actionOptionName);
|
||||
?>
|
||||
<ul class="wf-option wf-option-rate-limit<?php if (!wfConfig::p() && isset($premium) && $premium) { echo ' wf-option-premium'; } ?>" data-rate-option="<?php echo esc_attr($rateOptionName); ?>" data-original-rate-value="<?php echo esc_attr($rateValue); ?>" data-action-option="<?php echo esc_attr($actionOptionName); ?>" data-original-action-value="<?php echo esc_attr($actionValue); ?>" data-low-value="<?php echo (int) $lowValue; ?>">
|
||||
<li class="wf-option-spacer"></li>
|
||||
<li class="wf-option-content">
|
||||
<ul>
|
||||
<li class="wf-option-title"><span id="<?php echo esc_attr($rateID); ?>-label"><?php echo esc_html($title); ?></span><?php if (!wfConfig::p() && isset($premium) && $premium) { echo ' <a href="https://www.wordfence.com/gnl1optionUpgrade/wordfence-signup/" target="_blank" rel="noopener noreferrer" class="wf-premium-link">' . esc_html__('Premium Feature', 'wordfence') . '</a>'; } ?><?php if (isset($helpLink)) { echo ' <a href="' . esc_attr($helpLink) . '" target="_blank" rel="noopener noreferrer" class="wf-inline-help"><i class="wf-fa wf-fa-question-circle-o" aria-hidden="true"></i><span class="screen-reader-text"> (' . esc_html__('opens in new tab', 'wordfence') . ')</span></a>'; } ?></li>
|
||||
<li class="wf-option-select wf-left-xs wf-padding-add-top-xs-small wf-nowrap">
|
||||
<select<?php echo (!(!wfConfig::p() && isset($premium) && $premium) ? '' : ' disabled'); ?> id="<?php echo esc_attr($rateID); ?>" class="wf-rate-limit-rate" aria-labelledby="<?php echo esc_attr($rateID); ?>-label">
|
||||
<?php foreach ($rateOptions as $o): ?>
|
||||
<option class="wf-option-select-option" value="<?php echo esc_attr($o['value']); ?>"<?php if ($o['value'] == $rateValue) { echo ' selected'; } ?>><?php echo esc_html($o['label']); ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
<span class="wf-padding-add-left-small wf-padding-add-right-small wf-padding-add-top-xs-small wf-padding-add-bottom-xs-small wf-inline-block-xs"><?php esc_html_e('then', 'wordfence'); ?></span>
|
||||
<select<?php echo (!(!wfConfig::p() && isset($premium) && $premium) ? '' : ' disabled'); ?> id="<?php echo esc_attr($actionID); ?>" class="wf-rate-limit-action" aria-labelledby="<?php echo esc_attr($rateID); ?>-label">
|
||||
<?php foreach ($actionOptions as $o): ?>
|
||||
<option class="wf-option-select-option" value="<?php echo esc_attr($o['value']); ?>"<?php if ($o['value'] == $actionValue) { echo ' selected'; } ?>><?php echo esc_html($o['label']); ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
<div class="wf-rate-limit-warning"><div class="wf-inline-notice"><i class="wf-fa wf-fa-exclamation-triangle" aria-hidden="true"></i><span>Very strict. May cause false positives.</span></div></div>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
59
wp/wp-content/plugins/wordfence/views/waf/option-rules.php
Normal file
59
wp/wp-content/plugins/wordfence/views/waf/option-rules.php
Normal file
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
if (!defined('WORDFENCE_VERSION')) { exit; }
|
||||
?>
|
||||
<ul id="wf-option-wafRules" class="wf-option wf-flex-vertical wf-flex-align-left">
|
||||
<li class="wf-option-title"><strong><?php esc_html_e('Rules', 'wordfence'); ?></strong> <a href="<?php echo wfSupportController::esc_supportURL(wfSupportController::ITEM_FIREWALL_WAF_RULES); ?>" target="_blank" rel="noopener noreferrer" class="wf-inline-help"><i class="wf-fa wf-fa-question-circle-o" aria-hidden="true"></i><span class="screen-reader-text"> (<?php esc_html_e('opens in new tab', 'wordfence') ?>)</span></a></li>
|
||||
<li class="wf-option-subtitle"><?php echo ($firewall->isSubDirectoryInstallation() ? esc_html__('You are currently running the WAF from another WordPress installation. These rules can be disabled or enabled once you configure the firewall to run correctly on this site.', 'wordfence') : ''); ?></li>
|
||||
<li id="waf-rules-wrapper" class="wf-add-top"></li>
|
||||
<?php if (!WFWAF_SUBDIRECTORY_INSTALL): ?>
|
||||
<li id="waf-rules-manual-update">
|
||||
<ul class="wf-option wf-option-footer wf-padding-no-bottom">
|
||||
<li><a class="wf-btn wf-btn-default waf-rules-refresh" href="#" role="button"><?php esc_html_e('Manually Refresh Rules', 'wordfence'); ?></a> </li>
|
||||
<li class="wf-padding-add-top-xs-small"><em id="waf-rules-next-update"></em></li>
|
||||
</ul>
|
||||
<script type="application/javascript">
|
||||
(function($) {
|
||||
$('.waf-rules-refresh').on('click', function(e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
WFAD.wafUpdateRules();
|
||||
});
|
||||
})(jQuery);
|
||||
<?php
|
||||
try {
|
||||
$lastUpdated = wfWAF::getInstance()->getStorageEngine()->getConfig('rulesLastUpdated', null, 'transient');
|
||||
|
||||
$nextUpdate = PHP_INT_MAX;
|
||||
$cron = (array) wfWAF::getInstance()->getStorageEngine()->getConfig('cron', null, 'livewaf');
|
||||
if (is_array($cron)) {
|
||||
/** @var wfWAFCronEvent $event */
|
||||
foreach ($cron as $index => $event) {
|
||||
if ($event instanceof wfWAFCronFetchRulesEvent) {
|
||||
$event->setWaf(wfWAF::getInstance());
|
||||
if (!$event->isInPast()) {
|
||||
$nextUpdate = min($nextUpdate, $event->getFireTime());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (wfWAFStorageFileException $e) {
|
||||
error_log($e->getMessage());
|
||||
}
|
||||
catch (wfWAFStorageEngineMySQLiException $e) {
|
||||
error_log($e->getMessage());
|
||||
}
|
||||
if (!empty($lastUpdated)): ?>
|
||||
var lastUpdated = <?php echo (int) $lastUpdated ?>;
|
||||
WFAD.renderWAFRulesLastUpdated(new Date(lastUpdated * 1000));
|
||||
<?php endif ?>
|
||||
|
||||
<?php if ($nextUpdate < PHP_INT_MAX): ?>
|
||||
var nextUpdate = <?php echo (int) $nextUpdate ?>;
|
||||
WFAD.renderWAFRulesNextUpdate(new Date(nextUpdate * 1000));
|
||||
<?php endif ?>
|
||||
</script>
|
||||
</li>
|
||||
<?php endif ?>
|
||||
</ul>
|
||||
180
wp/wp-content/plugins/wordfence/views/waf/option-whitelist.php
Normal file
180
wp/wp-content/plugins/wordfence/views/waf/option-whitelist.php
Normal file
@@ -0,0 +1,180 @@
|
||||
<?php
|
||||
if (!defined('WORDFENCE_VERSION')) { exit; }
|
||||
?>
|
||||
<ul id="wf-option-wafWhitelist" class="wf-option wf-flex-vertical wf-flex-full-width">
|
||||
<li><strong><?php esc_html_e('Add Allowlisted URL/Param', 'wordfence'); ?></strong> <a href="<?php echo wfSupportController::esc_supportURL(wfSupportController::ITEM_FIREWALL_WAF_WHITELIST); ?>" target="_blank" rel="noopener noreferrer" class="wf-inline-help"><i class="wf-fa wf-fa-question-circle-o" aria-hidden="true"></i><span class="screen-reader-text"> (<?php esc_html_e('opens in new tab', 'wordfence') ?>)</span></a> <?php esc_html_e('The URL/parameters in this table will not be tested by the firewall. They are typically added while the firewall is in Learning Mode or by an admin who identifies a particular action/request is a false positive.', 'wordfence'); ?></li>
|
||||
<li id="whitelist-form">
|
||||
<div class="wf-form-inline">
|
||||
<div class="wf-form-group">
|
||||
<input class="wf-form-control" type="text" name="whitelistURL" id="whitelistURL" placeholder="<?php esc_attr_e('URL', 'wordfence'); ?>">
|
||||
</div>
|
||||
<div class="wf-form-group">
|
||||
<select class="wf-form-control" name="whitelistParam" id="whitelistParam">
|
||||
<option value="request.body"><?php esc_html_e('POST Body', 'wordfence'); ?></option>
|
||||
<option value="request.cookies"><?php esc_html_e('Cookie', 'wordfence'); ?></option>
|
||||
<option value="request.fileNames"><?php esc_html_e('File Name', 'wordfence'); ?></option>
|
||||
<option value="request.headers"><?php esc_html_e('Header', 'wordfence'); ?></option>
|
||||
<option value="request.queryString"><?php esc_html_e('Query String', 'wordfence'); ?></option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="wf-form-group">
|
||||
<input class="wf-form-control" type="text" name="whitelistParamName" id="whitelistParamName" placeholder="<?php esc_attr_e('Param Name', 'wordfence'); ?>">
|
||||
</div>
|
||||
<a href="#" class="wf-btn wf-btn-callout wf-btn-primary wf-disabled" id="waf-whitelisted-urls-add" role="button"><?php esc_html_e('Add', 'wordfence'); ?></a>
|
||||
</div>
|
||||
<script type="application/javascript">
|
||||
(function($) {
|
||||
$(function() {
|
||||
$('#whitelistURL, #whitelistParamName').on('change paste keyup', function() {
|
||||
setTimeout(function() {
|
||||
$('#waf-whitelisted-urls-add').toggleClass('wf-disabled', $('#whitelistURL').val().length == 0 || $('#whitelistParamName').val().length == 0);
|
||||
}, 100);
|
||||
});
|
||||
|
||||
$('#waf-whitelisted-urls-add').on('click', function(e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
var form = $('#whitelist-form');
|
||||
var inputURL = form.find('[name=whitelistURL]');
|
||||
var inputParam = form.find('[name=whitelistParam]');
|
||||
var inputParamName = form.find('[name=whitelistParamName]');
|
||||
|
||||
var url = inputURL.val();
|
||||
var param = inputParam.val();
|
||||
var paramName = inputParamName.val();
|
||||
if (url && param) {
|
||||
<?php $user = wp_get_current_user(); ?>
|
||||
var paramKey = WFAD.base64_encode(param + '[' + paramName + ']');
|
||||
var pathKey = WFAD.base64_encode(url);
|
||||
var key = pathKey + '|' + paramKey;
|
||||
var matches = $('#waf-whitelisted-urls-wrapper .whitelist-table > tbody > tr[data-key="' + key + '"]');
|
||||
if (matches.length > 0) {
|
||||
WFAD.colorboxModal((WFAD.isSmallScreen ? '300px' : '400px'), '<?php esc_attr_e('Allowlist Entry Exists', 'wordfence'); ?>', '<?php esc_attr_e('An allowlist entry for this URL and parameter already exists.', 'wordfence'); ?>');
|
||||
return;
|
||||
}
|
||||
|
||||
//Generate entry and add to display data set
|
||||
var entry = {
|
||||
data: {
|
||||
description: "<?php esc_attr_e('Allowlisted via Firewall Options page', 'wordfence'); ?>",
|
||||
source: 'waf-options',
|
||||
disabled: false,
|
||||
ip: "<?php echo esc_attr(wfUtils::getIP()); ?>",
|
||||
timestamp: Math.round(Date.now() / 1000),
|
||||
userID: <?php echo (int) $user->ID; ?>,
|
||||
username: "<?php echo esc_attr($user->user_login); ?>"
|
||||
},
|
||||
paramKey: paramKey,
|
||||
path: pathKey,
|
||||
ruleID: ['all'],
|
||||
adding: true
|
||||
};
|
||||
WFAD.wafData.whitelistedURLParams.push(entry);
|
||||
|
||||
//Add to change list
|
||||
if (!(WFAD.pendingChanges['whitelistedURLParams'] instanceof Object)) {
|
||||
WFAD.pendingChanges['whitelistedURLParams'] = {};
|
||||
}
|
||||
|
||||
if (!(WFAD.pendingChanges['whitelistedURLParams']['add'] instanceof Object)) {
|
||||
WFAD.pendingChanges['whitelistedURLParams']['add'] = {};
|
||||
}
|
||||
|
||||
WFAD.pendingChanges['whitelistedURLParams']['add'][key] = entry;
|
||||
WFAD.updatePendingChanges();
|
||||
|
||||
//Reload and reset add form
|
||||
var whitelistedIPsEl = $('#waf-whitelisted-urls-tmpl').tmpl(WFAD.wafData);
|
||||
$('#waf-whitelisted-urls-wrapper').html(whitelistedIPsEl);
|
||||
$(window).trigger('wordfenceWAFInstallWhitelistEventHandlers');
|
||||
|
||||
inputURL.val('');
|
||||
inputParamName.val('');
|
||||
}
|
||||
});
|
||||
});
|
||||
})(jQuery);
|
||||
</script>
|
||||
</li>
|
||||
<li><hr id="whitelist-form-separator"></li>
|
||||
<li id="whitelist-table-controls" class="wf-flex-horizontal wf-flex-vertical-xs wf-flex-full-width">
|
||||
<div><a href="#" id="whitelist-bulk-delete" class="wf-btn wf-btn-callout wf-btn-default" role="button"><?php esc_html_e('Delete', 'wordfence'); ?></a> <a href="#" id="whitelist-bulk-enable" class="wf-btn wf-btn-callout wf-btn-default" role="button"><?php esc_html_e('Enable', 'wordfence'); ?></a> <a href="#" id="whitelist-bulk-disable" class="wf-btn wf-btn-callout wf-btn-default" role="button"><?php esc_html_e('Disable', 'wordfence'); ?></a></div>
|
||||
<div class="wf-right wf-left-xs wf-padding-add-top-xs-small">
|
||||
<div class="wf-select-group wf-flex-vertical-xs wf-flex-full-width">
|
||||
<select name="filterColumn">
|
||||
<option value="url"><?php esc_html_e('URL', 'wordfence'); ?></option>
|
||||
<option value="param"><?php esc_html_e('Param', 'wordfence'); ?></option>
|
||||
<option value="source"><?php esc_html_e('Source', 'wordfence'); ?></option>
|
||||
<option value="user"><?php esc_html_e('User', 'wordfence'); ?></option>
|
||||
<option value="ip"><?php esc_html_e('IP', 'wordfence'); ?></option>
|
||||
</select>
|
||||
<input type="text" class="wf-form-control" placeholder="<?php esc_attr_e('Filter Value', 'wordfence'); ?>" name="filterValue">
|
||||
<div><span class="wf-hidden-xs"> </span><a href="#" id="whitelist-apply-filter" class="wf-btn wf-btn-callout wf-btn-default" role="button"><?php esc_html_e('Filter', 'wordfence'); ?></a></div>
|
||||
</div>
|
||||
<script type="application/javascript">
|
||||
(function($) {
|
||||
$(function() {
|
||||
$('#whitelist-apply-filter').on('click', function(e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
$(window).trigger('wordfenceWAFApplyWhitelistFilter');
|
||||
});
|
||||
});
|
||||
})(jQuery);
|
||||
</script>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<div id="waf-whitelisted-urls-wrapper"></div>
|
||||
</li>
|
||||
</ul>
|
||||
<script type="application/javascript">
|
||||
(function($) {
|
||||
$(function() {
|
||||
$('#whitelistParam').wfselect2({
|
||||
minimumResultsForSearch: -1,
|
||||
templateSelection: function(item) {
|
||||
return 'Param Type: ' + item.text;
|
||||
}
|
||||
});
|
||||
|
||||
$('#whitelist-table-controls select').wfselect2({
|
||||
minimumResultsForSearch: -1,
|
||||
placeholder: "Filter By",
|
||||
width: '200px',
|
||||
templateSelection: function(item) {
|
||||
return 'Filter By: ' + item.text;
|
||||
}
|
||||
});
|
||||
|
||||
$('#whitelist-bulk-delete').on('click', function(e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
WFAD.wafWhitelistedBulkDelete();
|
||||
WFAD.updatePendingChanges();
|
||||
var whitelistedIPsEl = $('#waf-whitelisted-urls-tmpl').tmpl(WFAD.wafData);
|
||||
$('#waf-whitelisted-urls-wrapper').html(whitelistedIPsEl);
|
||||
$(window).trigger('wordfenceWAFInstallWhitelistEventHandlers');
|
||||
});
|
||||
|
||||
$('#whitelist-bulk-enable').on('click', function(e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
WFAD.wafWhitelistedBulkChangeEnabled(true);
|
||||
WFAD.updatePendingChanges();
|
||||
});
|
||||
|
||||
$('#whitelist-bulk-disable').on('click', function(e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
WFAD.wafWhitelistedBulkChangeEnabled(false);
|
||||
WFAD.updatePendingChanges();
|
||||
});
|
||||
});
|
||||
})(jQuery);
|
||||
</script>
|
||||
@@ -0,0 +1,236 @@
|
||||
<?php
|
||||
if (!defined('WORDFENCE_VERSION')) { exit; }
|
||||
/**
|
||||
* Presents the Advanced Firewall Options group.
|
||||
*
|
||||
* Expects $firewall, $waf, and $stateKey.
|
||||
*
|
||||
* @var wfFirewall $firewall
|
||||
* @var wfWAF $waf
|
||||
* @var string $stateKey The key under which the collapse state is stored.
|
||||
* @var bool $collapseable If defined, specifies whether or not this grouping can be collapsed. Defaults to true.
|
||||
*/
|
||||
|
||||
$config = $waf->getStorageEngine();
|
||||
|
||||
if (!isset($collapseable)) {
|
||||
$collapseable = true;
|
||||
}
|
||||
?>
|
||||
<div class="wf-row">
|
||||
<div class="wf-col-xs-12">
|
||||
<div class="wf-block<?php if (!$collapseable) { echo ' wf-always-active'; } else { echo (wfPersistenceController::shared()->isActive($stateKey) ? ' wf-active' : ''); } ?>" data-persistence-key="<?php echo esc_attr($stateKey); ?>">
|
||||
<div class="wf-block-header">
|
||||
<div class="wf-block-header-content">
|
||||
<div class="wf-block-title">
|
||||
<strong><?php esc_html_e('Advanced Firewall Options', 'wordfence'); ?></strong>
|
||||
</div>
|
||||
<?php if ($collapseable): ?><div class="wf-block-header-action"><div class="wf-block-header-action-disclosure" role="checkbox" aria-checked="<?php echo (wfPersistenceController::shared()->isActive($stateKey) ? 'true' : 'false'); ?>" tabindex="0"></div></div><?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="wf-block-content">
|
||||
<ul class="wf-block-list">
|
||||
<li>
|
||||
<?php
|
||||
echo wfView::create('options/option-toggled', array(
|
||||
'optionName' => 'disableWAFIPBlocking',
|
||||
'enabledValue' => 1,
|
||||
'disabledValue' => 0,
|
||||
'value' => wfConfig::get('disableWAFIPBlocking') ? 1 : 0,
|
||||
'title' => __('Delay IP and Country blocking until after WordPress and plugins have loaded (only process firewall rules early)', 'wordfence'),
|
||||
'subtitle' => ($firewall->isSubDirectoryInstallation() ? __('You are currently running the WAF from another WordPress installation. This option can be changed once you configure the firewall to run correctly on this site.', 'wordfence') : ''),
|
||||
'helpLink' => wfSupportController::supportURL(wfSupportController::ITEM_FIREWALL_WAF_OPTION_DELAY_BLOCKING),
|
||||
'disabled' => $firewall->isSubDirectoryInstallation(),
|
||||
))->render();
|
||||
?>
|
||||
</li>
|
||||
<li>
|
||||
<?php
|
||||
echo wfView::create('options/option-textarea', array(
|
||||
'textOptionName' => 'whitelisted',
|
||||
'textValue' => wfUtils::cleanupOneEntryPerLine(wfConfig::get('whitelisted')),
|
||||
'title' => __('Allowlisted IP addresses that bypass all rules', 'wordfence'),
|
||||
'alignTitle' => 'top',
|
||||
'subtitleHTML' => wp_kses(__('Allowlisted IPs must be separated by commas or placed on separate lines. You can specify ranges using the following formats: 127.0.0.1/24, 127.0.0.[1-100], or 127.0.0.1-127.0.1.100<br/>Wordfence automatically allowlists <a href="http://en.wikipedia.org/wiki/Private_network" target="_blank" rel="noopener noreferrer">private networks<span class="screen-reader-text"> (opens in new tab)</span></a> because these are not routable on the public Internet.', 'wordfence'), array('br'=>array(), 'a'=>array('href'=>array(), 'target'=>array(), 'rel'=>array()), 'span'=>array('class'=>array()))),
|
||||
'subtitlePosition' => 'value',
|
||||
'helpLink' => wfSupportController::supportURL(wfSupportController::ITEM_FIREWALL_WAF_OPTION_WHITELISTED_IPS),
|
||||
))->render();
|
||||
?>
|
||||
</li>
|
||||
<li>
|
||||
<?php
|
||||
$whitelistedServices = wfConfig::getJSON('whitelistedServices', array());
|
||||
$whitelistPresets = wfUtils::whitelistPresets();
|
||||
|
||||
$names = array();
|
||||
foreach ($whitelistPresets as $tag => $preset) {
|
||||
if (!isset($preset['n'])) { continue; } //Not named, omitted from configurable list
|
||||
if ((isset($preset['h']) && $preset['h']) || (isset($preset['f']) && $preset['f'])) { continue; } //Flagged as hidden or always enabled, omitted from configurable list
|
||||
$names[$tag] = $preset['n'];
|
||||
if (!isset($whitelistedServices[$tag]) && isset($preset['d']) && $preset['d']) {
|
||||
$whitelistedServices[$tag] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
$options = array();
|
||||
foreach ($names as $tag => $name) {
|
||||
$options[] = array(
|
||||
'name' => 'whitelistedServices.' . preg_replace('/[^a-z0-9]/i', '', $tag),
|
||||
'enabledValue' => 1,
|
||||
'disabledValue' => 0,
|
||||
'value' => (isset($whitelistedServices[$tag]) && $whitelistedServices[$tag]) ? 1 : 0,
|
||||
'title' => $name,
|
||||
);
|
||||
}
|
||||
|
||||
echo wfView::create('options/option-toggled-multiple', array(
|
||||
'options' => $options,
|
||||
'title' => __('Allowlisted services', 'wordfence'),
|
||||
'id' => 'wf-option-whitelistedServices',
|
||||
'helpLink' => wfSupportController::supportURL(wfSupportController::ITEM_FIREWALL_WAF_OPTION_WHITELISTED_SERVICES),
|
||||
))->render();
|
||||
?>
|
||||
</li>
|
||||
<li>
|
||||
<?php
|
||||
echo wfView::create('options/option-textarea', array(
|
||||
'textOptionName' => 'bannedURLs',
|
||||
'textValue' => wfUtils::cleanupOneEntryPerLine(wfConfig::get('bannedURLs')),
|
||||
'title' => __('Immediately block IPs that access these URLs', 'wordfence'),
|
||||
'alignTitle' => 'top',
|
||||
'subtitle' => __('Separate multiple URLs with commas or place them on separate lines. Asterisks are wildcards, but use with care. If you see an attacker repeatedly probing your site for a known vulnerability you can use this to immediately block them. All URLs must start with a "/" without quotes and must be relative. e.g. /badURLone/, /bannedPage.html, /dont-access/this/URL/, /starts/with-*', 'wordfence'),
|
||||
'subtitlePosition' => 'value',
|
||||
'helpLink' => wfSupportController::supportURL(wfSupportController::ITEM_FIREWALL_WAF_OPTION_IMMEDIATELY_BLOCK_URLS),
|
||||
))->render();
|
||||
?>
|
||||
</li>
|
||||
<li>
|
||||
<?php
|
||||
echo wfView::create('options/option-textarea', array(
|
||||
'textOptionName' => 'wafAlertWhitelist',
|
||||
'textValue' => wfUtils::cleanupOneEntryPerLine(wfConfig::get('wafAlertWhitelist')),
|
||||
'title' => __('Ignored IP addresses for Wordfence Web Application Firewall alerting', 'wordfence'),
|
||||
'alignTitle' => 'top',
|
||||
'subtitle' => __('Ignored IPs must be separated by commas or placed on separate lines. These addresses will be ignored from any alerts about increased attacks and can be used to ignore things like standalone website security scanners.', 'wordfence'),
|
||||
'subtitlePosition' => 'value',
|
||||
'helpLink' => wfSupportController::supportURL(wfSupportController::ITEM_FIREWALL_WAF_IGNORED_ALERT_IPS),
|
||||
))->render();
|
||||
?>
|
||||
</li>
|
||||
<li>
|
||||
<?php
|
||||
echo wfView::create('waf/option-rules', array(
|
||||
'firewall' => $firewall,
|
||||
))->render();
|
||||
?>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div> <!-- end advanced firewall options -->
|
||||
<script type="text/x-jquery-template" id="waf-rules-tmpl">
|
||||
<table class="wf-striped-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width: 5%"></th>
|
||||
<th><?php esc_html_e('Category', 'wordfence'); ?></th>
|
||||
<th><?php esc_html_e('Description', 'wordfence'); ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{each(idx, rule) rules}}
|
||||
<tr data-rule-id="${rule.ruleID}" data-original-value="{{if (!disabledRules[rule.ruleID])}}1{{else}}0{{/if}}">
|
||||
<td style="text-align: center">
|
||||
<div class="wf-rule-toggle wf-boolean-switch{{if (!disabledRules[rule.ruleID])}} wf-active{{/if}}<?php echo ($firewall->isSubDirectoryInstallation() ? ' wf-disabled' : ''); ?>"><a href="#" class="wf-boolean-switch-handle"></a></div>
|
||||
</td>
|
||||
<td>${rule.category}</td>
|
||||
<td>${rule.description}</td>
|
||||
</tr>
|
||||
{{/each}}
|
||||
{{if (rules.length == 0)}}
|
||||
<tr>
|
||||
<td colspan="4"><?php esc_html_e('No rules currently set.', 'wordfence'); ?> <?php if (!($firewall->protectionMode() == wfFirewall::PROTECTION_MODE_EXTENDED && $firewall->isSubDirectoryInstallation())) { echo wp_kses(__('<a href="#" onclick="WFAD.wafUpdateRules();return false;" role="button">Click here</a> to pull down the latest from the Wordfence servers.', 'wordfence'), array('a'=>array('href'=>array(), 'onclick'=>array(), 'role'=>array()))); } ?>
|
||||
</td>
|
||||
</tr>
|
||||
{{/if}}
|
||||
</tbody>
|
||||
<tfoot>
|
||||
{{if (ruleCount >= 10)}}
|
||||
<tr id="waf-show-all-rules">
|
||||
<td class="wf-center" colspan="4"><a href="#" id="waf-show-all-rules-button" role="button"><?php esc_html_e('SHOW ALL RULES', 'wordfence'); ?></a></td>
|
||||
</tr>
|
||||
{{/if}}
|
||||
</tfoot>
|
||||
</table>
|
||||
</script>
|
||||
<script type="application/javascript">
|
||||
(function($) {
|
||||
$(window).on('wordfenceWAFConfigPageRender', function() {
|
||||
delete WFAD.pendingChanges['wafRules'];
|
||||
|
||||
//Add event handler to rule checkboxes
|
||||
$('.wf-rule-toggle.wf-boolean-switch').each(function() {
|
||||
$(this).on('keydown', function(e) {
|
||||
if (e.keyCode == 32) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
$(this).find('.wf-boolean-switch-handle').trigger('click');
|
||||
}
|
||||
});
|
||||
|
||||
$(this).on('click', function(e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
$(this).find('.wf-boolean-switch-handle').trigger('click');
|
||||
});
|
||||
|
||||
$(this).find('.wf-boolean-switch-handle').on('keydown', function(e) {
|
||||
if (e.keyCode == 32) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
$(this).trigger('click');
|
||||
}
|
||||
});
|
||||
|
||||
$(this).find('.wf-boolean-switch-handle').on('click', function(e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
var control = $(this).closest('.wf-boolean-switch');
|
||||
var row = $(this).closest('tr');
|
||||
var ruleID = row.data('ruleId');
|
||||
var value = control.hasClass('wf-active') ? 1 : 0;
|
||||
if (value) {
|
||||
control.removeClass('wf-active').attr('aria-checked', 'false');
|
||||
value = 0;
|
||||
}
|
||||
else {
|
||||
control.addClass('wf-active').attr('aria-checked', 'false');
|
||||
value = 1;
|
||||
}
|
||||
|
||||
var originalValue = row.data('originalValue');
|
||||
if (originalValue == value) {
|
||||
delete WFAD.pendingChanges['wafRules'][ruleID];
|
||||
if (Object.keys(WFAD.pendingChanges['wafRules']).length == 0) {
|
||||
delete WFAD.pendingChanges['wafRules']
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!(WFAD.pendingChanges['wafRules'] instanceof Object)) {
|
||||
WFAD.pendingChanges['wafRules'] = {};
|
||||
}
|
||||
WFAD.pendingChanges['wafRules'][ruleID] = value;
|
||||
}
|
||||
|
||||
$(control).trigger('change', [false]);
|
||||
WFAD.updatePendingChanges();
|
||||
});
|
||||
});
|
||||
});
|
||||
})(jQuery);
|
||||
</script>
|
||||
@@ -0,0 +1,511 @@
|
||||
<?php
|
||||
if (!defined('WORDFENCE_VERSION')) { exit; }
|
||||
/**
|
||||
* Presents the Basic Firewall Options group.
|
||||
*
|
||||
* Expects $firewall, $waf, and $stateKey.
|
||||
*
|
||||
* @var wfFirewall $firewall
|
||||
* @var wfWAF $waf
|
||||
* @var string $stateKey The key under which the collapse state is stored.
|
||||
* @var bool $collapseable If defined, specifies whether or not this grouping can be collapsed. Defaults to true.
|
||||
*/
|
||||
|
||||
$config = $waf->getStorageEngine();
|
||||
|
||||
if (!isset($collapseable)) {
|
||||
$collapseable = true;
|
||||
}
|
||||
?>
|
||||
<div class="wf-row">
|
||||
<div class="wf-col-xs-12">
|
||||
<div class="wf-block<?php if (!$collapseable) { echo ' wf-always-active'; } else { echo (wfPersistenceController::shared()->isActive($stateKey) ? ' wf-active' : ''); } ?>" data-persistence-key="<?php echo esc_attr($stateKey); ?>">
|
||||
<div class="wf-block-header">
|
||||
<div class="wf-block-header-content">
|
||||
<div class="wf-block-title">
|
||||
<strong><?php esc_html_e('Basic Firewall Options', 'wordfence'); ?></strong>
|
||||
</div>
|
||||
<?php if ($collapseable): ?><div class="wf-block-header-action"><div class="wf-block-header-action-disclosure" role="checkbox" aria-checked="<?php echo (wfPersistenceController::shared()->isActive($stateKey) ? 'true' : 'false'); ?>" tabindex="0"></div></div><?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="wf-block-content">
|
||||
<ul class="wf-block-list wf-block-list-horizontal">
|
||||
<li id="wf-option-wafStatus" class="wf-flex-vertical wf-flex-align-left wf-flex-full-width">
|
||||
<h3><?php esc_html_e('Web Application Firewall Status', 'wordfence'); ?></h3>
|
||||
<?php if ($firewall->isSubDirectoryInstallation()): ?>
|
||||
<p class="wf-no-top"><?php echo wp_kses(sprintf(/* translators: WordPress admin URL. */ __('You are currently running the Wordfence Web Application Firewall from another WordPress installation. Please <a href="%s">click here</a> to configure the Firewall to run correctly on this site.', 'wordfence'), esc_attr(network_admin_url('admin.php?page=WordfenceWAF&subpage=waf_options#configureAutoPrepend'))), array('a'=>array('href'=>array()))); ?></p>
|
||||
<?php else: ?>
|
||||
<p class="wf-no-top">
|
||||
<?php $wafStatus = $firewall->firewallMode(); ?>
|
||||
<span id="wafStatus-enabled-description" class="wafStatus-description"<?php if ($wafStatus != wfFirewall::FIREWALL_MODE_ENABLED) { echo ' style="display: none;"'; } ?>><strong><?php esc_html_e('Enabled and Protecting:', 'wordfence'); ?></strong> <?php esc_html_e('In this mode, the Wordfence Web Application Firewall is actively blocking requests matching known attack patterns and is actively protecting your site from attackers.', 'wordfence'); ?></span>
|
||||
<span id="wafStatus-learning-mode-description" class="wafStatus-description"<?php if ($wafStatus != wfFirewall::FIREWALL_MODE_LEARNING) { echo ' style="display: none;"'; } ?>><strong><?php esc_html_e('Learning Mode:', 'wordfence'); ?></strong> <?php echo wp_kses(sprintf(/* translators: Support URL. */ __('When you first install the Wordfence Web Application Firewall, it will be in learning mode. This allows Wordfence to learn about your site so that we can understand how to protect it and how to allow normal visitors through the firewall. We recommend you let Wordfence learn for a week before you enable the firewall. <a href="%s" target="_blank" rel="noopener noreferrer">Learn More<span class="screen-reader-text"> (opens in new tab)</span></a>', 'wordfence'), wfSupportController::supportURL(wfSupportController::ITEM_FIREWALL_WAF_LEARNING_MODE)), array('a'=>array('href'=>array(), 'target'=>array(), 'rel'=>array()), 'span'=>array('class'=>array()))); ?></span>
|
||||
<span id="wafStatus-disabled-description" class="wafStatus-description"<?php if ($wafStatus != wfFirewall::FIREWALL_MODE_DISABLED) { echo ' style="display: none;"'; } ?>><strong><?php esc_html_e('Disabled:', 'wordfence'); ?></strong> <?php esc_html_e('In this mode, the Wordfence Web Application Firewall is functionally turned off and does not run any of its rules or analyze the request in any way.', 'wordfence'); ?></span>
|
||||
</p>
|
||||
<p class="wf-no-top wf-add-bottom">
|
||||
<select id="input-wafStatus" data-original-value="<?php echo esc_attr($wafStatus); ?>" name="wafStatus" class="wf-form-control"<?php echo !WFWAF_ENABLED ? ' disabled' : '' ?>>
|
||||
<option<?php echo $wafStatus == wfFirewall::FIREWALL_MODE_ENABLED ? ' selected' : '' ?> class="wafStatus-enabled" value="enabled"><?php esc_html_e('Enabled and Protecting', 'wordfence'); ?></option>
|
||||
<option<?php echo $wafStatus == wfFirewall::FIREWALL_MODE_LEARNING ? ' selected' : '' ?> class="wafStatus-learning-mode" value="learning-mode"><?php esc_html_e('Learning Mode', 'wordfence'); ?></option>
|
||||
<option<?php echo $wafStatus == wfFirewall::FIREWALL_MODE_DISABLED ? ' selected' : '' ?> class="wafStatus-disabled" value="disabled"><?php esc_html_e('Disabled', 'wordfence'); ?></option>
|
||||
</select>
|
||||
<script type="application/javascript">
|
||||
(function($) {
|
||||
$(function() {
|
||||
$('#input-wafStatus').wfselect2({
|
||||
minimumResultsForSearch: -1,
|
||||
width: '200px'
|
||||
}).on('change', function() {
|
||||
var select = $(this);
|
||||
var value = select.val();
|
||||
var container = $($(this).data('wfselect2').$container);
|
||||
container.removeClass('wafStatus-enabled wafStatus-learning-mode wafStatus-disabled')
|
||||
.addClass('wafStatus-' + value);
|
||||
|
||||
$('.wafStatus-description').hide();
|
||||
$('#wafStatus-' + value + '-description').show();
|
||||
if (value == 'learning-mode') {
|
||||
$('#waf-learning-mode-grace-period').show();
|
||||
}
|
||||
else {
|
||||
$('#waf-learning-mode-grace-period').hide();
|
||||
}
|
||||
|
||||
var originalValue = select.data('originalValue');
|
||||
if (originalValue == value) {
|
||||
delete WFAD.pendingChanges['wafStatus'];
|
||||
}
|
||||
else {
|
||||
WFAD.pendingChanges['wafStatus'] = value;
|
||||
}
|
||||
|
||||
WFAD.updatePendingChanges();
|
||||
}).val(<?php echo json_encode($wafStatus) ?>).triggerHandler('change');
|
||||
|
||||
$('#waf-learning-mode-grace-period .wf-datetime').datetimepicker({
|
||||
dateFormat: 'yy-mm-dd',
|
||||
timezone: <?php try { echo (int) wfUtils::timeZoneMinutes($config->getConfig('learningModeGracePeriod') ? (int) $config->getConfig('learningModeGracePeriod') : false); } catch (Exception $e) { echo 0; }; ?>,
|
||||
showTime: false,
|
||||
showTimepicker: false,
|
||||
showMonthAfterYear: true
|
||||
}).each(function() {
|
||||
var el = $(this);
|
||||
if (el.attr('data-value')) {
|
||||
el.datetimepicker('setDate', new Date(el.attr('data-value') * 1000));
|
||||
}
|
||||
}).on('change', function() {
|
||||
var value = Math.floor($(this).datetimepicker('getDate').getTime() / 1000);
|
||||
var originalValue = $('#input-learningModeGracePeriod').data('originalValue');
|
||||
if (originalValue == value) {
|
||||
delete WFAD.pendingChanges['learningModeGracePeriod'];
|
||||
}
|
||||
else {
|
||||
WFAD.pendingChanges['learningModeGracePeriod'] = $(this).val();
|
||||
}
|
||||
WFAD.updatePendingChanges();
|
||||
});
|
||||
|
||||
$('#waf-learning-mode-grace-period .wf-option-checkbox').on('click', function(e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
var originalValue = $(this).data('originalValue');
|
||||
var value = originalValue;
|
||||
var isActive = $(this).hasClass('wf-checked');
|
||||
if (isActive) {
|
||||
$(this).removeClass('wf-checked');
|
||||
$('#waf-learning-mode-grace-period .wf-datetime').attr('disabled', true);
|
||||
value = 0;
|
||||
}
|
||||
else {
|
||||
$(this).addClass('wf-checked');
|
||||
$('#waf-learning-mode-grace-period .wf-datetime').attr('disabled', false);
|
||||
value = 1;
|
||||
|
||||
if (!$('#input-learningModeGracePeriod').val()) {
|
||||
var date = new Date();
|
||||
date.setDate(date.getDate() + 7);
|
||||
$('#input-learningModeGracePeriod').datetimepicker('setDate', date);
|
||||
}
|
||||
}
|
||||
|
||||
if (originalValue == value) {
|
||||
delete WFAD.pendingChanges['learningModeGracePeriodEnabled'];
|
||||
}
|
||||
else {
|
||||
WFAD.pendingChanges['learningModeGracePeriodEnabled'] = value;
|
||||
}
|
||||
|
||||
WFAD.updatePendingChanges();
|
||||
});
|
||||
|
||||
$(window).on('wfOptionsReset', function() {
|
||||
$('#input-wafStatus').val($('#input-wafStatus').data('originalValue')).trigger('change');
|
||||
$('#waf-learning-mode-grace-period .wf-option-checkbox').each(function() {
|
||||
var originalValue = $(this).data('originalValue');
|
||||
$(this).toggleClass('wf-checked', !!originalValue);
|
||||
$('#waf-learning-mode-grace-period .wf-datetime').attr('disabled', !originalValue);
|
||||
});
|
||||
$('.wf-datetime').each(function() {
|
||||
var el = $(this);
|
||||
if (el.attr('data-value')) {
|
||||
el.datetimepicker('setDate', new Date(el.attr('data-value') * 1000));
|
||||
}
|
||||
else {
|
||||
el.val('');
|
||||
}
|
||||
})
|
||||
});
|
||||
});
|
||||
})(jQuery);
|
||||
</script>
|
||||
</p>
|
||||
<div id="waf-learning-mode-grace-period" class="wf-add-bottom" style="display: none;"><div class="waf-learning-mode wf-option-checkbox<?php try { echo $config->getConfig('learningModeGracePeriodEnabled') ? ' wf-checked' : ''; } catch (Exception $e) { /* Do nothing */ } ?>" data-original-value="<?php try { echo $config->getConfig('learningModeGracePeriodEnabled') ? 1 : 0; } catch (Exception $e) { echo 0; } ?>"><i class="wf-ion-ios-checkmark-empty" aria-hidden="true"></i></div><span> <?php esc_html_e('Automatically enable on', 'wordfence'); ?> </span><input type="text" name="learningModeGracePeriod" id="input-learningModeGracePeriod" class="wf-datetime wf-form-control" placeholder="Enabled until..." data-value="<?php try { echo esc_attr($config->getConfig('learningModeGracePeriod') ? (int) $config->getConfig('learningModeGracePeriod') : ''); } catch (Exception $e) { /* Do nothing */ } ?>" data-original-value="<?php try { echo esc_attr($config->getConfig('learningModeGracePeriod') ? (int) $config->getConfig('learningModeGracePeriod') : ''); } catch (Exception $e) { /* Do nothing */ } ?>"<?php try { echo $config->getConfig('learningModeGracePeriodEnabled') ? '' : ' disabled'; } catch (Exception $e) { echo ' disabled'; } ?>></div>
|
||||
<?php endif; ?>
|
||||
</li>
|
||||
<li id="wf-option-protectionMode" class="wf-flex-vertical wf-flex-align-left">
|
||||
<h3><?php esc_html_e('Protection Level', 'wordfence'); ?></h3>
|
||||
<?php if ($firewall->protectionMode() == wfFirewall::PROTECTION_MODE_EXTENDED && !$firewall->isSubDirectoryInstallation()): ?>
|
||||
<p class="wf-no-top"><strong><?php esc_html_e('Extended Protection:', 'wordfence'); ?></strong> <?php esc_html_e('All PHP requests will be processed by the firewall prior to running.', 'wordfence'); ?></p>
|
||||
<p><?php echo wp_kses(sprintf(/* translators: Support URL. */ __('If you\'re moving to a new host or a new installation location, you may need to temporarily disable extended protection to avoid any file not found errors. Use this action to remove the configuration changes that enable extended protection mode or you can <a href="%s" target="_blank" rel="noopener noreferrer">remove them manually<span class="screen-reader-text"> (opens in new tab)</span></a>.', 'wordfence'), wfSupportController::esc_supportURL(wfSupportController::ITEM_FIREWALL_WAF_REMOVE_MANUALLY)), array('a'=>array('href'=>array(), 'target'=>array(), 'rel'=>array()), 'span'=>array('class'=>array()))); ?></p>
|
||||
<p class="wf-no-top"><a class="wf-btn wf-btn-default" href="#" id="wf-waf-uninstall" role="button"><?php esc_html_e('Remove Extended Protection', 'wordfence'); ?></a></p>
|
||||
<?php elseif ($firewall->isSubDirectoryInstallation()): ?>
|
||||
<p class="wf-no-top"><strong><?php esc_html_e('Existing WAF Installation Detected:', 'wordfence'); ?></strong> <?php esc_html_e('You are currently running the Wordfence Web Application Firewall from another WordPress installation. Please configure the firewall to run correctly on this site.', 'wordfence'); ?></p>
|
||||
<p><a class="wf-btn wf-btn-primary" href="#" id="wf-waf-install" role="button"><?php esc_html_e('Optimize the Wordfence Firewall', 'wordfence'); ?></a></p>
|
||||
<?php else: ?>
|
||||
<p class="wf-no-top"><strong><?php esc_html_e('Basic WordPress Protection:', 'wordfence'); ?></strong> <?php esc_html_e('The plugin will load as a regular plugin after WordPress has been loaded, and while it can block many malicious requests, some vulnerable plugins or WordPress itself may run vulnerable code before all plugins are loaded.', 'wordfence'); ?></p>
|
||||
<p><a class="wf-btn wf-btn-primary" href="#" id="wf-waf-install" role="button"><?php esc_html_e('Optimize the Wordfence Firewall', 'wordfence'); ?></a></p>
|
||||
<?php endif; ?>
|
||||
<script type="application/javascript">
|
||||
|
||||
(function($) {
|
||||
$(function() {
|
||||
var validateContinue = function() {
|
||||
var backupsAvailable = $('.wf-waf-backups:visible').data('backups');
|
||||
var backupsDownloaded = $('#wf-waf-server-config').data('backups');
|
||||
|
||||
var matchCount = 0;
|
||||
backupsAvailable = backupsAvailable.sort();
|
||||
backupsDownloaded = backupsDownloaded.sort();
|
||||
for (var i = 0; i < backupsAvailable.length; i++) {
|
||||
for (var n = 0; n < backupsDownloaded.length; n++) {
|
||||
if (backupsAvailable[i] == backupsDownloaded[n]) {
|
||||
matchCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$('#wf-waf-install-continue, #wf-waf-uninstall-continue').toggleClass('wf-disabled', matchCount != backupsAvailable.length);
|
||||
};
|
||||
|
||||
var installUninstallResponseHandler = function(action, res) {
|
||||
var modal = $('.wf-modal-title').closest('.wf-modal');
|
||||
if (res.needsCredentials) {
|
||||
var replacement = $(res.html);
|
||||
modal.replaceWith(replacement);
|
||||
modal = replacement;
|
||||
|
||||
var form = replacement.find('#request-filesystem-credentials-form').closest('form');
|
||||
form.find('input[type="submit"]').attr('type', 'hidden');
|
||||
form.on('submit', function(e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
WFAD.ajax(action, form.serialize(), function(res) {
|
||||
installUninstallResponseHandler(action, res);
|
||||
});
|
||||
});
|
||||
modal.find('#wf-waf-modal-continue').on('click', function(e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
form.trigger('submit');
|
||||
});
|
||||
$.wfcolorbox.resize();
|
||||
}
|
||||
else if (res.credentialsFailed || res.installationFailed || res.uninstallationFailed) {
|
||||
var replacement = $(res.html);
|
||||
modal.replaceWith(replacement);
|
||||
modal = replacement;
|
||||
modal.find('#wf-waf-modal-continue').on('click', function(e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
WFAD.colorboxClose();
|
||||
});
|
||||
$.wfcolorbox.resize();
|
||||
|
||||
var payload = {serverConfiguration: res.serverConfiguration, iniModified: 1};
|
||||
if (res.credentials) {
|
||||
payload['credentials'] = res.credentials;
|
||||
payload['credentialsSignature'] = res.credentialsSignature;
|
||||
}
|
||||
|
||||
$('.wf-waf-uninstall-try-again').on('click', function(e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
$(this).text('Retrying');
|
||||
payload['retryAttempted'] = 1;
|
||||
|
||||
WFAD.ajax(action, payload, function(res) {
|
||||
installUninstallResponseHandler(action, res);
|
||||
});
|
||||
});
|
||||
}
|
||||
else if (res.uninstallationWaiting) {
|
||||
var replacement = $(res.html);
|
||||
modal.replaceWith(replacement);
|
||||
modal = replacement;
|
||||
modal.find('#wf-waf-modal-continue').on('click', function(e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
WFAD.colorboxClose();
|
||||
}).addClass('wf-disabled');
|
||||
|
||||
var timeout = res.timeout; //In seconds
|
||||
setTimeout(function() {
|
||||
modal.find('#wf-waf-modal-continue').removeClass('wf-disabled');
|
||||
var payload = {serverConfiguration: res.serverConfiguration, iniModified: 1};
|
||||
if (res.credentials) {
|
||||
payload['credentials'] = res.credentials;
|
||||
payload['credentialsSignature'] = res.credentialsSignature;
|
||||
}
|
||||
WFAD.ajax(action, payload, function(res) {
|
||||
installUninstallResponseHandler(action, res);
|
||||
});
|
||||
}, (timeout + 10) * 1000);
|
||||
$.wfcolorbox.resize();
|
||||
}
|
||||
else if (res.ok) {
|
||||
var replacement = $(res.html);
|
||||
modal.replaceWith(replacement);
|
||||
modal = replacement;
|
||||
modal.find('#wf-waf-modal-continue').on('click', function(e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
<?php if (array_key_exists('wf_deactivate', $_GET)): ?>
|
||||
window.location.href = <?php echo json_encode(wfUtils::wpAdminURL('plugins.php?wf_deactivate=true')); ?>;
|
||||
<?php else: ?>
|
||||
window.location.reload(true);
|
||||
<?php endif ?>
|
||||
});
|
||||
$.wfcolorbox.resize();
|
||||
}
|
||||
else {
|
||||
WFAD.colorboxModal((WFAD.isSmallScreen ? '300px' : '400px'), <?php echo json_encode(__('Error During Setup', 'wordfence')) ?> , res.errorMsg);
|
||||
}
|
||||
};
|
||||
|
||||
var installUninstallHandler = function(html) {
|
||||
WFAD.colorboxHTML('800px', html, {overlayClose: false, closeButton: false, className: 'wf-modal', onComplete: function() {
|
||||
$('#wf-waf-server-config').data('backups', []);
|
||||
$('.wf-waf-backup-download').on('click', function(e) {
|
||||
var backupIndex = parseInt($(this).data('backupIndex'));
|
||||
var backupsAvailable = $(this).closest('.wf-waf-backups').data('backups');
|
||||
var backupsDownloaded = $('#wf-waf-server-config').data('backups');
|
||||
var found = false;
|
||||
for (var i = 0; i < backupsDownloaded.length; i++) {
|
||||
if (backupsDownloaded[i] == backupsAvailable[backupIndex]) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
backupsDownloaded.push(backupsAvailable[backupIndex]);
|
||||
$('#wf-waf-server-config').data('backups', backupsDownloaded);
|
||||
validateContinue();
|
||||
}
|
||||
});
|
||||
|
||||
$('#wf-waf-server-config').wfselect2({
|
||||
minimumResultsForSearch: -1,
|
||||
width: WFAD.isSmallScreen ? '300px' : '500px'
|
||||
});
|
||||
|
||||
$('#wf-waf-include-prepend > li').each(function(index, element) {
|
||||
$(element).on('click', function(e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
var control = $(this).closest('.wf-switch');
|
||||
var value = $(this).data('optionValue');
|
||||
|
||||
control.find('li').each(function() {
|
||||
$(this).toggleClass('wf-active', value == $(this).data('optionValue'));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
var nginxNotice = $('.wf-nginx-waf-config');
|
||||
var manualNotice = $('.wf-manual-waf-config');
|
||||
$('#wf-waf-server-config').on('change', function() {
|
||||
var el = $(this);
|
||||
if (manualNotice.length) {
|
||||
if (el.val() == 'manual') {
|
||||
manualNotice.fadeIn(400, function () {
|
||||
$.wfcolorbox.resize();
|
||||
});
|
||||
}
|
||||
else {
|
||||
manualNotice.fadeOut(400, function () {
|
||||
$.wfcolorbox.resize();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
var identifier = '.wf-waf-backups-' + el.val().replace(/[^a-z0-9\-]/i, '');
|
||||
$('.wf-waf-backups').hide();
|
||||
$(identifier).show();
|
||||
if ($(identifier).find('.wf-waf-backup-file-list').children().length > 0) {
|
||||
$('.wf-waf-download-instructions').show();
|
||||
}
|
||||
else {
|
||||
$('.wf-waf-download-instructions').hide();
|
||||
}
|
||||
|
||||
if (nginxNotice.length) { //Install only
|
||||
if (el.val() == 'nginx') {
|
||||
nginxNotice.fadeIn(400, function () {
|
||||
$.wfcolorbox.resize();
|
||||
});
|
||||
}
|
||||
else {
|
||||
nginxNotice.fadeOut(400, function () {
|
||||
$.wfcolorbox.resize();
|
||||
});
|
||||
}
|
||||
|
||||
validateContinue();
|
||||
return;
|
||||
}
|
||||
|
||||
$.wfcolorbox.resize();
|
||||
validateContinue();
|
||||
}).triggerHandler('change');
|
||||
|
||||
$('#wf-waf-install-continue').on('click', function(e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
var serverConfiguration = $('#wf-waf-server-config').val();
|
||||
var currentAutoPrepend = $('#wf-waf-include-prepend .wf-active').data('optionValue');
|
||||
|
||||
WFAD.ajax('wordfence_installAutoPrepend', {serverConfiguration: serverConfiguration, currentAutoPrepend: currentAutoPrepend}, function(res) {
|
||||
installUninstallResponseHandler('wordfence_installAutoPrepend', res);
|
||||
});
|
||||
});
|
||||
|
||||
$('#wf-waf-uninstall-continue').on('click', function(e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
if ($('.wf-manual-waf-config').is(':visible')) {
|
||||
WFAD.colorboxClose();
|
||||
return;
|
||||
}
|
||||
|
||||
var serverConfiguration = $('#wf-waf-server-config').val();
|
||||
|
||||
WFAD.ajax('wordfence_uninstallAutoPrepend', {serverConfiguration: serverConfiguration}, function(res) {
|
||||
installUninstallResponseHandler('wordfence_uninstallAutoPrepend', res);
|
||||
});
|
||||
});
|
||||
}});
|
||||
};
|
||||
|
||||
$('#wf-waf-install').on('click', function(e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
var installer = $('#wafTmpl_install').tmpl();
|
||||
var installerHTML = $("<div />").append(installer).html();
|
||||
installUninstallHandler(installerHTML);
|
||||
});
|
||||
|
||||
$('#wf-waf-uninstall').on('click', function(e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
var uninstaller = $('#wafTmpl_uninstall').tmpl();
|
||||
var uninstallerHTML = $("<div />").append(uninstaller).html();
|
||||
installUninstallHandler(uninstallerHTML);
|
||||
});
|
||||
|
||||
if (window.location.hash) {
|
||||
var hashes = WFAD.parseHashes();
|
||||
for (var i = 0; i < hashes.length; i++) {
|
||||
if (hashes[i] == 'configureAutoPrepend') {
|
||||
$('#wf-waf-install').trigger('click');
|
||||
history.replaceState('', document.title, window.location.pathname + window.location.search);
|
||||
}
|
||||
else if (hashes[i] == 'removeAutoPrepend') {
|
||||
$('#wf-waf-uninstall').trigger('click');
|
||||
history.replaceState('', document.title, window.location.pathname + window.location.search);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$(window).on('hashchange', function () {
|
||||
var hashes = WFAD.parseHashes();
|
||||
for (var i = 0; i < hashes.length; i++) {
|
||||
if (hashes[i] == 'configureAutoPrepend') {
|
||||
$('#wf-waf-install').trigger('click');
|
||||
history.replaceState('', document.title, window.location.pathname + window.location.search);
|
||||
}
|
||||
else if (hashes[i] == 'removeAutoPrepend') {
|
||||
$('#wf-waf-uninstall').trigger('click');
|
||||
history.replaceState('', document.title, window.location.pathname + window.location.search);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
})(jQuery);
|
||||
</script>
|
||||
</li>
|
||||
<li id="wf-option-disableWAFBlacklistBlocking" class="wf-flex-vertical wf-flex-align-left">
|
||||
<h3><?php esc_html_e('Real-Time IP Blocklist', 'wordfence'); ?></h3>
|
||||
<?php if ($firewall->ruleMode() == wfFirewall::RULE_MODE_COMMUNITY): ?>
|
||||
<p class="wf-no-top"><strong><?php esc_html_e('Premium Feature:', 'wordfence'); ?></strong> <?php esc_html_e('This feature blocks all traffic from IPs with a high volume of recent malicious activity using Wordfence\'s real-time blocklist.', 'wordfence'); ?></p>
|
||||
<p><a class="wf-btn wf-btn-primary wf-btn-callout-subtle" href="https://www.wordfence.com/gnl1blacklistUpgrade/wordfence-signup/#premium-order-form" target="_blank" rel="noopener noreferrer"><?php esc_html_e('Upgrade to Premium', 'wordfence'); ?></a> <a class="wf-btn wf-btn-callout-subtle wf-btn-default" href="https://www.wordfence.com/gnl1blacklistLearn/wordfence-signup/" target="_blank" rel="noopener noreferrer"><?php esc_html_e('Learn More', 'wordfence'); ?><span class="screen-reader-text"> (<?php esc_html_e('opens in new tab', 'wordfence') ?>)</span></a></p>
|
||||
<?php elseif ($firewall->isSubDirectoryInstallation()): ?>
|
||||
<p class="wf-no-top"><?php echo wp_kses(sprintf(__('You are currently running the Wordfence Web Application Firewall from another WordPress installation. Please <a href="%s">click here</a> to configure the Firewall to run correctly on this site.', 'wordfence'), esc_attr(network_admin_url('admin.php?page=WordfenceWAF&subpage=waf_options#configureAutoPrepend'))), array('a'=>array('href'=>array()))); ?></p>
|
||||
<?php else: ?>
|
||||
<p class="wf-no-top"><?php esc_html_e('This feature blocks all traffic from IPs with a high volume of recent malicious activity using Wordfence\'s real-time blocklist.', 'wordfence'); ?></p>
|
||||
<div class="wf-option wf-option-switch wf-padding-add-bottom" data-option-name="disableWAFBlacklistBlocking" data-original-value="<?php try { echo $config->getConfig('disableWAFBlacklistBlocking') ? '1': '0'; } catch (Exception $e) { echo 0; } ?>">
|
||||
<ul class="wf-switch" role="radiogroup">
|
||||
<?php
|
||||
$states = array(
|
||||
array('value' => '1', 'label' => __('Disabled', 'wordfence')),
|
||||
array('value' => '0', 'label' => __('Enabled', 'wordfence')),
|
||||
);
|
||||
|
||||
foreach ($states as $s):
|
||||
$disableBlacklist = false;
|
||||
try {
|
||||
$disableBlacklist = !!$config->getConfig('disableWAFBlacklistBlocking');
|
||||
}
|
||||
catch (Exception $e) { }
|
||||
?>
|
||||
<li<?php if ($s['value'] == ($disableBlacklist ? '1': '0')) { echo ' class="wf-active"'; } ?> data-option-value="<?php echo esc_attr($s['value']); ?>" role="radio" aria-checked="<?php echo (($s['value'] == ($disableBlacklist ? '1': '0')) ? 'true' : 'false'); ?>" tabindex="0"><?php echo esc_html($s['label']); ?></li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div> <!-- end basic firewall options -->
|
||||
<?php
|
||||
if ($firewall->protectionMode() == wfFirewall::PROTECTION_MODE_BASIC || ($firewall->protectionMode() == wfFirewall::PROTECTION_MODE_EXTENDED && $firewall->isSubDirectoryInstallation())) {
|
||||
echo wfView::create('waf/waf-install', array(
|
||||
))->render();
|
||||
}
|
||||
else {
|
||||
echo wfView::create('waf/waf-uninstall', array(
|
||||
))->render();
|
||||
}
|
||||
?>
|
||||
@@ -0,0 +1,285 @@
|
||||
<?php
|
||||
if (!defined('WORDFENCE_VERSION')) { exit; }
|
||||
/**
|
||||
* Presents the Brute Force Protection group.
|
||||
*
|
||||
* Expects $firewall, $waf, and $stateKey.
|
||||
*
|
||||
* @var wfFirewall $firewall
|
||||
* @var wfWAF $waf
|
||||
* @var string $stateKey The key under which the collapse state is stored.
|
||||
* @var bool $collapseable If defined, specifies whether or not this grouping can be collapsed. Defaults to true.
|
||||
*/
|
||||
|
||||
$config = $waf->getStorageEngine();
|
||||
|
||||
if (!isset($collapseable)) {
|
||||
$collapseable = true;
|
||||
}
|
||||
?>
|
||||
<div class="wf-row">
|
||||
<div class="wf-col-xs-12">
|
||||
<div class="wf-block<?php if (!$collapseable) { echo ' wf-always-active'; } else { echo (wfPersistenceController::shared()->isActive($stateKey) ? ' wf-active' : ''); } ?>" data-persistence-key="<?php echo esc_attr($stateKey); ?>">
|
||||
<div class="wf-block-header">
|
||||
<div class="wf-block-header-content">
|
||||
<div class="wf-block-title">
|
||||
<strong><?php esc_html_e('Brute Force Protection', 'wordfence'); ?></strong>
|
||||
</div>
|
||||
<?php if ($collapseable): ?><div class="wf-block-header-action"><div class="wf-block-header-action-disclosure" role="checkbox" aria-checked="<?php echo (wfPersistenceController::shared()->isActive($stateKey) ? 'true' : 'false'); ?>" tabindex="0"></div></div><?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="wf-block-content">
|
||||
<ul class="wf-block-list">
|
||||
<li>
|
||||
<?php
|
||||
echo wfView::create('options/option-switch', array(
|
||||
'optionName' => 'loginSecurityEnabled',
|
||||
'value' => wfConfig::get('loginSecurityEnabled') ? '1': '0',
|
||||
'titleHTML' => '<strong>' . esc_html__('Enable brute force protection', 'wordfence') . '</strong>',
|
||||
'subtitle' => __('This option enables all "Brute Force Protection" options, including strong password enforcement and invalid login throttling. You can modify individual options below.', 'wordfence'),
|
||||
'states' => array(
|
||||
array('value' => '0', 'label' => __('Off', 'wordfence')),
|
||||
array('value' => '1', 'label' => __('On', 'wordfence')),
|
||||
),
|
||||
'helpLink' => wfSupportController::supportURL(wfSupportController::ITEM_FIREWALL_WAF_OPTION_ENABLE_LOGIN_SECURITY),
|
||||
'noSpacer' => true,
|
||||
'alignment' => 'wf-right',
|
||||
))->render();
|
||||
?>
|
||||
</li>
|
||||
<li>
|
||||
<?php
|
||||
$breakpoints = array(2, 3, 4, 5, 6, 7, 8, 9, 10, 20, 30, 40, 50, 100, 200, 500);
|
||||
$options = array();
|
||||
foreach ($breakpoints as $b) {
|
||||
$options[] = array('value' => $b, 'label' => $b);
|
||||
}
|
||||
echo wfView::create('options/option-select', array(
|
||||
'selectOptionName' => 'loginSec_maxFailures',
|
||||
'selectOptions' => $options,
|
||||
'selectValue' => wfConfig::get('loginSec_maxFailures'),
|
||||
'title' => __('Lock out after how many login failures', 'wordfence'),
|
||||
'helpLink' => wfSupportController::supportURL(wfSupportController::ITEM_FIREWALL_WAF_OPTION_LOCK_OUT_FAILURE_COUNT),
|
||||
))->render();
|
||||
?>
|
||||
</li>
|
||||
<li>
|
||||
<?php
|
||||
$breakpoints = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 20, 30, 40, 50, 100, 200, 500);
|
||||
$options = array();
|
||||
foreach ($breakpoints as $b) {
|
||||
$options[] = array('value' => $b, 'label' => $b);
|
||||
}
|
||||
echo wfView::create('options/option-select', array(
|
||||
'selectOptionName' => 'loginSec_maxForgotPasswd',
|
||||
'selectOptions' => $options,
|
||||
'selectValue' => wfConfig::get('loginSec_maxForgotPasswd'),
|
||||
'title' => __('Lock out after how many forgot password attempts', 'wordfence'),
|
||||
'helpLink' => wfSupportController::supportURL(wfSupportController::ITEM_FIREWALL_WAF_OPTION_LOCK_OUT_FORGOT_PASSWORD_COUNT),
|
||||
))->render();
|
||||
?>
|
||||
</li>
|
||||
<li>
|
||||
<?php
|
||||
$breakpoints = array(5, 10, 30, 60, 120, 240, 360, 720, 1440);
|
||||
$options = array();
|
||||
foreach ($breakpoints as $b) {
|
||||
$options[] = array('value' => $b, 'label' => wfUtils::makeDuration($b * 60));
|
||||
}
|
||||
echo wfView::create('options/option-select', array(
|
||||
'selectOptionName' => 'loginSec_countFailMins',
|
||||
'selectOptions' => $options,
|
||||
'selectValue' => wfConfig::getInt('loginSec_countFailMins'),
|
||||
'title' => __('Count failures over what time period', 'wordfence'),
|
||||
'helpLink' => wfSupportController::supportURL(wfSupportController::ITEM_FIREWALL_WAF_OPTION_COUNT_TIME_PERIOD),
|
||||
))->render();
|
||||
?>
|
||||
</li>
|
||||
<li>
|
||||
<?php
|
||||
$breakpoints = array(5, 10, 30, 60, 120, 240, 360, 720, 1440, 2880, 7200, 14400, 28800, 43200, 86400);
|
||||
$options = array();
|
||||
foreach ($breakpoints as $b) {
|
||||
$options[] = array('value' => $b, 'label' => wfUtils::makeDuration($b * 60));
|
||||
}
|
||||
echo wfView::create('options/option-select', array(
|
||||
'selectOptionName' => 'loginSec_lockoutMins',
|
||||
'selectOptions' => $options,
|
||||
'selectValue' => wfConfig::getInt('loginSec_lockoutMins'),
|
||||
'title' => __('Amount of time a user is locked out', 'wordfence'),
|
||||
'helpLink' => wfSupportController::supportURL(wfSupportController::ITEM_FIREWALL_WAF_OPTION_LOCKOUT_DURATION),
|
||||
))->render();
|
||||
?>
|
||||
</li>
|
||||
<li>
|
||||
<?php
|
||||
echo wfView::create('options/option-toggled', array(
|
||||
'optionName' => 'loginSec_lockInvalidUsers',
|
||||
'enabledValue' => 1,
|
||||
'disabledValue' => 0,
|
||||
'value' => wfConfig::get('loginSec_lockInvalidUsers') ? 1 : 0,
|
||||
'title' => __('Immediately lock out invalid usernames', 'wordfence'),
|
||||
'helpLink' => wfSupportController::supportURL(wfSupportController::ITEM_FIREWALL_WAF_OPTION_IMMEDIATELY_LOCK_OUT_INVALID_USERS),
|
||||
))->render();
|
||||
?>
|
||||
</li>
|
||||
<li>
|
||||
<?php
|
||||
$blacklist = wfConfig::get('loginSec_userBlacklist', '');
|
||||
if (empty($blacklist)) {
|
||||
$users = array();
|
||||
}
|
||||
else {
|
||||
$users = explode("\n", wfUtils::cleanupOneEntryPerLine($blacklist));
|
||||
}
|
||||
|
||||
echo wfView::create('options/option-token', array(
|
||||
'tokenOptionName' => 'loginSec_userBlacklist',
|
||||
'tokenValue' => $users,
|
||||
'title' => __('Immediately block the IP of users who try to sign in as these usernames', 'wordfence'),
|
||||
'subtitle' => __('Hit enter to add a username', 'wordfence'),
|
||||
'helpLink' => wfSupportController::supportURL(wfSupportController::ITEM_FIREWALL_WAF_OPTION_IMMEDIATELY_BLOCK_USERS),
|
||||
))->render();
|
||||
?>
|
||||
</li>
|
||||
<li>
|
||||
<?php
|
||||
echo wfView::create('options/option-toggled-select', array(
|
||||
'toggleOptionName' => 'loginSec_breachPasswds_enabled',
|
||||
'enabledToggleValue' => 1,
|
||||
'disabledToggleValue' => 0,
|
||||
'toggleValue' => !!wfConfig::get('loginSec_breachPasswds_enabled') ? 1 : 0,
|
||||
'selectOptionName' => 'loginSec_breachPasswds',
|
||||
'selectOptions' => array(array('value' => 'admins', 'label' => __('For admins only', 'wordfence')), array('value' => 'pubs', 'label' => __('For all users with "publish posts" capability', 'wordfence'))),
|
||||
'selectValue' => wfConfig::get('loginSec_breachPasswds'),
|
||||
'title' => __('Prevent the use of passwords leaked in data breaches', 'wordfence'),
|
||||
'helpLink' => wfSupportController::supportURL(wfSupportController::ITEM_FIREWALL_WAF_OPTION_PREVENT_BREACH_PASSWORDS),
|
||||
))->render();
|
||||
?>
|
||||
</li>
|
||||
<li>
|
||||
<?php
|
||||
echo wfView::create('options/option-label', array(
|
||||
'titleHTML' => '<strong>' . esc_html__('Additional Options', 'wordfence') . '</strong>',
|
||||
'noSpacer' => true,
|
||||
))->render();
|
||||
?>
|
||||
</li>
|
||||
<li>
|
||||
<?php
|
||||
echo wfView::create('options/option-toggled-select', array(
|
||||
'toggleOptionName' => 'loginSec_strongPasswds_enabled',
|
||||
'enabledToggleValue' => 1,
|
||||
'disabledToggleValue' => 0,
|
||||
'toggleValue' => !!wfConfig::get('loginSec_strongPasswds_enabled') ? 1 : 0,
|
||||
'selectOptionName' => 'loginSec_strongPasswds',
|
||||
'selectOptions' => array(array('value' => 'pubs', 'label' => __('Force admins and publishers to use strong passwords (recommended)', 'wordfence')), array('value' => 'all', 'label' => __('Force all members to use strong passwords', 'wordfence'))),
|
||||
'selectValue' => wfConfig::get('loginSec_strongPasswds'),
|
||||
'title' => __('Enforce strong passwords', 'wordfence'),
|
||||
'helpLink' => wfSupportController::supportURL(wfSupportController::ITEM_FIREWALL_WAF_OPTION_ENFORCE_STRONG_PASSWORDS),
|
||||
))->render();
|
||||
?>
|
||||
</li>
|
||||
<li>
|
||||
<?php
|
||||
echo wfView::create('options/option-toggled', array(
|
||||
'optionName' => 'loginSec_maskLoginErrors',
|
||||
'enabledValue' => 1,
|
||||
'disabledValue' => 0,
|
||||
'value' => wfConfig::get('loginSec_maskLoginErrors') ? 1 : 0,
|
||||
'title' => __('Don\'t let WordPress reveal valid users in login errors', 'wordfence'),
|
||||
'helpLink' => wfSupportController::supportURL(wfSupportController::ITEM_FIREWALL_WAF_OPTION_MASK_LOGIN_ERRORS),
|
||||
))->render();
|
||||
?>
|
||||
</li>
|
||||
<li>
|
||||
<?php
|
||||
echo wfView::create('options/option-toggled', array(
|
||||
'optionName' => 'loginSec_blockAdminReg',
|
||||
'enabledValue' => 1,
|
||||
'disabledValue' => 0,
|
||||
'value' => wfConfig::get('loginSec_blockAdminReg') ? 1 : 0,
|
||||
'title' => __('Prevent users registering \'admin\' username if it doesn\'t exist', 'wordfence'),
|
||||
'helpLink' => wfSupportController::supportURL(wfSupportController::ITEM_FIREWALL_WAF_OPTION_PREVENT_ADMIN_REGISTRATION),
|
||||
))->render();
|
||||
?>
|
||||
</li>
|
||||
<li>
|
||||
<?php
|
||||
echo wfView::create('options/option-toggled', array(
|
||||
'optionName' => 'loginSec_disableAuthorScan',
|
||||
'enabledValue' => 1,
|
||||
'disabledValue' => 0,
|
||||
'value' => wfConfig::get('loginSec_disableAuthorScan') ? 1 : 0,
|
||||
'title' => __('Prevent discovery of usernames through \'/?author=N\' scans, the oEmbed API, the WordPress REST API, and WordPress XML Sitemaps', 'wordfence'),
|
||||
'helpLink' => wfSupportController::supportURL(wfSupportController::ITEM_FIREWALL_WAF_OPTION_PREVENT_AUTHOR_SCAN),
|
||||
))->render();
|
||||
?>
|
||||
</li>
|
||||
<li>
|
||||
<?php
|
||||
echo wfView::create('options/option-toggled', array(
|
||||
'optionName' => 'loginSec_disableApplicationPasswords',
|
||||
'enabledValue' => 1,
|
||||
'disabledValue' => 0,
|
||||
'value' => wfConfig::get('loginSec_disableApplicationPasswords') ? 1 : 0,
|
||||
'title' => __('Disable WordPress application passwords', 'wordfence'),
|
||||
'helpLink' => wfSupportController::supportURL(wfSupportController::ITEM_FIREWALL_WAF_OPTION_DISABLE_APPLICATION_PASSWORDS),
|
||||
))->render();
|
||||
?>
|
||||
</li>
|
||||
<li>
|
||||
<?php
|
||||
echo wfView::create('options/option-toggled', array(
|
||||
'optionName' => 'other_blockBadPOST',
|
||||
'enabledValue' => 1,
|
||||
'disabledValue' => 0,
|
||||
'value' => wfConfig::get('other_blockBadPOST') ? 1 : 0,
|
||||
'title' => __('Block IPs who send POST requests with blank User-Agent and Referer', 'wordfence'),
|
||||
'subtitleHTML' => esc_html__('If you use external services that may send POST requests without these headers, do not use this option, as they will be blocked.', 'wordfence'),
|
||||
'helpLink' => wfSupportController::supportURL(wfSupportController::ITEM_FIREWALL_WAF_OPTION_BLOCK_BAD_POST),
|
||||
))->render();
|
||||
?>
|
||||
</li>
|
||||
<li>
|
||||
<?php
|
||||
echo wfView::create('options/option-textarea', array(
|
||||
'textOptionName' => 'blockCustomText',
|
||||
'textValue' => wfConfig::get('blockCustomText'),
|
||||
'title' => __('Custom text shown on block pages', 'wordfence'),
|
||||
'alignTitle' => 'top',
|
||||
'subtitleHTML' => esc_html__('HTML tags will be stripped prior to output and line breaks will be converted into the appropriate tags.', 'wordfence'),
|
||||
'subtitlePosition' => 'value',
|
||||
'helpLink' => wfSupportController::supportURL(wfSupportController::ITEM_FIREWALL_WAF_OPTION_CUSTOM_BLOCK_TEXT),
|
||||
))->render();
|
||||
?>
|
||||
</li>
|
||||
<li>
|
||||
<?php
|
||||
echo wfView::create('options/option-toggled', array(
|
||||
'optionName' => 'other_pwStrengthOnUpdate',
|
||||
'enabledValue' => 1,
|
||||
'disabledValue' => 0,
|
||||
'value' => wfConfig::get('other_pwStrengthOnUpdate') ? 1 : 0,
|
||||
'title' => __('Check password strength on profile update', 'wordfence'),
|
||||
'helpLink' => wfSupportController::supportURL(wfSupportController::ITEM_FIREWALL_WAF_OPTION_CHECK_PASSWORD),
|
||||
))->render();
|
||||
?>
|
||||
</li>
|
||||
<li>
|
||||
<?php
|
||||
echo wfView::create('options/option-toggled', array(
|
||||
'optionName' => 'other_WFNet',
|
||||
'enabledValue' => 1,
|
||||
'disabledValue' => 0,
|
||||
'value' => wfConfig::get('other_WFNet') ? 1 : 0,
|
||||
'title' => __('Participate in the Real-Time Wordfence Security Network', 'wordfence'),
|
||||
'helpLink' => wfSupportController::supportURL(wfSupportController::ITEM_FIREWALL_WAF_OPTION_PARTICIPATE_WFSN),
|
||||
))->render();
|
||||
?>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div> <!-- end brute force protection -->
|
||||
@@ -0,0 +1,282 @@
|
||||
<?php
|
||||
if (!defined('WORDFENCE_VERSION')) { exit; }
|
||||
/**
|
||||
* Presents the Rate Limiting group.
|
||||
*
|
||||
* Expects $firewall, $waf, and $stateKey.
|
||||
*
|
||||
* @var wfFirewall $firewall
|
||||
* @var wfWAF $waf
|
||||
* @var string $stateKey The key under which the collapse state is stored.
|
||||
* @var bool $collapseable If defined, specifies whether or not this grouping can be collapsed. Defaults to true.
|
||||
*/
|
||||
|
||||
$config = $waf->getStorageEngine();
|
||||
|
||||
if (!isset($collapseable)) {
|
||||
$collapseable = true;
|
||||
}
|
||||
?>
|
||||
<div class="wf-row">
|
||||
<div class="wf-col-xs-12">
|
||||
<div class="wf-block<?php if (!$collapseable) { echo ' wf-always-active'; } else { echo (wfPersistenceController::shared()->isActive($stateKey) ? ' wf-active' : ''); } ?>" data-persistence-key="<?php echo esc_attr($stateKey); ?>">
|
||||
<div class="wf-block-header">
|
||||
<div class="wf-block-header-content">
|
||||
<div class="wf-block-title">
|
||||
<strong><?php esc_html_e('Rate Limiting', 'wordfence'); ?></strong>
|
||||
</div>
|
||||
<?php if ($collapseable): ?><div class="wf-block-header-action"><div class="wf-block-header-action-disclosure" role="checkbox" aria-checked="<?php echo (wfPersistenceController::shared()->isActive($stateKey) ? 'true' : 'false'); ?>" tabindex="0"></div></div><?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="wf-block-content">
|
||||
<ul class="wf-block-list">
|
||||
<li>
|
||||
<?php
|
||||
echo wfView::create('options/option-switch', array(
|
||||
'optionName' => 'firewallEnabled',
|
||||
'value' => wfConfig::get('firewallEnabled') ? '1': '0',
|
||||
'title' => __('Enable Rate Limiting and Advanced Blocking', 'wordfence'),
|
||||
'subtitle' => __('NOTE: This checkbox enables ALL blocking/throttling functions including IP, country and advanced blocking, and the "Rate Limiting Rules" below.', 'wordfence'),
|
||||
'states' => array(
|
||||
array('value' => '0', 'label' => __('Off', 'wordfence')),
|
||||
array('value' => '1', 'label' => __('On', 'wordfence')),
|
||||
),
|
||||
'helpLink' => wfSupportController::supportURL(wfSupportController::ITEM_FIREWALL_WAF_OPTION_ENABLE_ADVANCED_BLOCKING),
|
||||
'noSpacer' => true,
|
||||
'alignment' => 'wf-right',
|
||||
))->render();
|
||||
?>
|
||||
</li>
|
||||
<li>
|
||||
<?php
|
||||
echo wfView::create('options/option-select', array(
|
||||
'selectOptionName' => 'neverBlockBG',
|
||||
'selectOptions' => array(
|
||||
array('value' => 'neverBlockVerified', 'label' => __('Verified Google crawlers will not be rate-limited', 'wordfence')),
|
||||
array('value' => 'neverBlockUA', 'label' => __('Anyone claiming to be Google will not be rate-limited', 'wordfence')),
|
||||
array('value' => 'treatAsOtherCrawlers', 'label' => __('Treat Google like any other Crawler', 'wordfence')),
|
||||
),
|
||||
'selectValue' => wfConfig::get('neverBlockBG'),
|
||||
'title' => __('How should we treat Google\'s crawlers', 'wordfence'),
|
||||
'helpLink' => wfSupportController::supportURL(wfSupportController::ITEM_FIREWALL_WAF_OPTION_GOOGLE_ACTION),
|
||||
))->render();
|
||||
?>
|
||||
</li>
|
||||
<?php
|
||||
$rateOptions = array(
|
||||
array('value' => 'DISABLED', 'label' => __('Unlimited', 'wordfence')),
|
||||
array('value' => 1920, 'label' => sprintf(/* translators: Number of HTTP requests. */__('%d per minute', 'wordfence'), 1920)),
|
||||
array('value' => 960, 'label' => sprintf(/* translators: Number of HTTP requests. */__('%d per minute', 'wordfence'), 960)),
|
||||
array('value' => 480, 'label' => sprintf(/* translators: Number of HTTP requests. */__('%d per minute', 'wordfence'), 480)),
|
||||
array('value' => 240, 'label' => sprintf(/* translators: Number of HTTP requests. */__('%d per minute', 'wordfence'), 240)),
|
||||
array('value' => 120, 'label' => sprintf(/* translators: Number of HTTP requests. */__('%d per minute', 'wordfence'), 120)),
|
||||
array('value' => 60, 'label' => sprintf(/* translators: Number of HTTP requests. */__('%d per minute', 'wordfence'), 60)),
|
||||
array('value' => 30, 'label' => sprintf(/* translators: Number of HTTP requests. */__('%d per minute', 'wordfence'), 30)),
|
||||
array('value' => 15, 'label' => sprintf(/* translators: Number of HTTP requests. */__('%d per minute', 'wordfence'), 15)),
|
||||
array('value' => 10, 'label' => sprintf(/* translators: Number of HTTP requests. */__('%d per minute', 'wordfence'), 10)),
|
||||
array('value' => 5, 'label' => sprintf(/* translators: Number of HTTP requests. */__('%d per minute', 'wordfence'), 5)),
|
||||
array('value' => 4, 'label' => sprintf(/* translators: Number of HTTP requests. */__('%d per minute', 'wordfence'), 4)),
|
||||
array('value' => 3, 'label' => sprintf(/* translators: Number of HTTP requests. */__('%d per minute', 'wordfence'), 3)),
|
||||
array('value' => 2, 'label' => sprintf(/* translators: Number of HTTP requests. */__('%d per minute', 'wordfence'), 2)),
|
||||
array('value' => 1, 'label' => sprintf(/* translators: Number of HTTP requests. */__('%d per minute', 'wordfence'), 1)),
|
||||
);
|
||||
$actionOptions = array(
|
||||
array('value' => 'throttle', 'label' => __('throttle it', 'wordfence')),
|
||||
array('value' => 'block', 'label' => __('block it', 'wordfence')),
|
||||
);
|
||||
?>
|
||||
<li>
|
||||
<?php
|
||||
echo wfView::create('waf/option-rate-limit', array(
|
||||
'toggleOptionName' => 'maxGlobalRequests_enabled',
|
||||
'toggleValue' => !!wfConfig::get('maxGlobalRequests_enabled') ? 1 : 0,
|
||||
'rateOptionName' => 'maxGlobalRequests',
|
||||
'rateOptions' => $rateOptions,
|
||||
'rateValue' => wfConfig::get('maxGlobalRequests'),
|
||||
'lowValue' => 120,
|
||||
'actionOptionName' => 'maxGlobalRequests_action',
|
||||
'actionOptions' => $actionOptions,
|
||||
'actionValue' => wfConfig::get('maxGlobalRequests_action'),
|
||||
'title' => __('If anyone\'s requests exceed', 'wordfence'),
|
||||
'helpLink' => wfSupportController::supportURL(wfSupportController::ITEM_FIREWALL_WAF_OPTION_RATE_LIMIT_ANY),
|
||||
))->render();
|
||||
?>
|
||||
</li>
|
||||
<li>
|
||||
<?php
|
||||
echo wfView::create('waf/option-rate-limit', array(
|
||||
'toggleOptionName' => 'maxRequestsCrawlers_enabled',
|
||||
'toggleValue' => !!wfConfig::get('maxRequestsCrawlers_enabled') ? 1 : 0,
|
||||
'rateOptionName' => 'maxRequestsCrawlers',
|
||||
'rateOptions' => $rateOptions,
|
||||
'rateValue' => wfConfig::get('maxRequestsCrawlers'),
|
||||
'lowValue' => 120,
|
||||
'actionOptionName' => 'maxRequestsCrawlers_action',
|
||||
'actionOptions' => $actionOptions,
|
||||
'actionValue' => wfConfig::get('maxRequestsCrawlers_action'),
|
||||
'title' => __('If a crawler\'s page views exceed', 'wordfence'),
|
||||
'helpLink' => wfSupportController::supportURL(wfSupportController::ITEM_FIREWALL_WAF_OPTION_RATE_LIMIT_CRAWLER),
|
||||
))->render();
|
||||
?>
|
||||
</li>
|
||||
<li>
|
||||
<?php
|
||||
echo wfView::create('waf/option-rate-limit', array(
|
||||
'toggleOptionName' => 'max404Crawlers_enabled',
|
||||
'toggleValue' => !!wfConfig::get('max404Crawlers_enabled') ? 1 : 0,
|
||||
'rateOptionName' => 'max404Crawlers',
|
||||
'rateOptions' => $rateOptions,
|
||||
'rateValue' => wfConfig::get('max404Crawlers'),
|
||||
'lowValue' => 60,
|
||||
'actionOptionName' => 'max404Crawlers_action',
|
||||
'actionOptions' => $actionOptions,
|
||||
'actionValue' => wfConfig::get('max404Crawlers_action'),
|
||||
'title' => __('If a crawler\'s pages not found (404s) exceed', 'wordfence'),
|
||||
'helpLink' => wfSupportController::supportURL(wfSupportController::ITEM_FIREWALL_WAF_OPTION_RATE_LIMIT_CRAWLER_404),
|
||||
))->render();
|
||||
?>
|
||||
</li>
|
||||
<li>
|
||||
<?php
|
||||
echo wfView::create('waf/option-rate-limit', array(
|
||||
'toggleOptionName' => 'maxRequestsHumans_enabled',
|
||||
'toggleValue' => !!wfConfig::get('maxRequestsHumans_enabled') ? 1 : 0,
|
||||
'rateOptionName' => 'maxRequestsHumans',
|
||||
'rateOptions' => $rateOptions,
|
||||
'rateValue' => wfConfig::get('maxRequestsHumans'),
|
||||
'lowValue' => 120,
|
||||
'actionOptionName' => 'maxRequestsHumans_action',
|
||||
'actionOptions' => $actionOptions,
|
||||
'actionValue' => wfConfig::get('maxRequestsHumans_action'),
|
||||
'title' => __('If a human\'s page views exceed', 'wordfence'),
|
||||
'helpLink' => wfSupportController::supportURL(wfSupportController::ITEM_FIREWALL_WAF_OPTION_RATE_LIMIT_HUMAN),
|
||||
))->render();
|
||||
?>
|
||||
</li>
|
||||
<li>
|
||||
<?php
|
||||
echo wfView::create('waf/option-rate-limit', array(
|
||||
'toggleOptionName' => 'max404Humans_enabled',
|
||||
'toggleValue' => !!wfConfig::get('max404Humans_enabled') ? 1 : 0,
|
||||
'rateOptionName' => 'max404Humans',
|
||||
'rateOptions' => $rateOptions,
|
||||
'rateValue' => wfConfig::get('max404Humans'),
|
||||
'lowValue' => 60,
|
||||
'actionOptionName' => 'max404Humans_action',
|
||||
'actionOptions' => $actionOptions,
|
||||
'actionValue' => wfConfig::get('max404Humans_action'),
|
||||
'title' => __('If a human\'s pages not found (404s) exceed', 'wordfence'),
|
||||
'helpLink' => wfSupportController::supportURL(wfSupportController::ITEM_FIREWALL_WAF_OPTION_RATE_LIMIT_HUMAN_404),
|
||||
))->render();
|
||||
?>
|
||||
</li>
|
||||
<li>
|
||||
<?php
|
||||
$breakpoints = array(60, 300, 1800, 3600, 7200, 21600, 43200, 86400, 172800, 432000, 864000, 2592000);
|
||||
$options = array();
|
||||
foreach ($breakpoints as $b) {
|
||||
$options[] = array('value' => $b, 'label' => wfUtils::makeDuration($b));
|
||||
}
|
||||
echo wfView::create('options/option-select', array(
|
||||
'selectOptionName' => 'blockedTime',
|
||||
'selectOptions' => $options,
|
||||
'selectValue' => wfConfig::getInt('blockedTime'),
|
||||
'title' => __('How long is an IP address blocked when it breaks a rule', 'wordfence'),
|
||||
'helpLink' => wfSupportController::supportURL(wfSupportController::ITEM_FIREWALL_WAF_OPTION_AUTOMATIC_BLOCK_DURATION),
|
||||
))->render();
|
||||
?>
|
||||
</li>
|
||||
<li>
|
||||
<?php
|
||||
echo wfView::create('options/option-textarea', array(
|
||||
'textOptionName' => 'allowed404s',
|
||||
'textValue' => wfUtils::cleanupOneEntryPerLine(wfConfig::get('allowed404s')),
|
||||
'title' => __('Allowlisted 404 URLs', 'wordfence'),
|
||||
'subtitle' => __('These URL patterns will be excluded from the throttling rules used to limit crawlers.', 'wordfence'),
|
||||
'helpLink' => wfSupportController::supportURL(wfSupportController::ITEM_FIREWALL_WAF_OPTION_WHITELISTED_404),
|
||||
))->render();
|
||||
?>
|
||||
</li>
|
||||
</ul>
|
||||
<script type="application/javascript">
|
||||
(function($) {
|
||||
WFAD.updateRateLimitDisplay = function(value, lowValue, warningElement) {
|
||||
var hide = true;
|
||||
if (Number.isNaN) { //Anything except IE
|
||||
var originalRateValue = Number.parseInt(value);
|
||||
var lowValue = Number.parseInt(lowValue);
|
||||
if (!Number.isNaN(originalRateValue) && !Number.isNaN(lowValue)) {
|
||||
if (originalRateValue < lowValue) {
|
||||
hide = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else { //IE
|
||||
var originalRateValue = parseInt(value);
|
||||
var lowValue = parseInt(lowValue);
|
||||
if (!isNaN(originalRateValue) && !isNaN(lowValue)) {
|
||||
if (originalRateValue < lowValue) {
|
||||
hide = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$(warningElement).css('display', hide ? 'none' : 'block');
|
||||
};
|
||||
|
||||
$(function() {
|
||||
$('.wf-option.wf-option-rate-limit > .wf-option-content > ul > li.wf-option-select select').wfselect2({
|
||||
minimumResultsForSearch: -1
|
||||
}).on('change', function () {
|
||||
var optionElement = $(this).closest('.wf-option');
|
||||
if ($(this).hasClass('wf-rate-limit-rate')) {
|
||||
var option = optionElement.data('rateOption');
|
||||
var value = $(this).val();
|
||||
|
||||
var originalValue = optionElement.data('originalRateValue');
|
||||
if (originalValue == value) {
|
||||
delete WFAD.pendingChanges[option];
|
||||
}
|
||||
else {
|
||||
WFAD.pendingChanges[option] = value;
|
||||
}
|
||||
|
||||
WFAD.updateRateLimitDisplay(value, $(optionElement).data('lowValue'), $(optionElement).find('.wf-rate-limit-warning'));
|
||||
}
|
||||
else if ($(this).hasClass('wf-rate-limit-action')) {
|
||||
var option = optionElement.data('actionOption');
|
||||
var value = $(this).val();
|
||||
|
||||
var originalValue = optionElement.data('originalActionValue');
|
||||
if (originalValue == value) {
|
||||
delete WFAD.pendingChanges[option];
|
||||
}
|
||||
else {
|
||||
WFAD.pendingChanges[option] = value;
|
||||
}
|
||||
}
|
||||
|
||||
WFAD.updatePendingChanges();
|
||||
}).triggerHandler('change');
|
||||
|
||||
$(window).on('wfOptionsReset', function() {
|
||||
$('.wf-option.wf-option-rate-limit').each(function() {
|
||||
var originalRateValue = $(this).data('originalRateValue');
|
||||
$(this).find('.wf-rate-limit-rate').val(originalRateValue).trigger('change');
|
||||
var originalActionValue = $(this).data('originalActionValue');
|
||||
$(this).find('.wf-rate-limit-action').val(originalActionValue).trigger('change');
|
||||
WFAD.updateRateLimitDisplay($(this).data('originalRateValue'), $(this).data('lowValue'), $(this).find('.wf-rate-limit-warning'));
|
||||
});
|
||||
});
|
||||
|
||||
//Initial warning display
|
||||
$('.wf-option.wf-option-rate-limit').each(function() {
|
||||
WFAD.updateRateLimitDisplay($(this).data('originalRateValue'), $(this).data('lowValue'), $(this).find('.wf-rate-limit-warning'));
|
||||
});
|
||||
});
|
||||
})(jQuery);
|
||||
</script>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div> <!-- end rate limiting -->
|
||||
@@ -0,0 +1,304 @@
|
||||
<?php
|
||||
if (!defined('WORDFENCE_VERSION')) { exit; }
|
||||
/**
|
||||
* Presents the Whitelisted URLs group.
|
||||
*
|
||||
* Expects $firewall, $waf, and $stateKey.
|
||||
*
|
||||
* @var wfFirewall $firewall
|
||||
* @var wfWAF $waf
|
||||
* @var string $stateKey The key under which the collapse state is stored.
|
||||
* @var bool $collapseable If defined, specifies whether or not this grouping can be collapsed. Defaults to true.
|
||||
*/
|
||||
|
||||
$config = $waf->getStorageEngine();
|
||||
|
||||
if (!isset($collapseable)) {
|
||||
$collapseable = true;
|
||||
}
|
||||
?>
|
||||
<div class="wf-row">
|
||||
<div class="wf-col-xs-12">
|
||||
<div class="wf-block<?php if (!$collapseable) { echo ' wf-always-active'; } else { echo (wfPersistenceController::shared()->isActive($stateKey) ? ' wf-active' : ''); } ?>" data-persistence-key="<?php echo esc_attr($stateKey); ?>">
|
||||
<div class="wf-block-header">
|
||||
<div class="wf-block-header-content">
|
||||
<div class="wf-block-title">
|
||||
<strong><?php esc_html_e('Allowlisted URLs', 'wordfence'); ?></strong>
|
||||
</div>
|
||||
<?php if ($collapseable): ?><div class="wf-block-header-action"><div class="wf-block-header-action-disclosure" role="checkbox" aria-checked="<?php echo (wfPersistenceController::shared()->isActive($stateKey) ? 'true' : 'false'); ?>" tabindex="0"></div></div><?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="wf-block-content">
|
||||
<ul class="wf-block-list">
|
||||
<?php if ($firewall->isSubDirectoryInstallation()): ?>
|
||||
<li>
|
||||
<p><?php echo wp_kses(sprintf(__('You are currently running the Wordfence Web Application Firewall from another WordPress installation. Please <a href="%s">click here</a> to configure the Firewall to run correctly on this site.', 'wordfence'), esc_attr(network_admin_url('admin.php?page=WordfenceWAF&subpage=waf_options#configureAutoPrepend'))), array('a'=>array('href'=>array()))); ?></p>
|
||||
</li>
|
||||
<?php else: ?>
|
||||
<li>
|
||||
<?php
|
||||
echo wfView::create('waf/option-whitelist', array(
|
||||
))->render();
|
||||
?>
|
||||
</li>
|
||||
<li>
|
||||
<?php
|
||||
echo wfView::create('options/option-toggled-multiple', array(
|
||||
'options' => array(
|
||||
array(
|
||||
'name' => 'ajaxWatcherDisabled_front',
|
||||
'enabledValue' => 0,
|
||||
'disabledValue' => 1,
|
||||
'value' => wfConfig::get('ajaxWatcherDisabled_front') ? 1 : 0,
|
||||
'title' => __('Front-end Website', 'wordfence'),
|
||||
),
|
||||
array(
|
||||
'name' => 'ajaxWatcherDisabled_admin',
|
||||
'enabledValue' => 0,
|
||||
'disabledValue' => 1,
|
||||
'value' => wfConfig::get('ajaxWatcherDisabled_admin') ? 1 : 0,
|
||||
'title' => __('Admin Panel', 'wordfence'),
|
||||
),
|
||||
),
|
||||
'noSpacer' => true,
|
||||
'htmlTitle' => '<strong>' . esc_html__('Monitor background requests from an administrator\'s web browser for false positives', 'wordfence') . '</strong>',
|
||||
'helpLink' => wfSupportController::supportURL(wfSupportController::ITEM_FIREWALL_WAF_OPTION_MONITOR_AJAX),
|
||||
))->render();
|
||||
?>
|
||||
</li>
|
||||
<?php endif; ?>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div> <!-- end whitelisted urls -->
|
||||
<script type="text/x-jquery-template" id="waf-whitelisted-urls-tmpl">
|
||||
<div class="whitelist-table-container">
|
||||
<table class="wf-striped-table whitelist-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width: 2%;text-align: center"><div class="wf-whitelist-bulk-select wf-option-checkbox" role="checkbox" aria-checked="false" tabindex="0" aria-label="<?php esc_attr_e('Select/deselect all', 'wordfence'); ?>"><i class="wf-ion-ios-checkmark-empty" aria-hidden="true"></i></div></th>
|
||||
<th style="width: 5%;"><?php esc_html_e('Enabled', 'wordfence'); ?></th>
|
||||
<th><?php esc_html_e('URL', 'wordfence'); ?></th>
|
||||
<th><?php esc_html_e('Param', 'wordfence'); ?></th>
|
||||
<th><?php esc_html_e('Created', 'wordfence'); ?></th>
|
||||
<th><?php esc_html_e('Source', 'wordfence'); ?></th>
|
||||
<th><?php esc_html_e('User', 'wordfence'); ?></th>
|
||||
<th><?php esc_html_e('IP', 'wordfence'); ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
{{if whitelistedURLParams.length > 5}}
|
||||
<tfoot>
|
||||
<tr>
|
||||
<th style="width: 2%;text-align: center"><div class="wf-whitelist-bulk-select wf-option-checkbox" role="checkbox" aria-checked="false" tabindex="0" aria-label="<?php esc_attr_e('Select/deselect all', 'wordfence'); ?>"><i class="wf-ion-ios-checkmark-empty" aria-hidden="true"></i></div></th>
|
||||
<th style="width: 5%;"><?php esc_html_e('Enabled', 'wordfence'); ?></th>
|
||||
<th><?php esc_html_e('URL', 'wordfence'); ?></th>
|
||||
<th><?php esc_html_e('Param', 'wordfence'); ?></th>
|
||||
<th><?php esc_html_e('Created', 'wordfence'); ?></th>
|
||||
<th><?php esc_html_e('Source', 'wordfence'); ?></th>
|
||||
<th><?php esc_html_e('User', 'wordfence'); ?></th>
|
||||
<th><?php esc_html_e('IP', 'wordfence'); ?></th>
|
||||
</tr>
|
||||
{{/if}}
|
||||
</tfoot>
|
||||
<tbody>
|
||||
{{each(idx, whitelistedURLParam) whitelistedURLParams}}
|
||||
<tr data-index="${idx}" data-adding="{{if (whitelistedURLParam.adding)}}1{{else}}0{{/if}}" data-key="${whitelistedURLParam.path}|${whitelistedURLParam.paramKey}">
|
||||
<td style="text-align: center;"><div class="wf-whitelist-table-bulk-checkbox wf-option-checkbox" role="checkbox" aria-checked="false" tabindex="0" aria-label="<?php esc_attr_e('Select row ${idx}', 'wordfence'); ?>"><i class="wf-ion-ios-checkmark-empty" aria-hidden="true"></i></div></td>
|
||||
<td style="text-align: center;"><div class="wf-whitelist-item-enabled wf-option-checkbox{{if (!whitelistedURLParam.data.disabled)}} wf-checked{{/if}}" data-original-value="{{if (!whitelistedURLParam.data.disabled)}}1{{else}}0{{/if}}" role="checkbox" aria-checked="{{if (!whitelistedURLParam.data.disabled)}}true{{else}}false{{/if}}" tabindex="0" aria-label="<?php esc_attr_e('Toggle row ${idx}', 'wordfence'); ?>"><i class="wf-ion-ios-checkmark-empty" aria-hidden="true"></i></div></td>
|
||||
<td data-column="url">
|
||||
<input name="replaceWhitelistedPath" type="hidden" value="${whitelistedURLParam.path}">
|
||||
<span class="whitelist-display">${WFAD.htmlEscape(WFAD.base64_decode(whitelistedURLParam.path))}</span>
|
||||
<input name="whitelistedPath" class="whitelist-edit whitelist-path" type="text"
|
||||
value="${WFAD.htmlEscape(WFAD.base64_decode(whitelistedURLParam.path))}">
|
||||
</td>
|
||||
<td data-column="param">
|
||||
<input name="replaceWhitelistedParam" type="hidden" value="${whitelistedURLParam.paramKey}">
|
||||
<span class="whitelist-display">${WFAD.htmlEscape(WFAD.base64_decode(whitelistedURLParam.paramKey))}</span>
|
||||
<input name="whitelistedParam" class="whitelist-edit whitelist-param-key"
|
||||
type="text" value="${WFAD.htmlEscape(WFAD.base64_decode(whitelistedURLParam.paramKey))}">
|
||||
</td>
|
||||
<td>
|
||||
{{if (whitelistedURLParam.data.timestamp)}}
|
||||
${WFAD.dateFormat((new Date(whitelistedURLParam.data.timestamp * 1000)))}
|
||||
{{else}}
|
||||
-
|
||||
{{/if}}
|
||||
</td>
|
||||
<td data-column="source">
|
||||
{{if (whitelistedURLParam.data.description)}}
|
||||
${whitelistedURLParam.data.description}
|
||||
{{else}}
|
||||
-
|
||||
{{/if}}
|
||||
</td>
|
||||
<td data-column="user">
|
||||
{{if (whitelistedURLParam.data.userID)}}
|
||||
{{if (whitelistedURLParam.data.username)}}
|
||||
${whitelistedURLParam.data.username}
|
||||
{{else}}
|
||||
${whitelistedURLParam.data.userID}
|
||||
{{/if}}
|
||||
{{else}}
|
||||
-
|
||||
{{/if}}
|
||||
</td>
|
||||
<td data-column="ip">
|
||||
{{if (whitelistedURLParam.data.ip)}}
|
||||
${whitelistedURLParam.data.ip}
|
||||
{{else}}
|
||||
-
|
||||
{{/if}}
|
||||
</td>
|
||||
</tr>
|
||||
{{/each}}
|
||||
{{if (whitelistedURLParams.length == 0)}}
|
||||
<tr>
|
||||
<td colspan="8"><?php esc_html_e('No allowlisted URLs currently set.', 'wordfence'); ?></td>
|
||||
</tr>
|
||||
{{/if}}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</script>
|
||||
<script type="application/javascript">
|
||||
(function($) {
|
||||
function whitelistCheckAllVisible() {
|
||||
$('.wf-whitelist-bulk-select.wf-option-checkbox').toggleClass('wf-checked', true).attr('aria-checked', 'true');
|
||||
$('.wf-whitelist-table-bulk-checkbox.wf-option-checkbox').each(function() {
|
||||
$(this).toggleClass('wf-checked', $(this).closest('tr').is(':visible')).attr('aria-checked', $(this).closest('tr').is(':visible') ? 'true' : 'false');
|
||||
});
|
||||
}
|
||||
|
||||
function whitelistUncheckAll() {
|
||||
$('.wf-whitelist-bulk-select.wf-option-checkbox').toggleClass('wf-checked', false).attr('aria-checked', 'false');
|
||||
$('.wf-whitelist-table-bulk-checkbox.wf-option-checkbox').toggleClass('wf-checked', false).attr('aria-checked', 'false');
|
||||
}
|
||||
|
||||
$(window).on('wordfenceWAFInstallWhitelistEventHandlers', function() {
|
||||
//Enabled/Disabled
|
||||
$('.wf-whitelist-item-enabled.wf-option-checkbox').each(function() {
|
||||
$(this).on('keydown', function(e) {
|
||||
if (e.keyCode == 32) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
$(this).trigger('click');
|
||||
}
|
||||
});
|
||||
|
||||
$(this).on('click', function(e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
var row = $(this).closest('tr');
|
||||
var key = row.data('key');
|
||||
var value = $(this).hasClass('wf-checked') ? 1 : 0;
|
||||
if (value) {
|
||||
$(this).removeClass('wf-checked').attr('aria-checked', 'false');
|
||||
value = 0;
|
||||
}
|
||||
else {
|
||||
$(this).addClass('wf-checked').attr('aria-checked', 'true');
|
||||
value = 1;
|
||||
}
|
||||
|
||||
WFAD.wafWhitelistedChangeEnabled(key, value);
|
||||
WFAD.updatePendingChanges();
|
||||
});
|
||||
});
|
||||
|
||||
//Header/Footer Bulk Action
|
||||
$('.wf-whitelist-bulk-select.wf-option-checkbox').each(function() {
|
||||
$(this).on('keydown', function(e) {
|
||||
if (e.keyCode == 32) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
$(this).trigger('click');
|
||||
}
|
||||
});
|
||||
|
||||
$(this).on('click', function(e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
if ($(this).hasClass('wf-checked')) {
|
||||
$(this).removeClass('wf-checked').attr('aria-checked', 'false');
|
||||
whitelistUncheckAll();
|
||||
}
|
||||
else {
|
||||
$(this).addClass('wf-checked');
|
||||
whitelistCheckAllVisible().attr('aria-checked', 'true');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
//Row Bulk Action
|
||||
$('.wf-whitelist-table-bulk-checkbox.wf-option-checkbox').each(function() {
|
||||
$(this).on('keydown', function(e) {
|
||||
if (e.keyCode == 32) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
$(this).trigger('click');
|
||||
}
|
||||
});
|
||||
|
||||
$(this).on('click', function(e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
var row = $(this).closest('tr');
|
||||
var key = row.data('key');
|
||||
var value = $(this).hasClass('wf-checked') ? 1 : 0;
|
||||
if (value) {
|
||||
$(this).removeClass('wf-checked').attr('aria-checked', 'false');
|
||||
}
|
||||
else {
|
||||
$(this).addClass('wf-checked').attr('aria-checked', 'true');
|
||||
}
|
||||
|
||||
var totalCount = $('.wf-whitelist-table-bulk-checkbox.wf-option-checkbox:visible').length;
|
||||
var checkedCount = $('.wf-whitelist-table-bulk-checkbox.wf-option-checkbox.wf-checked:visible').length;
|
||||
if (totalCount == 0 || (checkedCount != totalCount)) {
|
||||
$('.wf-whitelist-bulk-select.wf-option-checkbox').removeClass('wf-checked').attr('aria-checked', 'false');
|
||||
}
|
||||
else {
|
||||
$('.wf-whitelist-bulk-select.wf-option-checkbox').addClass('wf-checked').attr('aria-checked', 'true');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$(window).trigger('wordfenceWAFApplyWhitelistFilter');
|
||||
});
|
||||
|
||||
$(window).on('wordfenceWAFApplyWhitelistFilter', function() {
|
||||
if (WFAD.wafData.whitelistedURLParams.length == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
var filterColumn = $('#whitelist-table-controls select').val();
|
||||
var filterValue = $('input[name="filterValue"]').val();
|
||||
if (typeof filterValue != 'string' || filterValue.length == 0) {
|
||||
$('#waf-whitelisted-urls-wrapper .whitelist-table > tbody > tr[data-index]').show();
|
||||
}
|
||||
else {
|
||||
$('#waf-whitelisted-urls-wrapper .whitelist-table > tbody > tr[data-index]').each(function() {
|
||||
var text = $(this).find('td[data-column="' + filterColumn + '"]').text();
|
||||
if (text.indexOf(filterValue) > -1) {
|
||||
$(this).show();
|
||||
}
|
||||
else {
|
||||
$(this).hide();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
$(window).on('wordfenceWAFConfigPageRender', function() {
|
||||
//Add event handler to whitelist checkboxes
|
||||
$(window).trigger('wordfenceWAFInstallWhitelistEventHandlers');
|
||||
});
|
||||
})(jQuery);
|
||||
</script>
|
||||
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
if (!defined('WORDFENCE_VERSION')) { exit; }
|
||||
?>
|
||||
<ul class="wf-flex-horizontal wf-flex-full-width wf-no-top">
|
||||
<li class="wf-tip-light-bulb"><i class="wf-ion-ios-lightbulb-outline"></i></li>
|
||||
<li class="wf-tip-info-message"><strong><?php echo wp_kses(sprintf(/* translators: Support URL. */ __('The Web Application Firewall is currently in Learning Mode. <a href="%s" target="_blank" rel="noopener noreferrer">Learn More<span class="screen-reader-text"> (opens in new tab)</span></a>', 'wordfence'), wfSupportController::supportURL(wfSupportController::ITEM_FIREWALL_WAF_LEARNING_MODE)), array('a'=>array('href'=>array(), 'target'=>array(), 'rel'=>array()), 'span'=>array('class'=>array()))); ?></strong></li>
|
||||
</ul>
|
||||
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
if (!defined('WORDFENCE_VERSION')) { exit; }
|
||||
|
||||
/**
|
||||
* Presents the manual message for WAF auto prepend installation.
|
||||
*
|
||||
*/
|
||||
|
||||
?>
|
||||
<p><?php echo wp_kses(__('The required file has been created. You\'ll need to insert the following code into your <code>php.ini</code> to finish installation:', 'wordfence'), array('code'=>array())); ?></p>
|
||||
<pre class="wf-pre">auto_prepend_file = '<?php echo esc_html(addcslashes(wordfence::getWAFBootstrapPath(), "'")); ?>'</pre>
|
||||
<p><?php echo wp_kses(sprintf(/* translators: Support URL. */ __('You can find more details on alternative setup steps, including installation on SiteGround or for multiple sites sharing a single php.ini, <a target="_blank" rel="noopener noreferrer" href="%s">in our documentation<span class="screen-reader-text"> (opens in new tab)</span></a>.', 'wordfence'), wfSupportController::esc_supportURL(wfSupportController::ITEM_FIREWALL_WAF_INSTALL_MANUALLY)), array('a'=>array('href'=>array(), 'target'=>array(), 'rel'=>array()), 'span'=>array('class'=>array()))); ?></p>
|
||||
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
if (!defined('WORDFENCE_VERSION')) { exit; }
|
||||
|
||||
/**
|
||||
* Presents the success message for WAF auto prepend installation.
|
||||
*
|
||||
* Expects $active.
|
||||
*
|
||||
* @var bool $active True if the WAF's auto_prepend_file is active and not because of a subdirectory install.
|
||||
*/
|
||||
|
||||
if ($active):
|
||||
?>
|
||||
<p><?php esc_html_e('Nice work! The firewall is now optimized.', 'wordfence'); ?></p>
|
||||
<?php else: ?>
|
||||
<p><?php esc_html_e('The changes have not yet taken effect. If you are using LiteSpeed or IIS as your web server or CGI/FastCGI interface, you may need to wait a few minutes for the changes to take effect since the configuration files are sometimes cached. You also may need to select a different server configuration in order to complete this step, but wait for a few minutes before trying. You can try refreshing this page.', 'wordfence'); ?></p>
|
||||
<?php endif; ?>
|
||||
110
wp/wp-content/plugins/wordfence/views/waf/waf-install.php
Normal file
110
wp/wp-content/plugins/wordfence/views/waf/waf-install.php
Normal file
@@ -0,0 +1,110 @@
|
||||
<?php
|
||||
if (!defined('WORDFENCE_VERSION')) { exit; }
|
||||
?>
|
||||
<script type="text/x-jquery-template" id="wafTmpl_install">
|
||||
<div class="wf-modal">
|
||||
<div class="wf-modal-header">
|
||||
<div class="wf-modal-header-content">
|
||||
<div class="wf-modal-title">
|
||||
<strong><?php esc_html_e('Optimize Wordfence Firewall', 'wordfence'); ?></strong>
|
||||
</div>
|
||||
</div>
|
||||
<div class="wf-modal-header-action">
|
||||
<div><?php esc_html_e('If you cannot complete the setup process, ', 'wordfence'); ?><a target="_blank" rel="noopener noreferrer" href="<?php echo wfSupportController::esc_supportURL(wfSupportController::ITEM_FIREWALL_WAF_INSTALL_MANUALLY); ?>"><?php esc_html_e('click here for help', 'wordfence'); ?><span class="screen-reader-text"> (<?php esc_html_e('opens in new tab', 'wordfence') ?>)</span></a></div>
|
||||
<div class="wf-padding-add-left-small wf-modal-header-action-close"><a href="#" onclick="WFAD.colorboxClose(); return false" role="button"><i class="wf-fa wf-fa-times-circle" aria-hidden="true"></i></a></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="wf-modal-content">
|
||||
<?php
|
||||
$currentAutoPrependFile = ini_get('auto_prepend_file');
|
||||
if (empty($currentAutoPrependFile) || WF_IS_WP_ENGINE || WF_IS_PRESSABLE || WF_IS_FLYWHEEL):
|
||||
?>
|
||||
<p><?php echo wp_kses(__('To make your site as secure as possible, the Wordfence Web Application Firewall is designed to run via a PHP setting called <code>auto_prepend_file</code>, which ensures it runs before any potentially vulnerable code runs.', 'wordfence'), array('code'=>array())); ?></p>
|
||||
<?php else: ?>
|
||||
<p><?php echo wp_kses(__('To make your site as secure as possible, the Wordfence Web Application Firewall is designed to run via a PHP setting called <code>auto_prepend_file</code>, which ensures it runs before any potentially vulnerable code runs. This PHP setting is currently in use, and is including this file:', 'wordfence'), array('code'=>array())); ?></p>
|
||||
<pre class='wf-pre'><?php echo esc_html($currentAutoPrependFile); ?></pre>
|
||||
<p><?php echo wp_kses(__('If you don\'t recognize this file, please <a href="https://wordpress.org/support/plugin/wordfence" target="_blank" rel="noopener noreferrer">contact us on the WordPress support forums<span class="screen-reader-text"> (opens in new tab)</span></a> before proceeding.', 'wordfence'), array('a'=>array('href'=>array(), 'target'=>array(), 'rel'=>array()), 'span'=>array('class'=>array()))); ?></p>
|
||||
<p><?php echo wp_kses(__('You can proceed with the installation and we will include this from within our <code>wordfence-waf.php</code> file which should maintain compatibility with your site, or you can opt to override the existing PHP setting.', 'wordfence'), array('code'=>array())); ?></p>
|
||||
<ul id="wf-waf-include-prepend" class="wf-switch"><li class="wf-active" data-option-value="include"><?php esc_html_e('Include', 'wordfence'); ?></li><li data-option-value="override"><?php esc_html_e('Override', 'wordfence'); ?></li></ul>
|
||||
<?php endif; ?>
|
||||
<div class="wf-notice"><strong><?php esc_html_e('NOTE:', 'wordfence'); ?></strong> <?php esc_html_e('If you have separate WordPress installations with Wordfence installed within a subdirectory of this site, it is recommended that you perform the Firewall installation procedure on those sites before this one.', 'wordfence'); ?></div>
|
||||
<?php
|
||||
$serverInfo = wfWebServerInfo::createFromEnvironment();
|
||||
$dropdown = array(
|
||||
array("apache-mod_php", __('Apache + mod_php', 'wordfence'), $serverInfo->isApacheModPHP(), wfWAFAutoPrependHelper::helper('apache-mod_php')->getFilesNeededForBackup()),
|
||||
array("apache-suphp", __('Apache + suPHP', 'wordfence'), $serverInfo->isApacheSuPHP(), wfWAFAutoPrependHelper::helper('apache-suphp')->getFilesNeededForBackup()),
|
||||
array("cgi", __('Apache + CGI/FastCGI', 'wordfence'), $serverInfo->isApache() && !$serverInfo->isApacheSuPHP() && ($serverInfo->isCGI() || $serverInfo->isFastCGI()), wfWAFAutoPrependHelper::helper('cgi')->getFilesNeededForBackup()),
|
||||
array("litespeed", __('LiteSpeed/lsapi', 'wordfence'), $serverInfo->isLiteSpeed(), wfWAFAutoPrependHelper::helper('litespeed')->getFilesNeededForBackup()),
|
||||
array("nginx", __('NGINX', 'wordfence'), $serverInfo->isNGINX(), wfWAFAutoPrependHelper::helper('nginx')->getFilesNeededForBackup()),
|
||||
array("iis", __('Windows (IIS)', 'wordfence'), $serverInfo->isIIS(), wfWAFAutoPrependHelper::helper('iis')->getFilesNeededForBackup()),
|
||||
array("manual", __('Manual Configuration', 'wordfence'), false, array()),
|
||||
);
|
||||
|
||||
$hasRecommendedOption = false;
|
||||
$wafPrependOptions = '';
|
||||
foreach ($dropdown as $option) {
|
||||
list($optionValue, $optionText, $selected) = $option;
|
||||
$optionValue=esc_attr($optionValue);
|
||||
$optionText=esc_html($optionText);
|
||||
$wafPrependOptions .= "<option value=\"{$optionValue}\"" . ($selected ? ' selected' : '') . ">{$optionText}" . ($selected ? ' (recommended based on our tests)' : '') . "</option>\n";
|
||||
if ($selected) {
|
||||
$hasRecommendedOption = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$hasRecommendedOption): ?>
|
||||
<p><?php esc_html_e('If you know your web server\'s configuration, please select it from the list below.', 'wordfence'); ?></p>
|
||||
<?php else: ?>
|
||||
<p><?php esc_html_e('We\'ve preselected your server configuration based on our tests, but if you know your web server\'s configuration, please select it now. You can also choose "Manual Configuration" for alternate installation details.', 'wordfence'); ?></p>
|
||||
<?php endif; ?>
|
||||
<select name='serverConfiguration' id='wf-waf-server-config'>
|
||||
<?php echo $wafPrependOptions; ?>
|
||||
</select>
|
||||
<div class="wf-notice wf-nginx-waf-config" style="display: none;"><?php wp_kses(printf(/* translators: 1. PHP ini setting. 2. Support URL. */ __('Part of the Firewall configuration procedure for NGINX depends on creating a <code>%1$s</code> file in the root of your WordPress installation. This file can contain sensitive information and public access to it should be restricted. We have <a href="%2$s" target="_blank" rel="noreferrer noopener">instructions on our documentation site<span class="screen-reader-text"> (opens in new tab)</span></a> on what directives to put in your nginx.conf to fix this.', 'wordfence'), esc_html(ini_get('user_ini.filename') ? ini_get('user_ini.filename') : '(.user.ini)'), wfSupportController::esc_supportURL(wfSupportController::ITEM_FIREWALL_WAF_INSTALL_NGINX)), array('a'=>array('href'=>array(), 'target'=>array(), 'rel'=>array()), 'span'=>array('class'=>array()))); ?></div>
|
||||
<div class="wf-manual-waf-config" style="display: none;">
|
||||
<p><?php esc_html_e('If you are using a web server not listed in the dropdown or if file permissions prevent the installer from completing successfully, you will need to perform the change manually. Click Continue below to create the required file and view manual installation instructions.', 'wordfence'); ?></p>
|
||||
</div>
|
||||
<?php
|
||||
$adminURL = network_admin_url('admin.php?page=WordfenceWAF&subpage=waf_options&action=configureAutoPrepend');
|
||||
$wfnonce = wp_create_nonce('wfWAFAutoPrepend');
|
||||
foreach ($dropdown as $option):
|
||||
list($optionValue, $optionText, $selected) = $option;
|
||||
$class = preg_replace('/[^a-z0-9\-]/i', '', $optionValue);
|
||||
$helper = new wfWAFAutoPrependHelper($optionValue, null);
|
||||
$backups = $helper->getFilesNeededForBackup();
|
||||
$filteredBackups = array();
|
||||
foreach ($backups as $index => $backup) {
|
||||
if (!file_exists($backup)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$filteredBackups[$index] = $backup;
|
||||
}
|
||||
$jsonBackups = json_encode(array_map('basename', $filteredBackups));
|
||||
?>
|
||||
<div class="wf-waf-backups wf-waf-backups-<?php echo $class; ?>" style="display: none;" data-backups="<?php echo esc_attr($jsonBackups); ?>">
|
||||
<?php if (count($filteredBackups)): ?><p><?php esc_html_e('Please download a backup of the following files before we make the necessary changes:', 'wordfence'); ?></p><?php endif; ?>
|
||||
<ul class="wf-waf-backup-file-list">
|
||||
<?php
|
||||
foreach ($filteredBackups as $index => $backup) {
|
||||
echo '<li><a class="wf-btn wf-btn-default wf-waf-backup-download" data-backup-index="' . $index . '" href="' .
|
||||
esc_url(add_query_arg(array(
|
||||
'downloadBackup' => 1,
|
||||
'backupIndex' => $index,
|
||||
'serverConfiguration' => $helper->getServerConfig(),
|
||||
'wfnonce' => $wfnonce,
|
||||
), $adminURL)) . '">' . esc_html(sprintf(/* translators: File path. */ __('Download %s', 'wordfence'), basename($backup))) . '</a></li>';
|
||||
}
|
||||
?>
|
||||
</ul>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<div class="wf-modal-footer">
|
||||
<ul class="wf-flex-horizontal wf-flex-full-width">
|
||||
<li class="wf-waf-download-instructions"><?php esc_html_e('Once you have downloaded the files, click Continue to complete the setup.', 'wordfence'); ?></li>
|
||||
<li class="wf-right"><a href="#" class="wf-btn wf-btn-primary wf-btn-callout-subtle wf-disabled" id="wf-waf-install-continue" role="button"><?php esc_html_e('Continue', 'wordfence'); ?></a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</script>
|
||||
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
if (!defined('WORDFENCE_VERSION')) { exit; }
|
||||
/**
|
||||
* Presents the content given in a modal wrapper for the WAF install/uninstall flow.
|
||||
*
|
||||
* Expects $title and $html to be defined. $helpHTML, $footerHTML, and $footerButtonTitle may also be defined.
|
||||
*
|
||||
* @var string $title The title for the panel.
|
||||
* @var string $html The main HTML content for the panel.
|
||||
* @var string $helpHTML HTML content for the help area next to the close button.
|
||||
* @var string $footerHTML HTML content for the footer area next to the footer button.
|
||||
* @var string $footerButtonTitle Title for the footer button, defaults to "Continue".
|
||||
* @var bool $noX Optional, hides the top right x button if truthy.
|
||||
*/
|
||||
|
||||
if (!isset($footerButtonTitle)) {
|
||||
$footerButtonTitle = __('Continue', 'wordfence');
|
||||
}
|
||||
|
||||
$showX = !isset($noX) || !$noX;
|
||||
?>
|
||||
<div class="wf-modal">
|
||||
<div class="wf-modal-header">
|
||||
<div class="wf-modal-header-content">
|
||||
<div class="wf-modal-title">
|
||||
<strong><?php echo $title; ?></strong>
|
||||
</div>
|
||||
</div>
|
||||
<div class="wf-modal-header-action">
|
||||
<div><?php if (isset($helpHTML)) { echo $helpHTML; } ?></div>
|
||||
<?php if ($showX) { ?><div class="wf-padding-add-left-small wf-modal-header-action-close"><a href="#" onclick="WFAD.colorboxClose(); return false" role="button"><i class="wf-fa wf-fa-times-circle" aria-hidden="true"></i></a></div><?php } ?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="wf-modal-content">
|
||||
<?php echo $html; ?>
|
||||
</div>
|
||||
<div class="wf-modal-footer">
|
||||
<ul class="wf-flex-horizontal wf-flex-full-width">
|
||||
<li><?php if (isset($footerHTML)) { echo $footerHTML; } ?></li>
|
||||
<li class="wf-right"><a href="#" class="wf-btn wf-btn-primary wf-btn-callout-subtle" id="wf-waf-modal-continue" role="button"><?php echo esc_html($footerButtonTitle); ?></a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
if (!defined('WORDFENCE_VERSION')) { exit; }
|
||||
|
||||
/**
|
||||
* Presents the success message for WAF auto prepend uninstallation.
|
||||
*
|
||||
* Expects $active and $subdirectory.
|
||||
*
|
||||
* @var bool $active True if the WAF's auto_prepend_file is active and not because of a subdirectory install.
|
||||
* @var bool $subdirectory True if the WAF's auto_prepend_file is active because of a subdirectory install.
|
||||
*/
|
||||
|
||||
if (!$active && !$subdirectory):
|
||||
?>
|
||||
<p><?php esc_html_e('Uninstallation was successful!', 'wordfence'); ?></p>
|
||||
<?php elseif (!$active): ?>
|
||||
<p><?php esc_html_e('Uninstallation from this site was successful! The Wordfence Firewall is still active because it is installed in another WordPress installation.', 'wordfence'); ?></p>
|
||||
<?php else: ?>
|
||||
<p><?php esc_html_e('The changes have not yet taken effect. If you are using LiteSpeed or IIS as your web server or CGI/FastCGI interface, you may need to wait a few minutes for the changes to take effect since the configuration files are sometimes cached. You also may need to select a different server configuration in order to complete this step, but wait for a few minutes before trying. You can try refreshing this page.', 'wordfence'); ?></p>
|
||||
<?php endif; ?>
|
||||
112
wp/wp-content/plugins/wordfence/views/waf/waf-uninstall.php
Normal file
112
wp/wp-content/plugins/wordfence/views/waf/waf-uninstall.php
Normal file
@@ -0,0 +1,112 @@
|
||||
<?php
|
||||
if (!defined('WORDFENCE_VERSION')) { exit; }
|
||||
?>
|
||||
<script type="text/x-jquery-template" id="wafTmpl_uninstall">
|
||||
<div class="wf-modal">
|
||||
<div class="wf-modal-header">
|
||||
<div class="wf-modal-header-content">
|
||||
<div class="wf-modal-title">
|
||||
<strong><?php esc_html_e('Uninstall Wordfence Firewall', 'wordfence'); ?></strong>
|
||||
</div>
|
||||
</div>
|
||||
<div class="wf-modal-header-action">
|
||||
<div><?php echo wp_kses(sprintf(__('If you cannot complete the uninstall process, <a target="_blank" rel="noopener noreferrer" href="%s">click here for help<span class="screen-reader-text"> (opens in new tab)</span></a>', 'wordfence'), wfSupportController::esc_supportURL(wfSupportController::ITEM_FIREWALL_WAF_REMOVE_MANUALLY)), array('a'=>array('href'=>array(), 'target'=>array(), 'rel'=>array()), 'span'=>array('class'=>array()))); ?></div>
|
||||
<div class="wf-padding-add-left-small wf-modal-header-action-close"><a href="#" onclick="WFAD.colorboxClose(); return false" role="button"><i class="wf-fa wf-fa-times-circle" aria-hidden="true"></i></a></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="wf-modal-content">
|
||||
<?php
|
||||
if (WF_IS_WP_ENGINE || WF_IS_PRESSABLE || WF_IS_FLYWHEEL) {
|
||||
$currentAutoPrependFile = wordfence::getWAFBootstrapPath();
|
||||
} else {
|
||||
$currentAutoPrependFile = ini_get('auto_prepend_file');
|
||||
}
|
||||
|
||||
?>
|
||||
<p><?php echo wp_kses(__('Extended Protection Mode of the Wordfence Web Application Firewall uses the PHP ini setting called <code>auto_prepend_file</code> in order to ensure it runs before any potentially vulnerable code runs. This PHP setting currently refers to the Wordfence file at:', 'wordfence'), array('code'=>array())); ?></p>
|
||||
<pre class='wf-pre'><?php echo esc_html($currentAutoPrependFile); ?></pre>
|
||||
<?php
|
||||
$contents = file_get_contents($currentAutoPrependFile);
|
||||
$refersToWAF = preg_match('/define\s*\(\s*(["\'])WFWAF_LOG_PATH\1\s*,\s*(__DIR__\s*\.\s*)?(["\']).+?\3\s*\)\s*/', $contents);
|
||||
|
||||
if (!$refersToWAF):
|
||||
?>
|
||||
<p><?php echo wp_kses(sprintf(/* translators: Support URL. */ __('Automatic uninstallation cannot be completed, but you may still be able to <a href="%s" target="_blank" rel="noopener noreferrer">manually uninstall extended protection<span class="screen-reader-text"> (opens in new tab)</span></a>.', 'wordfence'), wfSupportController::esc_supportURL(wfSupportController::ITEM_FIREWALL_WAF_REMOVE_MANUALLY)), array('a'=>array('href'=>array(), 'target'=>array(), 'rel'=>array()), 'span'=>array('class'=>array()))); ?></p>
|
||||
<?php else: ?>
|
||||
<p><?php echo wp_kses(__('Before this file can be deleted, the configuration for the <code>auto_prepend_file</code> setting needs to be removed.', 'wordfence'), array('code'=>array())); ?></p>
|
||||
<?php
|
||||
$serverInfo = wfWebServerInfo::createFromEnvironment();
|
||||
$dropdown = array(
|
||||
array("apache-mod_php", __('Apache + mod_php', 'wordfence'), $serverInfo->isApacheModPHP(), wfWAFAutoPrependHelper::helper('apache-mod_php')->getFilesNeededForBackup()),
|
||||
array("apache-suphp", __('Apache + suPHP', 'wordfence'), $serverInfo->isApacheSuPHP(), wfWAFAutoPrependHelper::helper('apache-suphp')->getFilesNeededForBackup()),
|
||||
array("cgi", __('Apache + CGI/FastCGI', 'wordfence'), $serverInfo->isApache() && !$serverInfo->isApacheSuPHP() && ($serverInfo->isCGI() || $serverInfo->isFastCGI()), wfWAFAutoPrependHelper::helper('cgi')->getFilesNeededForBackup()),
|
||||
array("litespeed", __('LiteSpeed/lsapi', 'wordfence'), $serverInfo->isLiteSpeed(), wfWAFAutoPrependHelper::helper('litespeed')->getFilesNeededForBackup()),
|
||||
array("nginx", __('NGINX', 'wordfence'), $serverInfo->isNGINX(), wfWAFAutoPrependHelper::helper('nginx')->getFilesNeededForBackup()),
|
||||
array("iis", __('Windows (IIS)', 'wordfence'), $serverInfo->isIIS(), wfWAFAutoPrependHelper::helper('iis')->getFilesNeededForBackup()),
|
||||
);
|
||||
|
||||
$hasRecommendedOption = false;
|
||||
$wafPrependOptions = '';
|
||||
foreach ($dropdown as $option) {
|
||||
list($optionValue, $optionText, $selected) = $option;
|
||||
$optionValue=esc_attr($optionValue);
|
||||
$optionText=esc_html($optionText);
|
||||
$wafPrependOptions .= "<option value=\"{$optionValue}\"" . ($selected ? ' selected' : '') . ">{$optionText}" . ($selected ? ' (recommended based on our tests)' : '') . "</option>\n";
|
||||
if ($selected) {
|
||||
$hasRecommendedOption = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$hasRecommendedOption): ?>
|
||||
<p><?php esc_html_e('If you know your web server\'s configuration, please select it from the list below.', 'wordfence'); ?></p>
|
||||
<?php else: ?>
|
||||
<p><?php esc_html_e('We\'ve preselected your server configuration based on our tests, but if you know your web server\'s configuration, please select it now.', 'wordfence'); ?></p>
|
||||
<?php endif; ?>
|
||||
<select name='serverConfiguration' id='wf-waf-server-config'>
|
||||
<?php echo $wafPrependOptions; ?>
|
||||
</select>
|
||||
<?php
|
||||
$adminURL = network_admin_url('admin.php?page=WordfenceWAF&subpage=waf_options&action=removeAutoPrepend');
|
||||
$wfnonce = wp_create_nonce('wfWAFRemoveAutoPrepend');
|
||||
foreach ($dropdown as $option):
|
||||
list($optionValue, $optionText, $selected) = $option;
|
||||
$class = preg_replace('/[^a-z0-9\-]/i', '', $optionValue);
|
||||
$helper = new wfWAFAutoPrependHelper($optionValue, null);
|
||||
$backups = $helper->getFilesNeededForBackup();
|
||||
$filteredBackups = array();
|
||||
foreach ($backups as $index => $backup) {
|
||||
if (!file_exists($backup)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$filteredBackups[$index] = $backup;
|
||||
}
|
||||
$jsonBackups = json_encode(array_map('basename', $filteredBackups));
|
||||
?>
|
||||
<div class="wf-waf-backups wf-waf-backups-<?php echo $class; ?>" style="display: none;" data-backups="<?php echo esc_attr($jsonBackups); ?>">
|
||||
<?php if (count($filteredBackups)): ?><p><?php esc_html_e('Please download a backup of the following files before we make the necessary changes:', 'wordfence'); ?></p><?php endif; ?>
|
||||
<ul class="wf-waf-backup-file-list">
|
||||
<?php
|
||||
foreach ($filteredBackups as $index => $backup) {
|
||||
echo '<li><a class="wf-btn wf-btn-default wf-waf-backup-download" data-backup-index="' . $index . '" href="' .
|
||||
esc_url(add_query_arg(array(
|
||||
'downloadBackup' => 1,
|
||||
'backupIndex' => $index,
|
||||
'serverConfiguration' => $helper->getServerConfig(),
|
||||
'wfnonce' => $wfnonce,
|
||||
), $adminURL)) . '">' . esc_html(sprintf(__('Download %s', 'wordfence'), basename($backup))) . '</a></li>';
|
||||
}
|
||||
?>
|
||||
</ul>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<div class="wf-modal-footer">
|
||||
<ul class="wf-flex-horizontal wf-flex-full-width">
|
||||
<li class="wf-waf-download-instructions"><?php esc_html_e('Once you have downloaded the files, click Continue to complete uninstallation.', 'wordfence'); ?></li>
|
||||
<li class="wf-right"><a href="#" class="wf-btn wf-btn-primary wf-btn-callout-subtle wf-disabled" id="wf-waf-uninstall-continue" role="button"><?php esc_html_e('Continue', 'wordfence'); ?></a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</script>
|
||||
Reference in New Issue
Block a user