diff --git a/core/lib/Drupal/Core/DrupalKernel.php b/core/lib/Drupal/Core/DrupalKernel.php
index 600fd21..6463090 100644
--- a/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;
 
@@ -293,12 +294,18 @@ public function __construct($environment, $class_loader, $allow_dumping = TRUE)
    * @return string
    *   The path of the matching directory.
    *
+   * @throws BadRequestHttpException
+   *
    * @see \Drupal\Core\DrupalKernelInterface::getSitePath()
    * @see \Drupal\Core\DrupalKernelInterface::setSitePath()
    * @see default.settings.php
    * @see example.sites.php
    */
   public static function findSitePath(Request $request, $require_settings = TRUE) {
+    if (self::validateHostname($request) !== TRUE) {
+      throw new BadRequestHttpException('Bad hostname');
+    }
+
     // Check for a simpletest override.
     if ($test_prefix = drupal_valid_test_ua()) {
       return 'sites/simpletest/' . substr($test_prefix, 10);
@@ -314,7 +321,7 @@ public static function findSitePath(Request $request, $require_settings = TRUE)
     if (!$script_name) {
       $script_name = $request->server->get('SCRIPT_FILENAME');
     }
-    $http_host = $request->server->get('HTTP_HOST');
+    $http_host = $request->getHost();
 
     $sites = array();
     include DRUPAL_ROOT . '/sites/sites.php';
@@ -809,8 +816,7 @@ protected function initializeRequestGlobals(Request $request) {
     }
     else {
       // Create base URL.
-      $http_protocol = $request->isSecure() ? 'https' : 'http';
-      $base_root = $http_protocol . '://' . $request->server->get('HTTP_HOST');
+      $base_root = $request->getSchemeAndHttpHost();
 
       $base_url = $base_root;
 
@@ -892,16 +898,14 @@ protected function initializeCookieGlobals(Request $request) {
       // 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->server->get('HTTP_HOST')) {
-        // Strip leading periods, www., and port numbers from cookie domain.
+      if ($cookie_domain = $request->getHost()) {
+        // Strip leading periods and www. from cookie domain.
         $cookie_domain = ltrim($cookie_domain, '.');
         if (strpos($cookie_domain, 'www.') === 0) {
           $cookie_domain = substr($cookie_domain, 4);
         }
-        $cookie_domain = explode(':', $cookie_domain);
-        $cookie_domain = '.' . $cookie_domain[0];
+        // Restore one leading period per RFC 2109
+        $cookie_domain = '.' . $cookie_domain;
       }
     }
     // Per RFC 2109, cookie domains must contain at least one dot other than the
@@ -1249,4 +1253,50 @@ protected function classLoaderAddMultiplePsr4(array $namespaces = array()) {
     }
   }
 
+  /**
+   * Validates a hostname length.
+   *
+   * @param string $host
+   *   A hostname.
+   *
+   * @return bool
+   *   TRUE if the length is appropriate, or FALSE otherwise.
+   */
+  protected static function validateHostnameLength($host) {
+    // Limit the length of the host name to 1000 bytes to prevent DoS attacks
+    // with long host names.
+    return strlen($host) <= 1000
+    // Limit the number of subdomains and port separators to prevent DoS attacks
+    // in findSitePath().
+    && substr_count($host, '.') <= 100
+    && substr_count($host, ':') <= 100;
+  }
+
+  /**
+   * Validates the hostname supplied from the HTTP request.
+   *
+   * @param Request $request
+   *   The request object
+   *
+   * @return bool
+   *   TRUE if the hostmame is valid, or FALSE otherwise.
+   *
+   * @todo Adjust per resolution to https://github.com/symfony/symfony/issues/12349
+   */
+  public static function validateHostname(Request $request) {
+    // $request->getHost() can also throw an UnexpectedValueException if it
+    // detects a bad hostname, but it does not validate the length.
+    try {
+      $http_host = $request->getHost();
+      if (self::validateHostnameLength($http_host) == FALSE) {
+        throw new \UnexpectedValueException('Bad hostname');
+      }
+    }
+    catch (\UnexpectedValueException $e) {
+      return FALSE;
+    }
+
+    return TRUE;
+  }
+
 }
diff --git a/core/modules/system/src/Tests/DrupalKernel/DrupalKernelTest.php b/core/modules/system/src/Tests/DrupalKernel/DrupalKernelTest.php
index 3c43f18..5182316 100644
--- a/core/modules/system/src/Tests/DrupalKernel/DrupalKernelTest.php
+++ b/core/modules/system/src/Tests/DrupalKernel/DrupalKernelTest.php
@@ -9,6 +9,7 @@
 
 use Drupal\Core\DrupalKernel;
 use Drupal\Core\Site\Settings;
+use Drupal\Core\Test\TestKernel;
 use Drupal\simpletest\KernelTestBase;
 use Symfony\Component\HttpFoundation\Request;
 
@@ -153,4 +154,44 @@ public function testCompileDIC() {
     ));
   }
 
+  /**
+   * Tests hostname validate.
+   */
+  public function testValidateHostame() {
+    // save off the server array
+    $server = $_SERVER;
+
+    $_SERVER['HTTP_HOST'] = 'www.example.com';
+    $request = Request::createFromGlobals();
+    $ok = DrupalKernel::validateHostname($request);
+    $this->assertTrue($ok, 'An valid, overridden hostname validates');
+
+    $_SERVER['HTTP_HOST'] = 'a bad hostmame';
+    $request = Request::createFromGlobals();
+    $ok = DrupalKernel::validateHostname($request);
+    $this->assertFalse($ok, 'An invalid, overridden hostname fails validation');
+
+    $_SERVER['HTTP_HOST'] = str_repeat('a', 2000);
+    $request = Request::createFromGlobals();
+    $ok = DrupalKernel::validateHostname($request);
+    $this->assertFalse($ok, 'An superlong, overridden hostname fails validation');
+
+    $_SERVER['HTTP_HOST'] = 'a' . str_repeat('.a', 110);
+    $request = Request::createFromGlobals();
+    $ok = DrupalKernel::validateHostname($request);
+    $this->assertFalse($ok, 'An hostname with too many dots fails validation');
+
+    $_SERVER['HTTP_HOST'] = 'a' . str_repeat(':a', 110);
+    $request = Request::createFromGlobals();
+    $ok = DrupalKernel::validateHostname($request);
+    $this->assertFalse($ok, 'An hostname with too many colons fails validation');
+
+    // restore the global server
+    $_SERVER = $server;
+
+    $request = Request::createFromGlobals();
+    $ok = DrupalKernel::validateHostname($request);
+    $this->assertTrue($ok, 'Normal hostname validates');
+  }
+
 }
diff --git a/core/rebuild.php b/core/rebuild.php
index c915aff..1b18c4a 100644
--- a/core/rebuild.php
+++ b/core/rebuild.php
@@ -14,6 +14,7 @@
 use Drupal\Core\DrupalKernel;
 use Drupal\Core\Site\Settings;
 use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpFoundation\Response;
 
 // Change the directory to the Drupal root.
 chdir('..');
@@ -25,7 +26,16 @@
 // Manually resemble early bootstrap of DrupalKernel::boot().
 require_once __DIR__ . '/includes/bootstrap.inc';
 DrupalKernel::bootEnvironment();
-Settings::initialize(DrupalKernel::findSitePath($request), $autoloader);
+
+try {
+  Settings::initialize(DrupalKernel::findSitePath($request), $autoloader);
+}
+catch (HttpException $e) {
+  $code = $e->getStatusCode();
+  http_response_code($code);
+  print Response::$statusTexts[$code];
+  exit;
+}
 
 if (Settings::get('rebuild_access', FALSE) ||
   ($request->get('token') && $request->get('timestamp') &&
diff --git a/index.php b/index.php
index 406d3dc..e54cec2 100644
--- a/index.php
+++ b/index.php
@@ -10,7 +10,9 @@
 
 use Drupal\Core\DrupalKernel;
 use Drupal\Core\Site\Settings;
+use Symfony\Component\HttpKernel\Exception\HttpException;
 use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpFoundation\Response;
 
 $autoloader = require_once __DIR__ . '/core/vendor/autoload.php';
 
@@ -24,6 +26,12 @@
       ->prepare($request)->send();
   $kernel->terminate($request, $response);
 }
+catch (HttpException $e) {
+  $code = $e->getStatusCode();
+  $content = Response::$statusTexts[$code];
+  $response = new Response($content, $code);
+  $response->prepare($request)->send();
+}
 catch (Exception $e) {
   $message = 'If you have just changed code (for example deployed a new module or moved an existing one) read <a href="http://drupal.org/documentation/rebuild">http://drupal.org/documentation/rebuild</a>';
   if (Settings::get('rebuild_access', FALSE)) {
