diff --git a/.htaccess b/.htaccess
index 5248bd85d61936b9f090993f396af1c31acbd3b5..7db5d3e5786887f4a4e1b28dba245dbe346d5e09 100644
--- a/.htaccess
+++ b/.htaccess
@@ -165,3 +165,9 @@ DirectoryIndex index.php index.html index.htm
     </FilesMatch>
   </IfModule>
 </IfModule>
+
+# Add headers to all responses.
+<IfModule mod_headers.c>
+  # Disable content sniffing, since it's an attack vector.
+  Header always set X-Content-Type-Options nosniff
+</IfModule>
diff --git a/core/lib/Drupal/Core/EventSubscriber/FinishResponseSubscriber.php b/core/lib/Drupal/Core/EventSubscriber/FinishResponseSubscriber.php
index fb68b07a04252d57b07ac7f63eeb79fc28c2f626..963795ed5185d02a26faf17545b3f8e60d202a82 100644
--- a/core/lib/Drupal/Core/EventSubscriber/FinishResponseSubscriber.php
+++ b/core/lib/Drupal/Core/EventSubscriber/FinishResponseSubscriber.php
@@ -96,6 +96,12 @@ public function onRespond(FilterResponseEvent $event) {
     // Set the Content-language header.
     $response->headers->set('Content-language', $this->languageManager->getCurrentLanguage()->getId());
 
+    // Prevent browsers from sniffing a response and picking a MIME type
+    // different from the declared content-type, since that can lead to
+    // XSS and other vulnerabilities.
+    // https://www.owasp.org/index.php/List_of_useful_HTTP_headers
+    $response->headers->set('X-Content-Type-Options', 'nosniff', FALSE);
+
     // Attach globally-declared headers to the response object so that Symfony
     // can send them for us correctly.
     // @todo Remove this once drupal_process_attached() no longer calls
diff --git a/core/modules/system/src/Tests/Routing/RouterTest.php b/core/modules/system/src/Tests/Routing/RouterTest.php
index 5651768a6d006f21f7d370155ac278cd15955eb2..e3287595e539db68eacc12e56b85f088407af093 100644
--- a/core/modules/system/src/Tests/Routing/RouterTest.php
+++ b/core/modules/system/src/Tests/Routing/RouterTest.php
@@ -25,17 +25,19 @@ class RouterTest extends WebTestBase {
   public static $modules = array('block', 'router_test');
 
   /**
-   * Confirms that the router can get to a controller.
+   * Confirms that our default controller logic works properly.
    */
-  public function testCanRoute() {
+  public function testDefaultController() {
+    // Confirm that the router can get to a controller.
     $this->drupalGet('router_test/test1');
     $this->assertRaw('test1', 'The correct string was returned because the route was successful.');
-  }
 
-  /**
-   * Confirms that our default controller logic works properly.
-   */
-  public function testDefaultController() {
+    // Check expected headers from FinishResponseSubscriber
+    $headers = $this->drupalGetHeaders();
+    $this->assertEqual($headers['x-ua-compatible'], 'IE=edge,chrome=1');
+    $this->assertEqual($headers['content-language'], 'en');
+    $this->assertEqual($headers['x-content-type-options'], 'nosniff');
+
     $this->drupalGet('router_test/test2');
     $this->assertRaw('test2', 'The correct string was returned because the route was successful.');