Merged in feature/81-dev-dev01 (pull request #5)

auto-patch  81-dev-dev01-2023-12-05T22_45_26

* auto-patch  81-dev-dev01-2023-12-05T22_45_26
This commit is contained in:
Tony Volpe
2023-12-05 23:05:59 +00:00
parent ba16964e7a
commit 725d3043d5
1463 changed files with 142461 additions and 89421 deletions

View File

@@ -234,7 +234,12 @@ if (!isset($sendingDiagnosticEmail)) {
<?php endforeach ?>
<tr>
<td><?php esc_html_e('Trusted Proxies', 'wordfence'); ?></td>
<td><?php echo esc_html(implode(', ', explode("\n", wfConfig::get('howGetIPs_trusted_proxies', '')))); ?></td>
<td><?php $proxies = wfConfig::get('howGetIPs_trusted_proxies', ''); echo esc_html(implode(', ', explode("\n", empty($proxies) ? __('(not set)', 'wordfence') : $proxies))); ?></td>
<td></td>
</tr>
<tr>
<td><?php esc_html_e('Trusted Proxy Preset', 'wordfence'); ?></td>
<td><?php $preset = wfConfig::get('howGetIPs_trusted_proxy_preset'); $presets = wfConfig::getJSON('ipResolutionList', array()); echo esc_html((is_array($presets) && isset($presets[$preset])) ? $presets[$preset]['name'] : __('(not set)', 'wordfence')); ?></td>
<td></td>
</tr>
</tbody>
@@ -524,8 +529,8 @@ if (!isset($sendingDiagnosticEmail)) {
global $wpdb;
$wfdb = new wfDB();
//This must be done this way because MySQL with InnoDB tables does a full regeneration of all metadata if we don't. That takes a long time with a large table count.
$tables = $wfdb->querySelect('SELECT SQL_CALC_FOUND_ROWS TABLE_NAME FROM information_schema.TABLES WHERE TABLE_SCHEMA=DATABASE() ORDER BY TABLE_NAME ASC LIMIT 250');
$total = $wfdb->querySingle('SELECT FOUND_ROWS()');
$tables = $wfdb->querySelect('SELECT TABLE_NAME FROM information_schema.TABLES WHERE TABLE_SCHEMA=DATABASE() ORDER BY TABLE_NAME ASC LIMIT 250');
$total = $wfdb->querySingle('SELECT COUNT(*) FROM information_schema.TABLES WHERE TABLE_SCHEMA=DATABASE()');
foreach ($tables as &$t) {
$t = "'" . esc_sql($t['TABLE_NAME']) . "'";
}
@@ -548,7 +553,7 @@ if (!isset($sendingDiagnosticEmail)) {
</div>
<div class="wf-block-content wf-clearfix wf-padding-no-left wf-padding-no-right">
<ul class="wf-block-list wf-padding-add-left-large wf-padding-add-right-large">
<li style="border-bottom: 1px solid #e2e2e2;">
<li>
<div style="width: 75%; min-width: 300px;"><?php esc_html_e('Wordfence Table Check', 'wordfence'); ?></div>
<div class="wf-right">
<?php if ($total > 250): ?>
@@ -590,6 +595,12 @@ if (!isset($sendingDiagnosticEmail)) {
<?php endif; ?>
</div>
</li>
<li style="border-bottom: 1px solid #e2e2e2;">
<div style="width: 75%; min-width: 300px;"><?php esc_html_e('Number of Database Tables', 'wordfence'); ?></div>
<div class="wf-right">
<div class="wf-result-info"><?php echo esc_html( $total ); ?></div>
</div>
</li>
</ul>
<div class="wf-add-top-large" style="max-width: 100%; overflow: auto; padding: 1px;">
<table class="wf-striped-table"<?php echo !empty($inEmail) ? ' border=1' : '' ?>>
@@ -906,4 +917,4 @@ if (!isset($sendingDiagnosticEmail)) {
'secondaryButtons' => array(array('id' => 'wf-restore-defaults-prompt-confirm', 'labelHTML' => wp_kses(/* translators: word order may be reversed as long as HTML remains around "Defaults" */ __('Restore<span class="wf-hidden-xs"> Defaults</span>', 'wordfence'), array('span'=>array('class'=>array()))), 'link' => '#')),
))->render();
?>
</script>
</script>

View File

@@ -567,6 +567,8 @@ class wfCentral {
$scan = array();
}
}
wfScanner::shared()->flushSummaryItems();
$siteID = wfConfig::get('wordfenceCentralSiteID');
$running = wfScanner::shared()->isRunning();

View File

@@ -176,6 +176,7 @@ class wfConfig {
'wafAlertInterval' => array('value' => 600, 'autoload' => self::AUTOLOAD, 'validation' => array('type' => self::TYPE_INT)),
'wafAlertThreshold' => array('value' => 100, 'autoload' => self::AUTOLOAD, 'validation' => array('type' => self::TYPE_INT)),
'howGetIPs_trusted_proxies' => array('value' => '', 'autoload' => self::AUTOLOAD, 'validation' => array('type' => self::TYPE_STRING)),
'howGetIPs_trusted_proxy_preset' => array('value' => '', 'autoload' => self::AUTOLOAD, 'validation' => array('type' => self::TYPE_STRING)),
'scanType' => array('value' => wfScanner::SCAN_TYPE_STANDARD, 'autoload' => self::AUTOLOAD, 'validation' => array('type' => self::TYPE_STRING)),
'manualScanType' => array('value' => wfScanner::MANUAL_SCHEDULING_ONCE_DAILY, 'autoload' => self::AUTOLOAD, 'validation' => array('type' => self::TYPE_STRING)),
'schedStartHour' => array('value' => -1, 'autoload' => self::AUTOLOAD, 'validation' => array('type' => self::TYPE_INT)),
@@ -1309,6 +1310,21 @@ Options -ExecCGI
$checked = true;
break;
}
case 'howGetIPs_trusted_proxy_preset':
{
$presets = wfConfig::getJSON('ipResolutionList', array());
if (!is_array($presets)) {
$presets = array();
}
if (!(empty($value) /* "None" */ || isset($presets[$value]))) {
$errors[] = array('option' => $key, 'error' => __('The selected trusted proxy preset is not valid: ', 'wordfence') . esc_html($value));
}
$checked = true;
break;
}
case 'apiKey':
{
$value = trim($value);
@@ -1830,7 +1846,7 @@ Options -ExecCGI
$api = new wfAPI($apiKey, wfUtils::getWPVersion());
try {
$keyType = wfLicense::KEY_TYPE_FREE;
$keyData = $api->call('ping_api_key', array(), array('supportHash' => wfConfig::get('supportHash', ''), 'whitelistHash' => wfConfig::get('whitelistHash', ''), 'tldlistHash' => wfConfig::get('tldlistHash', '')));
$keyData = $api->call('ping_api_key', array(), array('supportHash' => wfConfig::get('supportHash', ''), 'whitelistHash' => wfConfig::get('whitelistHash', ''), 'tldlistHash' => wfConfig::get('tldlistHash', ''), 'ipResolutionListHash' => wfConfig::get('ipResolutionListHash', '')));
if (isset($keyData['_isPaidKey'])) {
$keyType = wfConfig::get('keyType');
}
@@ -1850,6 +1866,10 @@ Options -ExecCGI
wfConfig::set('tldlist', $keyData['_tldlist']);
wfConfig::set('tldlistHash', $keyData['_tldlistHash']);
}
if (isset($keyData['_ipResolutionList']) && isset($keyData['_ipResolutionListHash'])) {
wfConfig::setJSON('ipResolutionList', $keyData['_ipResolutionList']);
wfConfig::set('ipResolutionListHash', $keyData['_ipResolutionListHash']);
}
if (isset($keyData['scanSchedule']) && is_array($keyData['scanSchedule'])) {
wfConfig::set_ser('noc1ScanSchedule', $keyData['scanSchedule']);
if (wfScanner::shared()->schedulingMode() == wfScanner::SCAN_SCHEDULING_MODE_AUTOMATIC) {
@@ -1910,6 +1930,7 @@ Options -ExecCGI
'email_summary_interval',
'email_summary_excluded_directories',
'howGetIPs_trusted_proxies',
'howGetIPs_trusted_proxy_preset',
'displayTopLevelOptions',
);
break;
@@ -2075,6 +2096,7 @@ Options -ExecCGI
'email_summary_interval',
'email_summary_excluded_directories',
'howGetIPs_trusted_proxies',
'howGetIPs_trusted_proxy_preset',
'firewallEnabled',
'autoBlockScanners',
'loginSecurityEnabled',

View File

@@ -669,13 +669,17 @@ class wfDiagnostic
$detail = '';
if (is_wp_error($result)) {
$message = __('wp_remote_post() test back to this server failed! Response was: ', 'wordfence') . $result->get_error_message();
$messageTextOnly = __('wp_remote_post() test back to this server failed! Response was: ', 'wordfence') . $result->get_error_message();
}
else {
$message = __('wp_remote_post() test back to this server failed! Response was: ', 'wordfence') . '<br>' . $result['response']['code'] . " " . $result['response']['message'] . '<br><br>';
$message = __('wp_remote_post() test back to this server failed! Response was: ', 'wordfence') . '<br>' . $result['response']['code'] . ' ' . $result['response']['message'] . '<br><br>';
$messageTextOnly = __('wp_remote_post() test back to this server failed! Response was: ', 'wordfence') . "\n" . $result['response']['code'] . ' ' . $result['response']['message'] . "\n\n";
if ($this->_detectBlockedByCloudflare($result)) {
$message .= __('Cloudflare appears to be blocking your site from connecting to itself.', 'wordfence') . '<br>' . sprintf(' <a href="%s" target="_blank" rel="noopener noreferrer">', wfSupportController::esc_supportURL(wfSupportController::ITEM_DIAGNOSTICS_CLOUDFLARE_BLOCK)) . __('Get help with Cloudflare compatibility', 'wordfence') . '</a><br><br>';
$messageTextOnly .= __('Cloudflare appears to be blocking your site from connecting to itself.', 'wordfence') . "\n" . __('Get help with Cloudflare compatibility', 'wordfence') . ': ' . wfSupportController::esc_supportURL(wfSupportController::ITEM_DIAGNOSTICS_CLOUDFLARE_BLOCK) . "\n\n";
}
$message .= __('This additional info may help you diagnose the issue. The response headers we received were:', 'wordfence') . '<br><br>';
$messageTextOnly .= __('This additional info may help you diagnose the issue. The response headers we received were:', 'wordfence') . "\n\n";
if (isset($result['http_response']) && is_object($result['http_response']) && method_exists($result['http_response'], 'get_response_object') && is_object($result['http_response']->get_response_object()) && property_exists($result['http_response']->get_response_object(), 'raw')) {
$detail = str_replace("\r\n", "\n", $result['http_response']->get_response_object()->raw);
}
@@ -685,7 +689,7 @@ class wfDiagnostic
return array(
'test' => false,
'message' => array('escaped' => $message),
'message' => array('escaped' => $message, 'textonly' => $messageTextOnly),
'detail' => $detail,
);
}
@@ -705,12 +709,13 @@ class wfDiagnostic
if ($errorNumber === 6 /* COULDNT_RESOLVE_HOST */) {
$detail = sprintf(/* translators: error message from failed request */ __('This likely indicates that the server either does not support IPv6 or does not have an IPv6 address assigned or associated with the domain. Original error message: %s', 'wordfence'), is_array($result['message']) ? $result['message']['escaped'] : $result['message']);
$detail = wp_kses($detail, array('a' => array('href' => array(), 'target' => array(), 'rel' => array()), 'span' => array('class' => array()), 'em' => array(), 'code' => array(), 'br' => array()));
$detailTextOnly = sprintf(/* translators: error message from failed request */ __('This likely indicates that the server either does not support IPv6 or does not have an IPv6 address assigned or associated with the domain. Original error message: %s', 'wordfence'), is_array($result['message']) ? $result['message']['textonly'] : strip_tags($result['message']));
return array(
'test' => false,
'infoOnly' => true,
'message' => __('IPv6 DNS resolution failed', 'wordfence'),
'detail' => array('escaped' => $detail),
'detail' => array('escaped' => $detail, 'textonly' => $detailTextOnly),
);
}
}

View File

@@ -120,8 +120,8 @@ class wfScanMonitor {
}
public static function registerActions() {
add_filter('cron_schedules', array(get_class(), 'registerCronInterval'));
add_action(self::CRON_HOOK, array(get_class(), 'monitorScan'));
add_filter('cron_schedules', array(self::class, 'registerCronInterval'));
add_action(self::CRON_HOOK, array(self::class, 'monitorScan'));
}
public static function handleDeactivation() {

View File

@@ -886,7 +886,7 @@ class wfUtils {
}
$skipToNext = false;
if ($trustedProxies === null) {
$trustedProxies = explode("\n", wfConfig::get('howGetIPs_trusted_proxies', ''));
$trustedProxies = self::unifiedTrustedProxies();
}
foreach(array(',', ' ', "\t") as $char){
if(strpos($item, $char) !== false){
@@ -944,6 +944,29 @@ class wfUtils {
return false;
}
}
/**
* Returns an array of all trusted proxies, combining both the user-entered ones and those from the selected preset.
*
* @return string[]
*/
public static function unifiedTrustedProxies() {
$trustedProxies = explode("\n", wfConfig::get('howGetIPs_trusted_proxies', ''));
$preset = wfConfig::get('howGetIPs_trusted_proxy_preset');
$presets = wfConfig::getJSON('ipResolutionList', array());
if (is_array($presets) && isset($presets[$preset])) {
$testIPs = array_merge($presets[$preset]['ipv4'], $presets[$preset]['ipv6']);
foreach ($testIPs as $val) {
if (strlen($val) > 0) {
if (wfUtils::isValidIP($val) || wfUtils::isValidCIDRRange($val)) {
$trustedProxies[] = $val;
}
}
}
}
return $trustedProxies;
}
/**
* @param string $ip

View File

@@ -179,7 +179,7 @@ class wordfence {
wfRateLimit::trimData();
wfCentral::checkForUnsentSecurityEvents();
wfVersionCheckController::shared()->checkVersionsAndWarn();
}
private static function keyAlert($msg){
@@ -192,7 +192,7 @@ class wordfence {
$api = new wfAPI($apiKey, wfUtils::getWPVersion());
try {
$keyType = wfLicense::KEY_TYPE_FREE;
$keyData = $api->call('ping_api_key', array(), array('supportHash' => wfConfig::get('supportHash', ''), 'whitelistHash' => wfConfig::get('whitelistHash', ''), 'tldlistHash' => wfConfig::get('tldlistHash', '')));
$keyData = $api->call('ping_api_key', array(), array('supportHash' => wfConfig::get('supportHash', ''), 'whitelistHash' => wfConfig::get('whitelistHash', ''), 'tldlistHash' => wfConfig::get('tldlistHash', ''), 'ipResolutionListHash' => wfConfig::get('ipResolutionListHash', '')));
if (isset($keyData['_isPaidKey'])) {
$keyType = wfConfig::get('keyType');
}
@@ -251,6 +251,10 @@ class wordfence {
wfConfig::set('tldlist', $keyData['_tldlist']);
wfConfig::set('tldlistHash', $keyData['_tldlistHash']);
}
if (isset($keyData['_ipResolutionList']) && isset($keyData['_ipResolutionListHash'])) {
wfConfig::setJSON('ipResolutionList', $keyData['_ipResolutionList']);
wfConfig::set('ipResolutionListHash', $keyData['_ipResolutionListHash']);
}
if (isset($keyData['scanSchedule']) && is_array($keyData['scanSchedule'])) {
wfConfig::set_ser('noc1ScanSchedule', $keyData['scanSchedule']);
if (wfScanner::shared()->schedulingMode() == wfScanner::SCAN_SCHEDULING_MODE_AUTOMATIC) {
@@ -2168,6 +2172,7 @@ SQL
}
hash_update($scontext, $data);
}
fclose($sp);
if ($scontext !== false) {
$shash = hash_final($scontext, false);
@@ -2184,6 +2189,7 @@ SQL
}
hash_update($dcontext, $data);
}
fclose($dp);
if ($scontext !== false) {
$dhash = hash_final($dcontext, false);
@@ -2292,7 +2298,7 @@ SQL
'whitelistedIPs' => (string) wfConfig::get('whitelisted'),
'whitelistedServiceIPs' => @json_encode(wfUtils::whitelistedServiceIPs()),
'howGetIPs' => (string) wfConfig::get('howGetIPs'),
'howGetIPs_trusted_proxies' => wfConfig::get('howGetIPs_trusted_proxies', ''),
'howGetIPs_trusted_proxies_unified' => implode("\n", wfUtils::unifiedTrustedProxies()),
'detectProxyRecommendation' => (string) wfConfig::get('detectProxyRecommendation'),
'other_WFNet' => !!wfConfig::get('other_WFNet', true),
'pluginABSPATH' => ABSPATH,
@@ -3232,10 +3238,9 @@ SQL
$threshold = wfConfig::get('lastBruteForceDataSendTime', 0);;
$wfdb = new wfDB();
global $wpdb;
$table_wfHits = wfDB::networkTable('wfHits');
$rawBlocks = $wfdb->querySelect("SELECT SQL_CALC_FOUND_ROWS IP, ctime, actionData FROM {$table_wfHits} WHERE ctime > %f AND action = 'blocked:wfsnrepeat' ORDER BY ctime ASC LIMIT 100", sprintf('%.6f', $threshold));
$totalRows = $wpdb->get_var('SELECT FOUND_ROWS()');
$rawBlocks = $wfdb->querySelect("SELECT IP, ctime, actionData FROM {$table_wfHits} WHERE ctime > %f AND action = 'blocked:wfsnrepeat' ORDER BY ctime ASC LIMIT 100", sprintf('%.6f', $threshold));
$totalRows = $wfdb->querySingle("SELECT COUNT(*) FROM {$table_wfHits} WHERE ctime > %f AND action = 'blocked:wfsnrepeat'", sprintf('%.6f', $threshold));
$ipCounts = array();
$maxctime = 0;
foreach ($rawBlocks as $record) {
@@ -4076,6 +4081,7 @@ SQL
if (isset($_POST['page'])) {
$page = $_POST['page'];
}
$keys = array(wfOnboardingController::TOUR_DASHBOARD, wfOnboardingController::TOUR_FIREWALL, wfOnboardingController::TOUR_SCAN, wfOnboardingController::TOUR_BLOCKING, wfOnboardingController::TOUR_LIVE_TRAFFIC, wfOnboardingController::TOUR_LOGIN_SECURITY);
if (in_array($page, $keys)) {
@@ -4658,9 +4664,22 @@ SQL
}
$trustedProxies = $validIPs;
$preset = $_POST['howGetIPs_trusted_proxy_preset'];
$presets = wfConfig::getJSON('ipResolutionList', array());
if (is_array($presets) && isset($presets[$preset])) {
$testIPs = array_merge($presets[$preset]['ipv4'], $presets[$preset]['ipv6']);
foreach ($testIPs as $val) {
if (strlen($val) > 0) {
if (wfUtils::isValidIP($val) || wfUtils::isValidCIDRRange($val)) {
$trustedProxies[] = $val;
}
}
}
}
$ipAll = wfUtils::getIPPreview($howGet, $trustedProxies);
$ip = wfUtils::getIPForField($howGet, $trustedProxies);
return array('ok' => 1, 'ip' => $ip, 'ipAll' => $ipAll);
return array('ok' => 1, 'ip' => $ip, 'ipAll' => $ipAll, 'resolvedProxies' => $trustedProxies);
}
public static function ajax_hideFileHtaccess_callback(){
@@ -6081,6 +6100,8 @@ HTML;
}
}
if (wfConfig::get('touppBypassNextCheck')) {
wfConfig::set('touppBypassNextCheck', 0);
wfConfig::set('touppPromptNeeded', 0);
@@ -6153,7 +6174,7 @@ HTML;
wp_enqueue_style('wordfence-global-style', wfUtils::getBaseURL() . wfUtils::versionedAsset('css/wf-global.css'), '', WORDFENCE_VERSION);
self::setupAdminVars();
}
if (is_admin()) { //Back end only
if (wfOnboardingController::shouldShowAnyAttempt()) {
wp_enqueue_script('wordfenceOnboardingjs', wfUtils::getBaseURL() . wfUtils::versionedAsset('js/wfonboarding.js'), array('jquery', 'wordfenceAdminExtjs'), WORDFENCE_VERSION);
@@ -8699,13 +8720,25 @@ SQL;
$entry = bin2hex($packed);
}
$wafAlertWhitelist = array_filter($wafAlertWhitelist);
$attackData = $wpdb->get_results($wpdb->prepare("SELECT SQL_CALC_FOUND_ROWS * FROM {$table_wfHits}
WHERE action = 'blocked:waf' " .
(count($wafAlertWhitelist) ? "AND HEX(IP) NOT IN (" . implode(", ", array_fill(0, count($wafAlertWhitelist), '%s')) . ")" : "")
. "AND attackLogTime > %f
ORDER BY attackLogTime DESC
LIMIT 10", array_merge($wafAlertWhitelist, array(sprintf('%.6f', $cutoffTime)))));
$attackCount = $wpdb->get_var('SELECT FOUND_ROWS()');
$attackDataQuery = $wpdb->prepare(
"SELECT * FROM {$table_wfHits}
WHERE action = 'blocked:waf' " .
(count($wafAlertWhitelist) ? "AND HEX(IP) NOT IN (" . implode(", ", array_fill(0, count($wafAlertWhitelist), '%s')) . ")" : "")
. " AND attackLogTime > %f
ORDER BY attackLogTime DESC
LIMIT 10",
array_merge($wafAlertWhitelist, array(sprintf('%.6f', $cutoffTime))));
$attackDataCountQuery = str_replace(
array(
"SELECT * FROM",
"ORDER BY attackLogTime DESC",
"LIMIT 10",
),
array( "SELECT COUNT(*) FROM", "", "" ), $attackDataQuery
);
$attackData = $wpdb->get_results($attackDataQuery);
$attackCount = $wpdb->get_var($attackDataCountQuery);
unset( $attackDataQuery, $attackDataCountQuery );
$threshold = (int) wfConfig::get('wafAlertThreshold');
if ($threshold < 1) {
$threshold = 100;
@@ -8803,21 +8836,38 @@ SQL;
$lastSendTime = wfConfig::get('lastAttackDataSendTime');
$lastSendId = wfConfig::get('lastAttackDataSendId');
if($lastSendId===false){
$query=$wpdb->prepare("SELECT SQL_CALC_FOUND_ROWS * FROM {$table_wfHits}
$query=$wpdb->prepare("SELECT * FROM {$table_wfHits}
WHERE action in ('blocked:waf', 'learned:waf', 'logged:waf', 'blocked:waf-always')
AND attackLogTime > %f
LIMIT %d", sprintf('%.6f', $lastSendTime), $limit);
$count_query = str_replace(
array(
"SELECT * FROM",
"LIMIT " . $limit,
),
array( "SELECT COUNT(*) FROM", "" ), $query
);
}
else{
$query=$wpdb->prepare("SELECT SQL_CALC_FOUND_ROWS * FROM {$table_wfHits}
$query=$wpdb->prepare("SELECT * FROM {$table_wfHits}
WHERE action in ('blocked:waf', 'learned:waf', 'logged:waf', 'blocked:waf-always')
AND id > %d
ORDER BY id LIMIT %d", $lastSendId, $limit);
$count_query = str_replace(
array(
"SELECT * FROM",
"ORDER BY id LIMIT " . $limit,
),
array( "SELECT COUNT(*) FROM", "" ), $query
);
}
$params[]=$limit;
$attackData = $wpdb->get_results($query);
$totalRows = $wpdb->get_var('SELECT FOUND_ROWS()');
$totalRows = $wpdb->get_var($count_query);
if ($attackData) { // Build JSON to send
$dataToSend = array();
$attackDataToUpdate = array();
@@ -10267,4 +10317,4 @@ auto_prepend_file = '%s'
}
class wfWAFAutoPrependHelperException extends Exception {
}
}