From a8cccfce62a5433a7c310ef50ad641db41b4bfe4 Mon Sep 17 00:00:00 2001 From: Alex Pott Date: Wed, 21 Jan 2015 10:03:23 +0000 Subject: [PATCH] Revert "Issue #2221699 by mpdonadio, mikey_p, kim.pepper, arlinsandbulte: HTTP_HOST header cannot be trusted" This reverts commit 2c9eddf3ac07969341afaa144b7b3f9bd06cc0c4. --- core/lib/Drupal/Core/DrupalKernel.php | 54 ------------- .../Core/Installer/Form/SiteSettingsForm.php | 7 -- .../system/src/PathBasedBreadcrumbBuilder.php | 13 ++-- .../src/Tests/System/TrustedHostsTest.php | 62 --------------- core/modules/system/system.install | 22 ------ .../PathBasedBreadcrumbBuilderTest.php | 4 +- core/modules/views_ui/src/ViewUI.php | 5 +- .../DrupalKernelTrustedHostsTest.php | 78 ------------------- index.php | 2 +- sites/default/default.settings.php | 37 --------- sites/example.settings.local.php | 12 --- 11 files changed, 12 insertions(+), 284 deletions(-) delete mode 100644 core/modules/system/src/Tests/System/TrustedHostsTest.php delete mode 100644 core/tests/Drupal/Tests/Core/DrupalKernel/DrupalKernelTrustedHostsTest.php diff --git a/core/lib/Drupal/Core/DrupalKernel.php b/core/lib/Drupal/Core/DrupalKernel.php index 67ac3b411d1..69717181c31 100644 --- a/core/lib/Drupal/Core/DrupalKernel.php +++ b/core/lib/Drupal/Core/DrupalKernel.php @@ -201,9 +201,6 @@ class DrupalKernel implements DrupalKernelInterface, TerminableInterface { * from disk. Defaults to TRUE. * * @return static - * - * @throws \Symfony\Component\HttpKernel\Exception\BadRequestHttpException - * In case the host name in the request is not trusted. */ public static function createFromRequest(Request $request, $class_loader, $environment, $allow_dumping = TRUE) { // Include our bootstrap file. @@ -220,15 +217,6 @@ class DrupalKernel implements DrupalKernelInterface, TerminableInterface { $kernel->setSitePath($site_path); Settings::initialize(dirname($core_root), $site_path, $class_loader); - // Initialize our list of trusted HTTP Host headers to protect against - // header attacks. - $hostPatterns = Settings::get('trusted_host_patterns', array()); - if (PHP_SAPI !== 'cli' && !empty($hostPatterns)) { - if (static::setupTrustedHosts($request, $hostPatterns) === FALSE) { - throw new BadRequestHttpException('The provided host name is not valid for this server.'); - } - } - // Redirect the user to the installation script if Drupal has not been // installed yet (i.e., if no $databases array has been defined in the // settings.php file) and we are not already installing. @@ -1266,46 +1254,4 @@ class DrupalKernel implements DrupalKernelInterface, TerminableInterface { return TRUE; } - /** - * Sets up the lists of trusted HTTP Host headers. - * - * Since the HTTP Host header can be set by the user making the request, it - * is possible to create an attack vectors against a site by overriding this. - * Symfony provides a mechanism for creating a list of trusted Host values. - * - * Host patterns (as regular expressions) can be configured throught - * settings.php for multisite installations, sites using ServerAlias without - * canonical redirection, or configurations where the site responds to default - * requests. For example, - * - * @code - * $settings['trusted_host_patterns'] = array( - * '^example\.com$', - * '^*.example\.com$', - * ); - * @endcode - * - * @param \Symfony\Component\HttpFoundation\Request $request - * The request object. - * @param array $hostPatterns - * The array of trusted host patterns. - * - * @return boolean - * TRUE if the Host header is trusted, FALSE otherwise. - * - * @see https://www.drupal.org/node/1992030 - */ - protected static function setupTrustedHosts(Request $request, $hostPatterns) { - $request->setTrustedHosts($hostPatterns); - - // Get the host, which will validate the current request. - try { - $request->getHost(); - } - catch (\UnexpectedValueException $e) { - return FALSE; - } - - return TRUE; - } } diff --git a/core/lib/Drupal/Core/Installer/Form/SiteSettingsForm.php b/core/lib/Drupal/Core/Installer/Form/SiteSettingsForm.php index 6feaa457c1d..8cf65c9c6ce 100644 --- a/core/lib/Drupal/Core/Installer/Form/SiteSettingsForm.php +++ b/core/lib/Drupal/Core/Installer/Form/SiteSettingsForm.php @@ -155,13 +155,6 @@ class SiteSettingsForm extends FormBase { 'value' => $install_state['parameters']['profile'], 'required' => TRUE, ); - // Set the initial trusted host value if this isn't a command line install. - if (PHP_SAPI !== 'cli') { - $settings['settings']['trusted_host_patterns'] = (object) array( - 'value' => array('^' . preg_quote(\Drupal::request()->getHost()) . '$'), - 'required' => TRUE, - ); - } drupal_rewrite_settings($settings); diff --git a/core/modules/system/src/PathBasedBreadcrumbBuilder.php b/core/modules/system/src/PathBasedBreadcrumbBuilder.php index 6080d6b8f2a..05693312e10 100644 --- a/core/modules/system/src/PathBasedBreadcrumbBuilder.php +++ b/core/modules/system/src/PathBasedBreadcrumbBuilder.php @@ -7,7 +7,6 @@ namespace Drupal\system; -use Drupal\Component\Utility\Unicode; use Drupal\Core\Access\AccessManagerInterface; use Drupal\Core\Breadcrumb\BreadcrumbBuilderInterface; use Drupal\Core\Config\ConfigFactoryInterface; @@ -15,17 +14,19 @@ use Drupal\Core\Controller\TitleResolverInterface; use Drupal\Core\Link; use Drupal\Core\ParamConverter\ParamNotConvertedException; use Drupal\Core\PathProcessor\InboundPathProcessorInterface; -use Drupal\Core\Routing\RequestContext; use Drupal\Core\Routing\RouteMatch; use Drupal\Core\Routing\RouteMatchInterface; use Drupal\Core\Session\AccountInterface; use Drupal\Core\StringTranslation\StringTranslationTrait; +use Drupal\Component\Utility\Unicode; use Drupal\Core\Url; use Symfony\Component\HttpFoundation\Request; +use Symfony\Cmf\Component\Routing\RouteObjectInterface; use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException; +use Symfony\Component\Routing\Matcher\RequestMatcherInterface; +use Symfony\Component\Routing\RequestContext; use Symfony\Component\Routing\Exception\MethodNotAllowedException; use Symfony\Component\Routing\Exception\ResourceNotFoundException; -use Symfony\Component\Routing\Matcher\RequestMatcherInterface; /** * Class to define the menu_link breadcrumb builder. @@ -36,7 +37,7 @@ class PathBasedBreadcrumbBuilder implements BreadcrumbBuilderInterface { /** * The router request context. * - * @var \Drupal\Core\Routing\RequestContext + * @var \Symfony\Component\Routing\RequestContext */ protected $context; @@ -85,7 +86,7 @@ class PathBasedBreadcrumbBuilder implements BreadcrumbBuilderInterface { /** * Constructs the PathBasedBreadcrumbBuilder. * - * @param \Drupal\Core\Routing\RequestContext $context + * @param \Symfony\Component\Routing\RequestContext $context * The router request context. * @param \Drupal\Core\Access\AccessManagerInterface $access_manager * The menu link access service. @@ -181,7 +182,7 @@ class PathBasedBreadcrumbBuilder implements BreadcrumbBuilderInterface { } // @todo Use the RequestHelper once https://drupal.org/node/2090293 is // fixed. - $request = Request::create($this->context->getCompleteBaseUrl() . '/' . $path); + $request = Request::create($this->context->getBaseUrl() . '/' . $path); // Performance optimization: set a short accept header to reduce overhead in // AcceptHeaderMatcher when matching the request. $request->headers->set('Accept', 'text/html'); diff --git a/core/modules/system/src/Tests/System/TrustedHostsTest.php b/core/modules/system/src/Tests/System/TrustedHostsTest.php deleted file mode 100644 index 2be2c8b70fe..00000000000 --- a/core/modules/system/src/Tests/System/TrustedHostsTest.php +++ /dev/null @@ -1,62 +0,0 @@ -drupalCreateUser(array( - 'administer site configuration', - )); - $this->drupalLogin($admin_user); - } - - /** - * Tests that the status page shows an error when the trusted host setting - * is missing from settings.php - */ - public function testStatusPageWithoutConfiguration() { - $this->drupalGet('admin/reports/status'); - $this->assertResponse(200, 'The status page is reachable.'); - - $this->assertRaw(t('Trusted Host Settings')); - $this->assertRaw(t('The trusted_host_patterns setting is not configured in settings.php.')); - } - - /** - * Tests that the status page shows the trusted patterns from settings.php. - */ - public function testStatusPageWithConfiguration() { - $settings['settings']['trusted_host_patterns'] = (object) array( - 'value' => array('^' . preg_quote(\Drupal::request()->getHost()) . '$'), - 'required' => TRUE, - ); - - $this->writeSettings($settings); - - $this->drupalGet('admin/reports/status'); - $this->assertResponse(200, 'The status page is reachable.'); - - $this->assertRaw(t('Trusted Host Settings')); - $this->assertRaw(t('The trusted_host_patterns setting is set to allow')); - } - -} diff --git a/core/modules/system/system.install b/core/modules/system/system.install index 4a8683eaae8..08e7865983f 100644 --- a/core/modules/system/system.install +++ b/core/modules/system/system.install @@ -611,28 +611,6 @@ function system_requirements($phase) { ); } } - - // See if trusted hostnames have been configured, and warn the user if they - // are not set. - if ($phase == 'runtime') { - $trusted_host_patterns = Settings::get('trusted_host_patterns'); - if (empty($trusted_host_patterns)) { - $requirements['trusted_host_patterns'] = array( - 'title' => t('Trusted Host Settings'), - 'value' => t('Not enabled'), - 'description' => t('The trusted_host_patterns setting is not configured in settings.php. This can lead to security vulnerabilities. It is highly recommended that you configure this. See Protecting against HTTP HOST Header attacks for more information.', array('@url' => 'https://www.drupal.org/node/1992030')), - 'severity' => REQUIREMENT_ERROR, - ); - } - else { - $requirements['trusted_host_patterns'] = array( - 'title' => t('Trusted Host Settings'), - 'value' => t('Enabled'), - 'description' => t('The trusted_host_patterns setting is set to allow %trusted_host_patterns', array('%trusted_host_patterns' => join(', ', $trusted_host_patterns))), - ); - } - } - return $requirements; } diff --git a/core/modules/system/tests/src/Unit/Breadcrumbs/PathBasedBreadcrumbBuilderTest.php b/core/modules/system/tests/src/Unit/Breadcrumbs/PathBasedBreadcrumbBuilderTest.php index fb530299c40..7daf8c2fa9c 100644 --- a/core/modules/system/tests/src/Unit/Breadcrumbs/PathBasedBreadcrumbBuilderTest.php +++ b/core/modules/system/tests/src/Unit/Breadcrumbs/PathBasedBreadcrumbBuilderTest.php @@ -58,7 +58,7 @@ class PathBasedBreadcrumbBuilderTest extends UnitTestCase { /** * The mocked route request context. * - * @var \Drupal\Core\Routing\RequestContext|\PHPUnit_Framework_MockObject_MockObject + * @var \Symfony\Component\Routing\RequestContext|\PHPUnit_Framework_MockObject_MockObject */ protected $context; @@ -89,7 +89,7 @@ class PathBasedBreadcrumbBuilderTest extends UnitTestCase { $config_factory = $this->getConfigFactoryStub(array('system.site' => array('front' => 'test_frontpage'))); $this->pathProcessor = $this->getMock('\Drupal\Core\PathProcessor\InboundPathProcessorInterface'); - $this->context = $this->getMock('\Drupal\Core\Routing\RequestContext'); + $this->context = $this->getMock('\Symfony\Component\Routing\RequestContext'); $this->accessManager = $this->getMock('\Drupal\Core\Access\AccessManagerInterface'); $this->titleResolver = $this->getMock('\Drupal\Core\Controller\TitleResolverInterface'); diff --git a/core/modules/views_ui/src/ViewUI.php b/core/modules/views_ui/src/ViewUI.php index e8464fa31ec..2f3e417d425 100644 --- a/core/modules/views_ui/src/ViewUI.php +++ b/core/modules/views_ui/src/ViewUI.php @@ -611,9 +611,8 @@ class ViewUI implements ViewEntityInterface { // Make view links come back to preview. - // Also override the current path so we get the pager, and make sure the - // Request object gets all of the proper values from $_SERVER. - $request = Request::createFromGlobals(); + // Also override the current path so we get the pager. + $request = new Request(); $request->attributes->set(RouteObjectInterface::ROUTE_NAME, 'entity.view.preview_form'); $request->attributes->set(RouteObjectInterface::ROUTE_OBJECT, \Drupal::service('router.route_provider')->getRouteByName('entity.view.preview_form')); $request->attributes->set('view', $this->storage); diff --git a/core/tests/Drupal/Tests/Core/DrupalKernel/DrupalKernelTrustedHostsTest.php b/core/tests/Drupal/Tests/Core/DrupalKernel/DrupalKernelTrustedHostsTest.php deleted file mode 100644 index 53a030513c5..00000000000 --- a/core/tests/Drupal/Tests/Core/DrupalKernel/DrupalKernelTrustedHostsTest.php +++ /dev/null @@ -1,78 +0,0 @@ - array( - '^example\.com$', - '^.+\.example\.com$', - '^example\.org', - '^.+\.example\.org', - ) - )); - - if (!empty($host)) { - $request->headers->set('HOST', $host); - } - - $request->server->set('SERVER_NAME', $server_name); - - $method = new \ReflectionMethod('Drupal\Core\DrupalKernel', 'setupTrustedHosts'); - $method->setAccessible(TRUE); - $valid_host = $method->invoke(null, $request, $settings->get('trusted_host_patterns', array())); - - $this->assertSame($expected, $valid_host, $message); - } - - /** - * Provides test data for testTrustedHosts(). - */ - public function providerTestTrustedHosts() { - $data = []; - - // Tests canonical URL. - $data[] = ['www.example.com', 'www.example.com', 'canonical URL is trusted', TRUE]; - - // Tests missing hostname for HTTP/1.0 compatability where the Host - // header is optional. - $data[] = [NULL, 'www.example.com', 'empty Host is valid', TRUE]; - - // Tests the additional paterns from the settings. - $data[] = ['example.com', 'www.example.com', 'host from settings is trusted', TRUE]; - $data[] = ['subdomain.example.com', 'www.example.com', 'host from settings is trusted', TRUE]; - $data[] = ['www.example.org', 'www.example.com', 'host from settings is trusted', TRUE]; - $data[] = ['example.org', 'www.example.com', 'host from settings is trusted', TRUE]; - - // Tests mismatch. - $data[] = ['www.blackhat.com', 'www.example.com', 'unspecified host is untrusted', FALSE]; - - return $data; - } - -} diff --git a/index.php b/index.php index 867f0e09215..55fc9474985 100644 --- a/index.php +++ b/index.php @@ -27,7 +27,7 @@ try { $kernel->terminate($request, $response); } catch (HttpExceptionInterface $e) { - $response = new Response($e->getMessage(), $e->getStatusCode()); + $response = new Response('', $e->getStatusCode()); $response->prepare($request)->send(); } catch (Exception $e) { diff --git a/sites/default/default.settings.php b/sites/default/default.settings.php index 7cc10be7260..76d26fcfdf3 100644 --- a/sites/default/default.settings.php +++ b/sites/default/default.settings.php @@ -607,40 +607,3 @@ if ($settings['hash_salt']) { # if (file_exists(__DIR__ . '/settings.local.php')) { # include __DIR__ . '/settings.local.php'; # } - -/** - * Trusted host configuration. - * - * Drupal core can use the Symfony trusted host mechanism to prevent HTTP Host - * header spoofing. - * - * To enable the trusted host mechanism, you enable your allowable hosts - * in $settings['trusted_host_patterns']. This should be an array of regular - * expression patterns, without delimiters, representing the hosts you would - * like to allow. - * - * For example: - * @code - * $settings['trusted_host_patterns'] = array( - * '^www\.example\.com$', - * ); - * @endcode - * will allow the site to only run from www.example.com. - * - * If you are running multisite, or if you are running your site from - * different domain names (eg, you don't redirect http://www.example.com to - * http://example.com), you should specify all of the host patterns that are - * allowed by your site. - * - * For example: - * @code - * $settings['trusted_host_patterns'] = array( - * '^example\.com$', - * '^.+\.example\.com$', - * '^example\.org', - * '^.+\.example\.org', - * ); - * @endcode - * will allow the site to run off of all variants of example.com and - * example.org, with all subdomains included. - */ diff --git a/sites/example.settings.local.php b/sites/example.settings.local.php index 3d5857a306b..7859fe50219 100644 --- a/sites/example.settings.local.php +++ b/sites/example.settings.local.php @@ -55,15 +55,3 @@ $settings['extension_discovery_scan_tests'] = TRUE; * using these parameters in a request to rebuild.php. */ $settings['rebuild_access'] = TRUE; - -/** - * Trust localhost. - * - * This will configure several common hostnames used for local development to - * be trusted hosts. - */ -$settings['trusted_host_patterns'] = array( - '^localhost$', - '^localhost\.*', - '\.local$', -);