bug 1003566 - part 2/2: prevent OCSP requests from being upgraded to HTTPS by HSTS r=cviecco
authorDavid Keeler <dkeeler@mozilla.com>
Wed, 04 Jun 2014 09:58:28 -0700
changeset 205882 5c901d7e88bc651bdcbc9d1427a2ba5342166d7a
parent 205881 d5c4fb8b899585fef26f2d2893a07d7ba7364903
child 205883 e7124b07804b86f825ae2e991832b32cf69ae11c
push id3741
push userasasaki@mozilla.com
push dateMon, 21 Jul 2014 20:25:18 +0000
treeherdermozilla-beta@4d6f46f5af68 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerscviecco
bugs1003566
milestone32.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
bug 1003566 - part 2/2: prevent OCSP requests from being upgraded to HTTPS by HSTS r=cviecco
security/manager/ssl/src/nsNSSCallbacks.cpp
security/manager/ssl/tests/unit/test_ocsp_no_hsts_upgrade.js
security/manager/ssl/tests/unit/xpcshell.ini
--- a/security/manager/ssl/src/nsNSSCallbacks.cpp
+++ b/security/manager/ssl/src/nsNSSCallbacks.cpp
@@ -131,16 +131,19 @@ nsHTTPDownloadEvent::Run()
   if (internalChannel) {
     rv = internalChannel->SetAllowSpdy(false);
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
   nsCOMPtr<nsIHttpChannel> hchan = do_QueryInterface(chan);
   NS_ENSURE_STATE(hchan);
 
+  rv = hchan->SetAllowSTS(false);
+  NS_ENSURE_SUCCESS(rv, rv);
+
   rv = hchan->SetRequestMethod(mRequestSession->mRequestMethod);
   NS_ENSURE_SUCCESS(rv, rv);
 
   mResponsibleForDoneSignal = false;
   mListener->mResponsibleForDoneSignal = true;
 
   mListener->mLoadGroup = lg.get();
   NS_ADDREF(mListener->mLoadGroup);
new file mode 100644
--- /dev/null
+++ b/security/manager/ssl/tests/unit/test_ocsp_no_hsts_upgrade.js
@@ -0,0 +1,62 @@
+// -*- Mode: javascript; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+"use strict";
+
+// Test that if an OCSP request is made to a domain that (erroneously)
+// has HSTS status, the request is not upgraded from HTTP to HTTPS.
+
+function run_test() {
+  do_get_profile();
+  // OCSP required means this test will only pass if the request succeeds.
+  Services.prefs.setBoolPref("security.OCSP.require", true);
+
+  // We don't actually make use of stapling in this test. This is just how we
+  // get a TLS connection.
+  add_tls_server_setup("OCSPStaplingServer");
+
+  let args = [["good", "localhostAndExampleCom", "unused"]];
+  let ocspResponses = generateOCSPResponses(args, "tlsserver");
+  let goodOCSPResponse = ocspResponses[0];
+
+  let ocspResponder = new HttpServer();
+  ocspResponder.registerPrefixHandler("/", function (request, response) {
+    response.setStatusLine(request.httpVersion, 200, "OK");
+    response.setHeader("Content-Type", "application/ocsp-response");
+    response.write(goodOCSPResponse);
+  });
+  ocspResponder.start(8080);
+
+  add_tests_in_mode(true);
+  add_tests_in_mode(false);
+
+  add_test(function () { ocspResponder.stop(run_next_test); });
+
+  let SSService = Cc["@mozilla.org/ssservice;1"]
+                    .getService(Ci.nsISiteSecurityService);
+  let uri = Services.io.newURI("http://localhost", null, null);
+  SSService.processHeader(Ci.nsISiteSecurityService.HEADER_HSTS, uri,
+                          "max-age=10000", 0);
+  do_check_true(SSService.isSecureHost(Ci.nsISiteSecurityService.HEADER_HSTS,
+                                       "localhost", 0));
+
+  run_next_test();
+}
+
+function add_tests_in_mode(useMozillaPKIX) {
+  add_test(function () {
+    Services.prefs.setBoolPref("security.use_mozillapkix_verification",
+                               useMozillaPKIX);
+    run_next_test();
+  });
+
+  // ocsp-stapling-none.example.com does not staple an OCSP response in the
+  // handshake, so the revocation checking code will attempt to fetch one.
+  // Since the domain of the certificate's OCSP AIA URI is an HSTS host
+  // (as added in the setup of this test), a buggy implementation would
+  // upgrade the OCSP request to HTTPS. We specifically prevent this. This
+  // test demonstrates that our implementation is correct in this regard.
+  add_connection_test("ocsp-stapling-none.example.com", Cr.NS_OK);
+  add_test(function () { run_next_test(); });
+}
--- a/security/manager/ssl/tests/unit/xpcshell.ini
+++ b/security/manager/ssl/tests/unit/xpcshell.ini
@@ -81,9 +81,12 @@ skip-if = os == "android"
 [test_ocsp_url.js]
 run-sequentially = hardcoded ports
 # Bug 1009158: this test times out on Android
 skip-if = os == "android"
 [test_ocsp_fetch_method.js]
 run-sequentially = hardcoded ports
 # Bug 1009158: this test times out on Android
 skip-if = os == "android"
-
+[test_ocsp_no_hsts_upgrade.js]
+run-sequentially = hardcoded ports
+# Bug 1009158: this test times out on Android
+skip-if = os == "android"