TrustedHosts.php in Security Review 8
File
src/Checks/TrustedHosts.php
View source
<?php
namespace Drupal\security_review\Checks;
use Drupal\Core\Link;
use Drupal\Core\Url;
use Drupal\security_review\Check;
use Drupal\security_review\CheckResult;
use Drupal\security_review\CheckSettings\TrustedHostSettings;
class TrustedHosts extends Check {
public function __construct() {
parent::__construct();
$this->settings = new TrustedHostSettings($this, $this->config);
}
public function getNamespace() {
return 'Security Review';
}
public function getTitle() {
return 'Trusted hosts';
}
public function run() {
$result = CheckResult::FAIL;
$base_url_set = FALSE;
$trusted_host_patterns_set = FALSE;
$findings = [];
$settings_php = $this
->security()
->sitePath() . '/settings.php';
if (!file_exists($settings_php)) {
return $this
->createResult(CheckResult::INFO, [], FALSE);
}
if ($this
->settings()
->get('method', 'token') === 'token') {
$content = file_get_contents($settings_php);
$tokens = token_get_all($content);
$prev_settings_line = -1;
foreach ($tokens as $token) {
if (is_array($token)) {
$line = $token[2];
$is_variable = $token[0] === T_VARIABLE;
$is_string = $token[0] === T_CONSTANT_ENCAPSED_STRING;
$is_settings = $is_variable ? $token[1] == '$settings' : FALSE;
$is_base_url = $token[1] == '$base_url';
$is_thp = trim($token[1], "\"'") == 'trusted_host_patterns';
$is_after_settings = $line == $prev_settings_line;
if ($is_variable && $is_base_url) {
$base_url_set = TRUE;
$result = CheckResult::SUCCESS;
}
if ($is_after_settings && $is_string && $is_thp) {
$trusted_host_patterns_set = TRUE;
$result = CheckResult::SUCCESS;
}
if ($base_url_set && $trusted_host_patterns_set) {
break;
}
if ($is_settings) {
$prev_settings_line = $line;
}
}
}
}
else {
include $settings_php;
$base_url_set = isset($base_url);
$trusted_host_patterns_set = isset($settings['trusted_host_patterns']);
}
if ($result === CheckResult::FAIL) {
global $base_url;
$findings['base_url'] = $base_url;
$findings['settings'] = $settings_php;
$findings['base_url_set'] = $base_url_set;
$findings['trusted_host_patterns_set'] = $trusted_host_patterns_set;
}
return $this
->createResult($result, $findings);
}
public function help() {
$paragraphs = [];
$paragraphs[] = $this
->t('Often Drupal needs to know the URL(s) it is responding from in order to build full links back to itself (e.g. password reset links sent via email). Until you explicitly tell Drupal what full or partial URL(s) it should respond for it must dynamically detect it based on the incoming request, something that can be malicously spoofed in order to trick someone into unknowningly visiting an attacker\'s site (known as a HTTP host header attack).');
return [
'#theme' => 'check_help',
'#title' => $this
->t('Drupal trusted hosts'),
'#paragraphs' => $paragraphs,
];
}
public function evaluate(CheckResult $result) {
global $base_url;
if ($result
->result() !== CheckResult::FAIL) {
return [];
}
$settings_php = $this
->security()
->sitePath() . '/settings.php';
$paragraphs = [];
$paragraphs[] = $this
->t('This site is responding from the URL: :url.', [
':url' => $base_url,
]);
$paragraphs[] = $this
->t('If the site should be available only at that URL it is recommended that you set it as the $base_url variable in the settings.php file at @file.', [
'@file' => $settings_php,
]);
$paragraphs[] = $this
->t('If the site has multiple URLs it can respond from you should whitelist host patterns with trusted_host_patterns in settings.php.');
$paragraphs[] = new Link($this
->t('Read more about HTTP Host Header attacks and setting trusted_host_patterns.'), Url::fromUri('https://www.drupal.org/node/1992030'));
return [
'#theme' => 'check_evaluation',
'#paragraphs' => $paragraphs,
'#items' => [],
];
}
public function getMessage($result_const) {
switch ($result_const) {
case CheckResult::SUCCESS:
return $this
->t('Either $base_url or trusted_host_patterns is set.');
case CheckResult::FAIL:
return $this
->t('Neither $base_url nor trusted_host_patterns is set.');
default:
return $this
->t('Unexpected result.');
}
}
}