diff -u b/core/lib/Drupal/Core/DrupalKernel.php b/core/lib/Drupal/Core/DrupalKernel.php --- b/core/lib/Drupal/Core/DrupalKernel.php +++ b/core/lib/Drupal/Core/DrupalKernel.php @@ -29,6 +29,7 @@ use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\RequestStack; use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; use Symfony\Component\HttpKernel\TerminableInterface; use Composer\Autoload\ClassLoader; @@ -202,8 +203,12 @@ $kernel = new static($environment, $class_loader, $allow_dumping); - // Ensure sane php environment variables.. - static::bootEnvironment(); + try { + // Ensure sane php environment variables.. + static::bootEnvironment($request); + } catch (\UnexpectedValueException $exception) { + throw new BadRequestHttpException('Bad Request'); + } // Get our most basic settings setup. $kernel->initializeSettings($request); @@ -315,9 +320,6 @@ $script_name = $request->server->get('SCRIPT_FILENAME'); } $http_host = $request->getHost(); - if (self::validateHostnameLength($http_host) == FALSE) { - throw new \UnexpectedValueException('Bad hostname'); - } $sites = array(); include DRUPAL_ROOT . '/sites/sites.php'; @@ -725,12 +727,19 @@ * * This method sets PHP environment options we want to be sure are set * correctly for security or just saneness. + * + * @throws UnexpectedValueException */ - public static function bootEnvironment() { + public static function bootEnvironment(Request $request) { if (static::$isEnvironmentInitialized) { return; } + $http_host = $request->getHost(); + if (self::validateHostnameLength($http_host) == FALSE) { + throw new \UnexpectedValueException('Bad hostname'); + } + // Enforce E_STRICT, but allow users to set levels not part of E_STRICT. error_reporting(E_STRICT | E_ALL); @@ -894,6 +903,8 @@ // Replace "core" out of session_name so core scripts redirect properly, // specifically install.php. $session_name = preg_replace('/\/core$/', '', $session_name); + // HTTP_HOST can be modified by a visitor, but has been sanitized already + // in DrupalKernel::bootEnvironment(). if ($cookie_domain = $request->getHost()) { // Strip leading periods, www., and port numbers from cookie domain. $cookie_domain = ltrim($cookie_domain, '.'); only in patch2: unchanged: --- a/core/core.services.yml +++ b/core/core.services.yml @@ -798,6 +798,11 @@ services: tags: - { name: event_subscriber } arguments: ['@config.factory', '@http_kernel'] + exception.bad_request: + class: Drupal\Core\EventSubscriber\BadRequestHttpExceptionSubscriber + tags: + - { name: event_subscriber } + arguments: ['@config.factory', '@http_kernel'] exception.test_site: class: Drupal\Core\EventSubscriber\ExceptionTestSiteSubscriber tags: only in patch2: unchanged: --- /dev/null +++ b/core/lib/Drupal/Core/EventSubscriber/BadRequestHttpExceptionSubscriber.php @@ -0,0 +1,79 @@ +configFactory = $config_factory; + $this->httpKernel = $http_kernel; + } + + + /** + * {@inheritdoc} + */ + protected static function getPriority() { + // A very high priority so that it can take precedent over anything else, + // and thus be fast. + return 1000; + } + + /** + * {@inheritDoc} + */ + protected function getHandledFormats() { + return ['html']; + } + + /** + * Handles a 400 error for HTML. + * + * @param \Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent $event + * The event to process. + */ + public function on400(GetResponseForExceptionEvent $event) { + $response = new Response('Bad Request', Response::HTTP_BAD_REQUEST); + $event->setResponse($response); + } + +}