diff --git a/devtools/client/webconsole/new-console-output/test/mochitest/browser_webconsole_block_mixedcontent_securityerrors.js b/devtools/client/webconsole/new-console-output/test/mochitest/browser_webconsole_block_mixedcontent_securityerrors.js index 0cdcdea0703a..f8846f31f63a 100644 --- a/devtools/client/webconsole/new-console-output/test/mochitest/browser_webconsole_block_mixedcontent_securityerrors.js +++ b/devtools/client/webconsole/new-console-output/test/mochitest/browser_webconsole_block_mixedcontent_securityerrors.js @@ -82,8 +82,6 @@ function pushPrefEnv() { const prefs = [ ["security.mixed_content.block_active_content", true], ["security.mixed_content.block_display_content", true], - ["security.mixed_content.use_hsts", false], - ["security.mixed_content.send_hsts_priming", false], ]; return Promise.all(prefs.map(([pref, value]) => pushPref(pref, value))); diff --git a/devtools/client/webconsole/test/browser_webconsole_block_mixedcontent_securityerrors.js b/devtools/client/webconsole/test/browser_webconsole_block_mixedcontent_securityerrors.js index 22340a6d8ec0..4ce7867173e3 100644 --- a/devtools/client/webconsole/test/browser_webconsole_block_mixedcontent_securityerrors.js +++ b/devtools/client/webconsole/test/browser_webconsole_block_mixedcontent_securityerrors.js @@ -61,8 +61,6 @@ function pushPrefEnv() { "set": [ ["security.mixed_content.block_active_content", true], ["security.mixed_content.block_display_content", true], - ["security.mixed_content.use_hsts", false], - ["security.mixed_content.send_hsts_priming", false], ] }; SpecialPowers.pushPrefEnv(options, deferred.resolve); diff --git a/devtools/client/webconsole/test/browser_webconsole_bug_632817.js b/devtools/client/webconsole/test/browser_webconsole_bug_632817.js index e2e335d74636..b2fffc6e13cf 100644 --- a/devtools/client/webconsole/test/browser_webconsole_bug_632817.js +++ b/devtools/client/webconsole/test/browser_webconsole_bug_632817.js @@ -95,10 +95,6 @@ function testXhrWarn() { let lastRequest = yield waitForFinishedRequest(XHR_WARN_REQUEST_PREDICATE); if (lastRequest.request.method == "HEAD") { - // in non-e10s, we get the HEAD request that priming sends, so make sure - // a priming request should be sent, and then get the actual request - is(Services.prefs.getBoolPref("security.mixed_content.send_hsts_priming"), - true, "Found HSTS Priming Request"); lastRequest = yield waitForFinishedRequest(XHR_WARN_REQUEST_PREDICATE); } diff --git a/docshell/base/nsDocShell.cpp b/docshell/base/nsDocShell.cpp index 8c079d57c6af..fbc7bcb78ecb 100644 --- a/docshell/base/nsDocShell.cpp +++ b/docshell/base/nsDocShell.cpp @@ -9557,27 +9557,6 @@ nsDocShell::InternalLoad(nsIURI* aURI, return NS_ERROR_CONTENT_BLOCKED; } - - // If HSTS priming was set by nsMixedContentBlocker::ShouldLoad, and we - // would block due to mixed content, go ahead and block here. If we try to - // proceed with priming, we will error out later on. - nsCOMPtr docShell = NS_CP_GetDocShellFromContext(requestingContext); - // When loading toplevel windows, requestingContext can be null. We don't - // really care about HSTS in that situation, though; loads in toplevel - // windows should all be browser UI. - if (docShell) { - nsIDocument* document = docShell->GetDocument(); - NS_ENSURE_TRUE(document, NS_OK); - - HSTSPrimingState state = document->GetHSTSPrimingStateForLocation(aURI); - if (state == HSTSPrimingState::eHSTS_PRIMING_BLOCK) { - // HSTS Priming currently disabled for InternalLoad, so we need to clear - // the location that was added by nsMixedContentBlocker::ShouldLoad - // Bug 1269815 will address images loaded via InternalLoad - document->ClearHSTSPrimingLocation(aURI); - return NS_ERROR_CONTENT_BLOCKED; - } - } } nsCOMPtr principalToInherit = aPrincipalToInherit; diff --git a/dom/base/nsIDocument.h b/dom/base/nsIDocument.h index f0a3a32ede08..bcdd226124cf 100644 --- a/dom/base/nsIDocument.h +++ b/dom/base/nsIDocument.h @@ -19,12 +19,12 @@ #include "nsIPresShell.h" #include "nsIScriptGlobalObject.h" // for member (in nsCOMPtr) #include "nsIServiceManager.h" +#include "nsIURI.h" // for use in inline functions #include "nsIUUIDGenerator.h" #include "nsPIDOMWindow.h" // for use in inline functions #include "nsPropertyTable.h" // for member #include "nsStringFwd.h" -#include "nsDataHashtable.h" // for member -#include "nsURIHashKey.h" // for member +#include "nsTHashtable.h" // for member #include "mozilla/net/ReferrerPolicy.h" // for member #include "nsWeakReference.h" #include "mozilla/UseCounter.h" @@ -194,13 +194,6 @@ enum DocumentFlavor { DocumentFlavorPlain, // Just a Document }; -// Enum for HSTS priming states -enum class HSTSPrimingState { - eNO_HSTS_PRIMING = 0, // don't do HSTS Priming - eHSTS_PRIMING_ALLOW = 1, // if HSTS priming fails, allow the load to proceed - eHSTS_PRIMING_BLOCK = 2 // if HSTS priming fails, block the load -}; - // Document states // RTL locale: specific to the XUL localedir attribute @@ -424,34 +417,6 @@ public: mReferrer = aReferrer; } - /** - * Check to see if a subresource we want to load requires HSTS priming - * to be done. - */ - HSTSPrimingState GetHSTSPrimingStateForLocation(nsIURI* aContentLocation) const - { - HSTSPrimingState state; - if (mHSTSPrimingURIList.Get(aContentLocation, &state)) { - return state; - } - return HSTSPrimingState::eNO_HSTS_PRIMING; - } - - /** - * Add a subresource to the HSTS priming list. If this URI is - * not in the HSTS cache, it will trigger an HSTS priming request - * when we try to load it. - */ - void AddHSTSPrimingLocation(nsIURI* aContentLocation, HSTSPrimingState aState) - { - mHSTSPrimingURIList.Put(aContentLocation, aState); - } - - void ClearHSTSPrimingLocation(nsIURI* aContentLocation) - { - mHSTSPrimingURIList.Remove(aContentLocation); - } - /** * Set the principal responsible for this document. Chances are, * you do not want to be using this. @@ -3339,11 +3304,6 @@ protected: bool mUpgradeInsecureRequests; bool mUpgradeInsecurePreloads; - // if nsMixedContentBlocker requires sending an HSTS priming request, - // temporarily store that in the document so that it can be propogated to the - // LoadInfo and eventually the HTTP Channel - nsDataHashtable mHSTSPrimingURIList; - mozilla::WeakPtr mDocumentContainer; NotNull mCharacterSet; diff --git a/dom/base/test/bug704320.sjs b/dom/base/test/bug704320.sjs index dff77f4b3ffd..e0f54953328d 100644 --- a/dom/base/test/bug704320.sjs +++ b/dom/base/test/bug704320.sjs @@ -194,12 +194,6 @@ function createPolicyTest(policy, optionalEarlierPolicy) { } function handleRequest(request, response) { - if (request.method == 'HEAD') { - // respond to a HEAD request with a 418 so that we can easily distinguish - // HSTS priming responses and ignore them - response.setStatusLine('1.1', 418, "I'm a teapot"); - return; - } var sharedKey = 'bug704320.sjs'; var params = request.queryString.split('&'); var action = params[0].split('=')[1]; diff --git a/dom/base/test/referrerHelper.js b/dom/base/test/referrerHelper.js index 207bf5f15f64..01a22829c2d0 100644 --- a/dom/base/test/referrerHelper.js +++ b/dom/base/test/referrerHelper.js @@ -25,9 +25,6 @@ function doXHR(url, onSuccess, onFail) { xhr.onload = function () { if (xhr.status == 200) { onSuccess(xhr); - } else if (xhr.status == 418) { - // Ignore HSTS priming responses - return; } else { onFail(xhr); } diff --git a/dom/html/test/test_anchor_ping.html b/dom/html/test/test_anchor_ping.html index 9b46387fb9a6..5a4936854f47 100644 --- a/dom/html/test/test_anchor_ping.html +++ b/dom/html/test/test_anchor_ping.html @@ -38,15 +38,10 @@ let tests = [ function setup() { Services.prefs.setBoolPref("browser.send_pings", true); Services.prefs.setIntPref("browser.send_pings.max_per_link", -1); - Services.prefs.setBoolPref("security.mixed_content.block_active_content", false); - // The server we create can't handle the priming HEAD requests - Services.prefs.setBoolPref("security.mixed_content.send_hsts_priming", false); SimpleTest.registerCleanupFunction(() => { Services.prefs.clearUserPref("browser.send_pings"); Services.prefs.clearUserPref("browser.send_pings.max_per_link"); - Services.prefs.clearUserPref("security.mixed_content.block_active_content"); - Services.prefs.clearUserPref("security.mixed_content.send_hsts_priming"); }); }, @@ -149,7 +144,7 @@ let tests = [ // The referrer will be loaded using a secure channel. navigate("https://example.com/chrome/dom/html/test/" + - "file_anchor_ping.html?" + "http://localhost:" + + "file_anchor_ping.html?" + "http://127.0.0.1:" + server.identity.primaryPort + ping); // Wait until the ping has been sent. diff --git a/dom/ipc/ContentParent.cpp b/dom/ipc/ContentParent.cpp index 2aaa174e1541..7a6a3d3e8e39 100644 --- a/dom/ipc/ContentParent.cpp +++ b/dom/ipc/ContentParent.cpp @@ -3566,14 +3566,14 @@ ContentParent::RecvIsSecureURI(const uint32_t& aType, } mozilla::ipc::IPCResult -ContentParent::RecvAccumulateMixedContentHSTS(const URIParams& aURI, const bool& aActive, const bool& aHSTSPriming, +ContentParent::RecvAccumulateMixedContentHSTS(const URIParams& aURI, const bool& aActive, const OriginAttributes& aOriginAttributes) { nsCOMPtr ourURI = DeserializeURI(aURI); if (!ourURI) { return IPC_FAIL_NO_REASON(this); } - nsMixedContentBlocker::AccumulateMixedContentHSTS(ourURI, aActive, aHSTSPriming, aOriginAttributes); + nsMixedContentBlocker::AccumulateMixedContentHSTS(ourURI, aActive, aOriginAttributes); return IPC_OK(); } diff --git a/dom/ipc/ContentParent.h b/dom/ipc/ContentParent.h index 8a0540ace879..7ff8a4d98384 100644 --- a/dom/ipc/ContentParent.h +++ b/dom/ipc/ContentParent.h @@ -894,7 +894,6 @@ private: virtual mozilla::ipc::IPCResult RecvAccumulateMixedContentHSTS(const URIParams& aURI, const bool& aActive, - const bool& aHSTSPriming, const OriginAttributes& aOriginAttributes) override; virtual bool DeallocPHalParent(PHalParent*) override; diff --git a/dom/ipc/PContent.ipdl b/dom/ipc/PContent.ipdl index 65b2d5aada7b..433a89e00180 100644 --- a/dom/ipc/PContent.ipdl +++ b/dom/ipc/PContent.ipdl @@ -743,7 +743,7 @@ parent: OriginAttributes aOriginAttributes) returns (bool isSecureURI); - async AccumulateMixedContentHSTS(URIParams aURI, bool aActive, bool aHasHSTSPriming, + async AccumulateMixedContentHSTS(URIParams aURI, bool aActive, OriginAttributes aOriginAttributes); nested(inside_cpow) async PHal(); diff --git a/dom/security/nsContentSecurityManager.cpp b/dom/security/nsContentSecurityManager.cpp index 2322a35bfa60..2d1ec7f57876 100644 --- a/dom/security/nsContentSecurityManager.cpp +++ b/dom/security/nsContentSecurityManager.cpp @@ -15,8 +15,6 @@ #include "nsContentUtils.h" #include "nsCORSListenerProxy.h" #include "nsIStreamListener.h" -#include "nsIDocument.h" -#include "nsMixedContentBlocker.h" #include "nsCDefaultURIFixup.h" #include "nsIURIFixup.h" #include "nsIImageLoadingContent.h" @@ -512,13 +510,6 @@ DoContentSecurityChecks(nsIChannel* aChannel, nsILoadInfo* aLoadInfo) return NS_ERROR_CONTENT_BLOCKED; } - if (nsMixedContentBlocker::sSendHSTSPriming) { - rv = nsMixedContentBlocker::MarkLoadInfoForPriming(uri, - requestingContext, - aLoadInfo); - return rv; - } - return NS_OK; } diff --git a/dom/security/nsMixedContentBlocker.cpp b/dom/security/nsMixedContentBlocker.cpp index 59a3b9300b93..bc76dc7ef950 100644 --- a/dom/security/nsMixedContentBlocker.cpp +++ b/dom/security/nsMixedContentBlocker.cpp @@ -58,40 +58,6 @@ bool nsMixedContentBlocker::sBlockMixedObjectSubrequest = false; // Is mixed display content blocking (images, audio, video, ) enabled? bool nsMixedContentBlocker::sBlockMixedDisplay = false; -// Do we move HSTS before mixed-content -bool nsMixedContentBlocker::sUseHSTS = false; -// Do we send an HSTS priming request -bool nsMixedContentBlocker::sSendHSTSPriming = false; -// Default HSTS Priming failure timeout to 7 days, in seconds -uint32_t nsMixedContentBlocker::sHSTSPrimingCacheTimeout = (60 * 60 * 24 * 7); - -bool -IsEligibleForHSTSPriming(nsIURI* aContentLocation) { - bool isHttpScheme = false; - nsresult rv = aContentLocation->SchemeIs("http", &isHttpScheme); - NS_ENSURE_SUCCESS(rv, false); - if (!isHttpScheme) { - return false; - } - - int32_t port = -1; - rv = aContentLocation->GetPort(&port); - NS_ENSURE_SUCCESS(rv, false); - int32_t defaultPort = NS_GetDefaultPort("https"); - - if (port != -1 && port != defaultPort) { - // HSTS priming requests are only sent if the port is the default port - return false; - } - - nsAutoCString hostname; - rv = aContentLocation->GetHost(hostname); - NS_ENSURE_SUCCESS(rv, false); - - PRNetAddr hostAddr; - return (PR_StringToNetAddr(hostname.get(), &hostAddr) != PR_SUCCESS); -} - enum MixedContentHSTSState { MCB_HSTS_PASSIVE_NO_HSTS = 0, MCB_HSTS_PASSIVE_WITH_HSTS = 1, @@ -99,22 +65,6 @@ enum MixedContentHSTSState { MCB_HSTS_ACTIVE_WITH_HSTS = 3 }; -// Similar to the existing mixed-content HSTS, except MCB_HSTS_*_NO_HSTS is -// broken into two distinct states, indicating whether we plan to send a priming -// request or not. If we decided not go send a priming request, it could be -// because it is a type we do not support, or because we cached a previous -// negative response. -enum MixedContentHSTSPrimingState { - eMCB_HSTS_PASSIVE_WITH_HSTS = 0, - eMCB_HSTS_ACTIVE_WITH_HSTS = 1, - eMCB_HSTS_PASSIVE_NO_PRIMING = 2, - eMCB_HSTS_PASSIVE_DO_PRIMING = 3, - eMCB_HSTS_ACTIVE_NO_PRIMING = 4, - eMCB_HSTS_ACTIVE_DO_PRIMING = 5, - eMCB_HSTS_PASSIVE_UPGRADE = 6, - eMCB_HSTS_ACTIVE_UPGRADE = 7, -}; - // Fired at the document that attempted to load mixed content. The UI could // handle this event, for example, by displaying an info bar that offers the // choice to reload the page with mixed content permitted. @@ -264,18 +214,6 @@ nsMixedContentBlocker::nsMixedContentBlocker() // Cache the pref for mixed display blocking Preferences::AddBoolVarCache(&sBlockMixedDisplay, "security.mixed_content.block_display_content"); - - // Cache the pref for HSTS - Preferences::AddBoolVarCache(&sUseHSTS, - "security.mixed_content.use_hsts"); - - // Cache the pref for sending HSTS priming - Preferences::AddBoolVarCache(&sSendHSTSPriming, - "security.mixed_content.send_hsts_priming"); - - // Cache the pref for HSTS priming failure cache time - Preferences::AddUintVarCache(&sHSTSPrimingCacheTimeout, - "security.mixed_content.hsts_priming_cache_timeout"); } nsMixedContentBlocker::~nsMixedContentBlocker() @@ -405,26 +343,6 @@ nsMixedContentBlocker::AsyncOnChannelRedirect(nsIChannel* aOldChannel, return NS_BINDING_FAILED; } - if (nsMixedContentBlocker::sSendHSTSPriming) { - // The LoadInfo passed in is for the original channel, HSTS priming needs to - // be set on the new channel, if required. If the redirect changes - // http->https, or vice-versa, the need for priming may change. - nsCOMPtr newLoadInfo; - rv = aNewChannel->GetLoadInfo(getter_AddRefs(newLoadInfo)); - NS_ENSURE_SUCCESS(rv, rv); - if (newLoadInfo) { - rv = nsMixedContentBlocker::MarkLoadInfoForPriming(newUri, - requestingContext, - newLoadInfo); - if (NS_FAILED(rv)) { - decision = REJECT_REQUEST; - newLoadInfo->ClearHSTSPriming(); - } - } else { - decision = REJECT_REQUEST; - } - } - // If the channel is about to load mixed content, abort the channel if (!NS_CP_ACCEPTED(decision)) { autoCallback.DontCallback(); @@ -946,37 +864,6 @@ nsMixedContentBlocker::ShouldLoad(bool aHadInsecureImageRedirect, originAttributes = aRequestPrincipal->OriginAttributesRef(); } - bool active = (classification == eMixedScript); - bool doHSTSPriming = false; - if (IsEligibleForHSTSPriming(aContentLocation)) { - bool hsts = false; - bool cached = false; - nsCOMPtr sss = - do_GetService(NS_SSSERVICE_CONTRACTID, &rv); - NS_ENSURE_SUCCESS(rv, rv); - rv = sss->IsSecureURI(nsISiteSecurityService::HEADER_HSTS, aContentLocation, - 0, originAttributes, &cached, nullptr, &hsts); - NS_ENSURE_SUCCESS(rv, rv); - - if (hsts && sUseHSTS) { - // assume we will be upgraded later - Telemetry::Accumulate(Telemetry::MIXED_CONTENT_HSTS_PRIMING_2, - (active) ? MixedContentHSTSPrimingState::eMCB_HSTS_ACTIVE_UPGRADE - : MixedContentHSTSPrimingState::eMCB_HSTS_PASSIVE_UPGRADE); - *aDecision = ACCEPT; - return NS_OK; - } - - // Send a priming request if the result is not already cached and priming - // requests are allowed - if (!cached && sSendHSTSPriming) { - // add this URI as a priming location - doHSTSPriming = true; - document->AddHSTSPrimingLocation(innerContentLocation, - HSTSPrimingState::eHSTS_PRIMING_ALLOW); - *aDecision = ACCEPT; - } - } // At this point we know that the request is mixed content, and the only // question is whether we block it. Record telemetry at this point as to @@ -990,9 +877,10 @@ nsMixedContentBlocker::ShouldLoad(bool aHadInsecureImageRedirect, // // We do not count requests aHadInsecureImageRedirect=true, since these are // just an artifact of the image caching system. + bool active = (classification == eMixedScript); if (!aHadInsecureImageRedirect) { if (XRE_IsParentProcess()) { - AccumulateMixedContentHSTS(innerContentLocation, active, doHSTSPriming, + AccumulateMixedContentHSTS(innerContentLocation, active, originAttributes); } else { // Ask the parent process to do the same call @@ -1000,7 +888,7 @@ nsMixedContentBlocker::ShouldLoad(bool aHadInsecureImageRedirect, if (cc) { mozilla::ipc::URIParams uri; SerializeURI(innerContentLocation, uri); - cc->SendAccumulateMixedContentHSTS(uri, active, doHSTSPriming, + cc->SendAccumulateMixedContentHSTS(uri, active, originAttributes); } } @@ -1044,13 +932,7 @@ nsMixedContentBlocker::ShouldLoad(bool aHadInsecureImageRedirect, } } } else { - if (doHSTSPriming) { - document->AddHSTSPrimingLocation(innerContentLocation, - HSTSPrimingState::eHSTS_PRIMING_BLOCK); - *aDecision = nsIContentPolicy::ACCEPT; - } else { - *aDecision = nsIContentPolicy::REJECT_REQUEST; - } + *aDecision = nsIContentPolicy::REJECT_REQUEST; LogMixedContentMessage(classification, aContentLocation, rootDoc, eBlocked); if (!rootDoc->GetHasMixedDisplayContentBlocked() && NS_SUCCEEDED(stateRV)) { rootDoc->SetHasMixedDisplayContentBlocked(true); @@ -1096,13 +978,7 @@ nsMixedContentBlocker::ShouldLoad(bool aHadInsecureImageRedirect, } } else { //User has not overriden the pref by Disabling protection. Reject the request and update the security state. - if (doHSTSPriming) { - document->AddHSTSPrimingLocation(innerContentLocation, - HSTSPrimingState::eHSTS_PRIMING_BLOCK); - *aDecision = nsIContentPolicy::ACCEPT; - } else { - *aDecision = nsIContentPolicy::REJECT_REQUEST; - } + *aDecision = nsIContentPolicy::REJECT_REQUEST; LogMixedContentMessage(classification, aContentLocation, rootDoc, eBlocked); // See if the pref will change here. If it will, only then do we need to call OnSecurityChange() to update the UI. if (rootDoc->GetHasMixedActiveContentBlocked()) { @@ -1164,8 +1040,7 @@ nsMixedContentBlocker::ShouldProcess(uint32_t aContentType, // content (regardless of whether it was actually blocked) void nsMixedContentBlocker::AccumulateMixedContentHSTS( - nsIURI* aURI, bool aActive, bool aHasHSTSPriming, - const OriginAttributes& aOriginAttributes) + nsIURI* aURI, bool aActive, const OriginAttributes& aOriginAttributes) { // This method must only be called in the parent, because // nsSiteSecurityService is only available in the parent @@ -1193,101 +1068,19 @@ nsMixedContentBlocker::AccumulateMixedContentHSTS( if (!hsts) { Telemetry::Accumulate(Telemetry::MIXED_CONTENT_HSTS, MCB_HSTS_PASSIVE_NO_HSTS); - if (aHasHSTSPriming) { - Telemetry::Accumulate(Telemetry::MIXED_CONTENT_HSTS_PRIMING_2, - eMCB_HSTS_PASSIVE_DO_PRIMING); - } else { - Telemetry::Accumulate(Telemetry::MIXED_CONTENT_HSTS_PRIMING_2, - eMCB_HSTS_PASSIVE_NO_PRIMING); - } } else { Telemetry::Accumulate(Telemetry::MIXED_CONTENT_HSTS, MCB_HSTS_PASSIVE_WITH_HSTS); - Telemetry::Accumulate(Telemetry::MIXED_CONTENT_HSTS_PRIMING_2, - eMCB_HSTS_PASSIVE_WITH_HSTS); } } else { if (!hsts) { Telemetry::Accumulate(Telemetry::MIXED_CONTENT_HSTS, MCB_HSTS_ACTIVE_NO_HSTS); - if (aHasHSTSPriming) { - Telemetry::Accumulate(Telemetry::MIXED_CONTENT_HSTS_PRIMING_2, - eMCB_HSTS_ACTIVE_DO_PRIMING); - } else { - Telemetry::Accumulate(Telemetry::MIXED_CONTENT_HSTS_PRIMING_2, - eMCB_HSTS_ACTIVE_NO_PRIMING); - } } else { Telemetry::Accumulate(Telemetry::MIXED_CONTENT_HSTS, MCB_HSTS_ACTIVE_WITH_HSTS); - Telemetry::Accumulate(Telemetry::MIXED_CONTENT_HSTS_PRIMING_2, - eMCB_HSTS_ACTIVE_WITH_HSTS); } } } - -//static -nsresult -nsMixedContentBlocker::MarkLoadInfoForPriming(nsIURI* aURI, - nsISupports* aRequestingContext, - nsILoadInfo* aLoadInfo) -{ - nsresult rv; - bool sendPriming = false; - bool mixedContentWouldBlock = false; - rv = GetHSTSPrimingFromRequestingContext(aURI, - aRequestingContext, - &sendPriming, - &mixedContentWouldBlock); - NS_ENSURE_SUCCESS(rv, rv); - - if (sendPriming) { - aLoadInfo->SetHSTSPriming(mixedContentWouldBlock); - } - - return NS_OK; -} - -//static -nsresult -nsMixedContentBlocker::GetHSTSPrimingFromRequestingContext(nsIURI* aURI, - nsISupports* aRequestingContext, - bool* aSendPrimingRequest, - bool* aMixedContentWouldBlock) -{ - *aSendPrimingRequest = false; - *aMixedContentWouldBlock = false; - // If we marked for priming, we used the innermost URI, so get that - nsCOMPtr innerURI = NS_GetInnermostURI(aURI); - if (!innerURI) { - NS_ERROR("Can't get innerURI from aContentLocation"); - return NS_ERROR_CONTENT_BLOCKED; - } - - bool isHttp = false; - innerURI->SchemeIs("http", &isHttp); - if (!isHttp) { - // there is nothign to do - return NS_OK; - } - - // If the DocShell was marked for HSTS priming, propagate that to the LoadInfo - nsCOMPtr docShell = NS_CP_GetDocShellFromContext(aRequestingContext); - if (!docShell) { - return NS_OK; - } - nsCOMPtr document = docShell->GetDocument(); - if (!document) { - return NS_OK; - } - - HSTSPrimingState status = document->GetHSTSPrimingStateForLocation(innerURI); - if (status != HSTSPrimingState::eNO_HSTS_PRIMING) { - *aSendPrimingRequest = (status != HSTSPrimingState::eNO_HSTS_PRIMING); - *aMixedContentWouldBlock = (status == HSTSPrimingState::eHSTS_PRIMING_BLOCK); - } - - return NS_OK; -} diff --git a/dom/security/nsMixedContentBlocker.h b/dom/security/nsMixedContentBlocker.h index ad88a8af0a13..b7e4a7457bd2 100644 --- a/dom/security/nsMixedContentBlocker.h +++ b/dom/security/nsMixedContentBlocker.h @@ -69,45 +69,11 @@ public: int16_t* aDecision); static void AccumulateMixedContentHSTS(nsIURI* aURI, bool aActive, - bool aHasHSTSPriming, const OriginAttributes& aOriginAttributes); - /* If the document associated with aRequestingContext requires priming for - * aURI, propagate that to the LoadInfo so the HttpChannel will find out about - * it. - * - * @param aURI The URI associated with the load - * @param aRequestingContext the requesting context passed to ShouldLoad - * @param aLoadInfo the LoadInfo for the load - */ - static nsresult MarkLoadInfoForPriming(nsIURI* aURI, - nsISupports* aRequestingContext, - nsILoadInfo* aLoadInfo); - - /* Given a context, return whether HSTS was marked on the document associated - * with the load for the given URI. This is used by MarkLoadInfoForPriming and - * directly by the image loader to determine whether to allow a load to occur - * from the cache. - * - * @param aURI The URI associated with the load - * @param aRequestingContext the requesting context passed to ShouldLoad - * @param aSendPrimingRequest out true if priming is required on the channel - * @param aMixedContentWouldBlock out true if mixed content would block - */ - static nsresult GetHSTSPrimingFromRequestingContext(nsIURI* aURI, - nsISupports* aRequestingContext, - bool* aSendPrimingRequest, - bool* aMixedContentWouldBlock); - static bool sBlockMixedScript; static bool sBlockMixedObjectSubrequest; static bool sBlockMixedDisplay; - // Do we move HSTS before mixed-content - static bool sUseHSTS; - // Do we send an HSTS priming request - static bool sSendHSTSPriming; - // Default HSTS Priming failure timeout in seconds - static uint32_t sHSTSPrimingCacheTimeout; }; #endif /* nsMixedContentBlocker_h___ */ diff --git a/dom/security/test/csp/test_referrerdirective.html b/dom/security/test/csp/test_referrerdirective.html index 1caa5c99d063..88630617bf11 100644 --- a/dom/security/test/csp/test_referrerdirective.html +++ b/dom/security/test/csp/test_referrerdirective.html @@ -116,8 +116,6 @@ SimpleTest.waitForExplicitFinish(); SpecialPowers.pushPrefEnv({ 'set': [['security.mixed_content.block_active_content', false], ['security.mixed_content.block_display_content', false], - ['security.mixed_content.send_hsts_priming', false], - ['security.mixed_content.use_hsts', false], ] }, function() { diff --git a/dom/security/test/hsts/browser.ini b/dom/security/test/hsts/browser.ini deleted file mode 100644 index f9a9a58d6be0..000000000000 --- a/dom/security/test/hsts/browser.ini +++ /dev/null @@ -1,25 +0,0 @@ -[DEFAULT] -skip-if = true # Bug 1425968 - Depends on an expiring Telemetry probe and feature is being removed -support-files = - head.js - file_priming-top.html - file_testserver.sjs - file_1x1.png - file_priming.js - file_stylesheet.css - -[browser_hsts-priming_allow_active.js] -[browser_hsts-priming_block_active.js] -[browser_hsts-priming_hsts_after_mixed.js] -skip-if = os == "linux" # Bug 1311239 -[browser_hsts-priming_allow_display.js] -[browser_hsts-priming_block_display.js] -[browser_hsts-priming_block_active_css.js] -[browser_hsts-priming_block_active_with_redir_same.js] -[browser_hsts-priming_no-duplicates.js] -[browser_hsts-priming_cache-timeout.js] -[browser_hsts-priming_timeout.js] -[browser_hsts-priming_no-non-standard-ports.js] -[browser_hsts-priming_no-ip-address.js] -[browser_hsts-priming_include-subdomains.js] -skip-if = os == "linux" # Bug 1376238 diff --git a/dom/security/test/hsts/browser_hsts-priming_allow_active.js b/dom/security/test/hsts/browser_hsts-priming_allow_active.js deleted file mode 100644 index 184005439a15..000000000000 --- a/dom/security/test/hsts/browser_hsts-priming_allow_active.js +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Description of the test: - * Check that HSTS priming occurs correctly with mixed content when active - * content is allowed. - */ -'use strict'; - -var expected_telemetry = { - "histograms": { - "MIXED_CONTENT_HSTS_PRIMING_RESULT": 3, - "MIXED_CONTENT_HSTS_PRIMING_REQUESTS": 6, - "HSTS_UPGRADE_SOURCE": [ 0,0,1,0,0,0,0,0,0 ] - }, - "keyed-histograms": { - "HSTS_PRIMING_REQUEST_DURATION": { - "success": 1, - "failure": 2, - }, - } -}; - -//jscs:disable -add_task(async function() { - //jscs:enable - Services.obs.addObserver(Observer, "console-api-log-event"); - Services.obs.addObserver(Observer, "http-on-examine-response"); - registerCleanupFunction(do_cleanup); - - let which = "allow_active"; - - SetupPrefTestEnvironment(which); - clear_hists(expected_telemetry); - - for (let server of Object.keys(test_servers)) { - await execute_test(server, test_settings[which].mimetype); - } - - test_telemetry(expected_telemetry); - - SpecialPowers.popPrefEnv(); -}); diff --git a/dom/security/test/hsts/browser_hsts-priming_allow_display.js b/dom/security/test/hsts/browser_hsts-priming_allow_display.js deleted file mode 100644 index ec8158b78984..000000000000 --- a/dom/security/test/hsts/browser_hsts-priming_allow_display.js +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Description of the test: - * Check that HSTS priming occurs correctly with mixed content when display - * content is allowed. - */ -'use strict'; - -var expected_telemetry = { - "histograms": { - "MIXED_CONTENT_HSTS_PRIMING_RESULT": 3, - "MIXED_CONTENT_HSTS_PRIMING_REQUESTS": 6, - "HSTS_UPGRADE_SOURCE": [ 0,0,1,0,0,0,0,0,0 ] - }, - "keyed-histograms": { - "HSTS_PRIMING_REQUEST_DURATION": { - "success": 1, - "failure": 2, - }, - } -}; - -//jscs:disable -add_task(async function() { - //jscs:enable - Services.obs.addObserver(Observer, "console-api-log-event"); - Services.obs.addObserver(Observer, "http-on-examine-response"); - registerCleanupFunction(do_cleanup); - - let which = "allow_display"; - - SetupPrefTestEnvironment(which); - clear_hists(expected_telemetry); - - for (let server of Object.keys(test_servers)) { - await execute_test(server, test_settings[which].mimetype); - } - - test_telemetry(expected_telemetry); - - SpecialPowers.popPrefEnv(); -}); diff --git a/dom/security/test/hsts/browser_hsts-priming_block_active.js b/dom/security/test/hsts/browser_hsts-priming_block_active.js deleted file mode 100644 index f6b9a8c3035c..000000000000 --- a/dom/security/test/hsts/browser_hsts-priming_block_active.js +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Description of the test: - * Check that HSTS priming occurs correctly with mixed content when active - * content is blocked. - */ -'use strict'; - -var expected_telemetry = { - "histograms": { - "MIXED_CONTENT_HSTS_PRIMING_RESULT": 3, - "MIXED_CONTENT_HSTS_PRIMING_REQUESTS": 6, - "HSTS_UPGRADE_SOURCE": [ 0,0,1,0,0,0,0,0,0 ] - }, - "keyed-histograms": { - "HSTS_PRIMING_REQUEST_DURATION": { - "success": 1, - "failure": 2, - }, - } -}; - -//jscs:disable -add_task(async function() { - //jscs:enable - Services.obs.addObserver(Observer, "console-api-log-event"); - Services.obs.addObserver(Observer, "http-on-examine-response"); - registerCleanupFunction(do_cleanup); - - let which = "block_active"; - - SetupPrefTestEnvironment(which); - clear_hists(expected_telemetry); - - for (let server of Object.keys(test_servers)) { - await execute_test(server, test_settings[which].mimetype); - } - - test_telemetry(expected_telemetry); - - SpecialPowers.popPrefEnv(); -}); diff --git a/dom/security/test/hsts/browser_hsts-priming_block_active_css.js b/dom/security/test/hsts/browser_hsts-priming_block_active_css.js deleted file mode 100644 index 9a057bc71ab5..000000000000 --- a/dom/security/test/hsts/browser_hsts-priming_block_active_css.js +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Description of the test: - * Check that HSTS priming occurs correctly with mixed content when active - * content is blocked for css. - */ -'use strict'; - -var expected_telemetry = { - "histograms": { - "MIXED_CONTENT_HSTS_PRIMING_RESULT": 3, - "MIXED_CONTENT_HSTS_PRIMING_REQUESTS": 6, - "HSTS_UPGRADE_SOURCE": [ 0,0,1,0,0,0,0,0,0 ] - }, - "keyed-histograms": { - "HSTS_PRIMING_REQUEST_DURATION": { - "success": 1, - "failure": 2, - }, - } -}; - -//jscs:disable -add_task(async function() { - //jscs:enable - Services.obs.addObserver(Observer, "console-api-log-event"); - Services.obs.addObserver(Observer, "http-on-examine-response"); - registerCleanupFunction(do_cleanup); - - let which = "block_active_css"; - - SetupPrefTestEnvironment(which); - clear_hists(expected_telemetry); - - for (let server of Object.keys(test_servers)) { - await execute_test(server, test_settings[which].mimetype); - } - - test_telemetry(expected_telemetry); - - SpecialPowers.popPrefEnv(); -}); diff --git a/dom/security/test/hsts/browser_hsts-priming_block_active_with_redir_same.js b/dom/security/test/hsts/browser_hsts-priming_block_active_with_redir_same.js deleted file mode 100644 index e62c104d7823..000000000000 --- a/dom/security/test/hsts/browser_hsts-priming_block_active_with_redir_same.js +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Description of the test: - * Check that HSTS priming occurs correctly with mixed content when active - * content is blocked and redirect to the same host should still upgrade. - */ -'use strict'; - -var expected_telemetry = { - "histograms": { - "MIXED_CONTENT_HSTS_PRIMING_RESULT": 3, - "MIXED_CONTENT_HSTS_PRIMING_REQUESTS": 6, - "HSTS_UPGRADE_SOURCE": [ 0,0,1,0,0,0,0,0,0 ] - }, - "keyed-histograms": { - "HSTS_PRIMING_REQUEST_DURATION": { - "success": 1, - "failure": 2, - }, - } -}; - -//jscs:disable -add_task(async function() { - //jscs:enable - Services.obs.addObserver(Observer, "console-api-log-event"); - Services.obs.addObserver(Observer, "http-on-examine-response"); - registerCleanupFunction(do_cleanup); - - let which = "block_active_with_redir_same"; - - SetupPrefTestEnvironment(which); - clear_hists(expected_telemetry); - - for (let server of Object.keys(test_servers)) { - await execute_test(server, test_settings[which].mimetype); - } - - test_telemetry(expected_telemetry); - - SpecialPowers.popPrefEnv(); -}); diff --git a/dom/security/test/hsts/browser_hsts-priming_block_display.js b/dom/security/test/hsts/browser_hsts-priming_block_display.js deleted file mode 100644 index eec5e9841bb4..000000000000 --- a/dom/security/test/hsts/browser_hsts-priming_block_display.js +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Description of the test: - * Check that HSTS priming occurs correctly with mixed content when display - * content is blocked. - */ -'use strict'; - -var expected_telemetry = { - "histograms": { - "MIXED_CONTENT_HSTS_PRIMING_RESULT": 3, - "MIXED_CONTENT_HSTS_PRIMING_REQUESTS": 6, - "HSTS_UPGRADE_SOURCE": [ 0,0,1,0,0,0,0,0,0 ] - }, - "keyed-histograms": { - "HSTS_PRIMING_REQUEST_DURATION": { - "success": 1, - "failure": 2, - }, - } -}; - -//jscs:disable -add_task(async function() { - //jscs:enable - Services.obs.addObserver(Observer, "console-api-log-event"); - Services.obs.addObserver(Observer, "http-on-examine-response"); - registerCleanupFunction(do_cleanup); - - let which = "block_display"; - - SetupPrefTestEnvironment(which); - clear_hists(expected_telemetry); - - for (let server of Object.keys(test_servers)) { - await execute_test(server, test_settings[which].mimetype); - } - - test_telemetry(expected_telemetry); - - SpecialPowers.popPrefEnv(); -}); diff --git a/dom/security/test/hsts/browser_hsts-priming_cache-timeout.js b/dom/security/test/hsts/browser_hsts-priming_cache-timeout.js deleted file mode 100644 index 88a16c7e9be4..000000000000 --- a/dom/security/test/hsts/browser_hsts-priming_cache-timeout.js +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Description of the test: - * Test that the network.hsts_priming.cache_timeout preferene causes the cache - * to timeout - */ -'use strict'; - -var expected_telemetry = { - "histograms": { - "MIXED_CONTENT_HSTS_PRIMING_RESULT": 2, - "MIXED_CONTENT_HSTS_PRIMING_REQUESTS": 4, - }, - "keyed-histograms": { - "HSTS_PRIMING_REQUEST_DURATION": { - "failure": 2, - }, - } -}; - -//jscs:disable -add_task(async function() { - //jscs:enable - Observer.add_observers(Services); - registerCleanupFunction(do_cleanup); - - let which = "block_display"; - - SetupPrefTestEnvironment(which, [["security.mixed_content.hsts_priming_cache_timeout", 1]]); - clear_hists(expected_telemetry); - - await execute_test("no-ssl", test_settings[which].mimetype); - - let pre_promise = performance.now(); - - while ((performance.now() - pre_promise) < 1000) { - await new Promise(function (resolve) { - setTimeout(resolve, 1000); - }); - } - - // clear the fact that we saw a priming request - test_settings[which].priming = {}; - - await execute_test("no-ssl", test_settings[which].mimetype); - is(test_settings[which].priming["no-ssl"], true, - "Correctly send a priming request after expiration."); - - test_telemetry(expected_telemetry); - - SpecialPowers.popPrefEnv(); -}); diff --git a/dom/security/test/hsts/browser_hsts-priming_hsts_after_mixed.js b/dom/security/test/hsts/browser_hsts-priming_hsts_after_mixed.js deleted file mode 100644 index 2cb92ab8132e..000000000000 --- a/dom/security/test/hsts/browser_hsts-priming_hsts_after_mixed.js +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Description of the test: - * Check that HSTS priming occurs correctly with mixed content when the - * mixed-content blocks before HSTS. - */ -'use strict'; - -var expected_telemetry = { - "histograms": { - "MIXED_CONTENT_HSTS_PRIMING_RESULT": 3, - "MIXED_CONTENT_HSTS_PRIMING_REQUESTS": 6, - "HSTS_UPGRADE_SOURCE": [ 0,0,0,0,0,0,0,0,0 ] - }, - "keyed-histograms": { - "HSTS_PRIMING_REQUEST_DURATION": { - "success": 1, - "failure": 2, - }, - } -}; - -//jscs:disable -add_task(async function() { - //jscs:enable - Services.obs.addObserver(Observer, "console-api-log-event"); - Services.obs.addObserver(Observer, "http-on-examine-response"); - registerCleanupFunction(do_cleanup); - - let which = "hsts_after_mixed"; - - SetupPrefTestEnvironment(which); - clear_hists(expected_telemetry); - - for (let server of Object.keys(test_servers)) { - await execute_test(server, test_settings[which].mimetype); - } - - test_telemetry(expected_telemetry); - - SpecialPowers.popPrefEnv(); -}); diff --git a/dom/security/test/hsts/browser_hsts-priming_include-subdomains.js b/dom/security/test/hsts/browser_hsts-priming_include-subdomains.js deleted file mode 100644 index f13db3759c32..000000000000 --- a/dom/security/test/hsts/browser_hsts-priming_include-subdomains.js +++ /dev/null @@ -1,55 +0,0 @@ -/* 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/. */ - -/* - * Description of the test: - * If the top-level domain sends the STS header but does not have - * includeSubdomains, HSTS priming requests should still be sent to - * subdomains. - */ -'use strict'; - -var expected_telemetry = { - "histograms": { - "MIXED_CONTENT_HSTS_PRIMING_RESULT": 2, - "MIXED_CONTENT_HSTS_PRIMING_REQUESTS": 4, - "HSTS_UPGRADE_SOURCE": [ 0,0,2,0,0,0,0,0,0 ] - }, - "keyed-histograms": { - "HSTS_PRIMING_REQUEST_DURATION": { - "success": 2, - }, - } -}; - -//jscs:disable -add_task(async function() { - //jscs:enable - Observer.add_observers(Services); - registerCleanupFunction(do_cleanup); - - // add the top-level server - test_servers['top-level'] = { - host: 'example.com', - response: true, - id: 'top-level', - }; - test_settings.block_active.result['top-level'] = 'secure'; - - let which = "block_active"; - - SetupPrefTestEnvironment(which); - clear_hists(expected_telemetry); - - await execute_test("top-level", test_settings[which].mimetype); - - await execute_test("prime-hsts", test_settings[which].mimetype); - - ok("prime-hsts" in test_settings[which].priming, - "HSTS priming on a subdomain when top-level does not includeSubDomains"); - - test_telemetry(expected_telemetry); - - SpecialPowers.popPrefEnv(); -}); diff --git a/dom/security/test/hsts/browser_hsts-priming_no-duplicates.js b/dom/security/test/hsts/browser_hsts-priming_no-duplicates.js deleted file mode 100644 index e02bf546c5b6..000000000000 --- a/dom/security/test/hsts/browser_hsts-priming_no-duplicates.js +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Description of the test: - * Only one request should be sent per host, even if we run the test more - * than once. - */ -'use strict'; - -var expected_telemetry = { - "histograms": { - "MIXED_CONTENT_HSTS_PRIMING_RESULT": 3, - "MIXED_CONTENT_HSTS_PRIMING_REQUESTS": 8, - "HSTS_UPGRADE_SOURCE": [ 0,0,2,0,0,0,0,0,0 ] - }, - "keyed-histograms": { - "HSTS_PRIMING_REQUEST_DURATION": { - "success": 1, - "failure": 2, - }, - } -}; - -//jscs:disable -add_task(async function() { - //jscs:enable - Observer.add_observers(Services); - registerCleanupFunction(do_cleanup); - - let which = "block_display"; - - SetupPrefTestEnvironment(which); - clear_hists(expected_telemetry); - - for (let server of Object.keys(test_servers)) { - await execute_test(server, test_settings[which].mimetype); - } - - // run the tests twice to validate the cache is being used - for (let server of Object.keys(test_servers)) { - await execute_test(server, test_settings[which].mimetype); - } - - test_telemetry(expected_telemetry); - - SpecialPowers.popPrefEnv(); -}); diff --git a/dom/security/test/hsts/browser_hsts-priming_no-ip-address.js b/dom/security/test/hsts/browser_hsts-priming_no-ip-address.js deleted file mode 100644 index d6ed113ac935..000000000000 --- a/dom/security/test/hsts/browser_hsts-priming_no-ip-address.js +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Description of the test: - * If the top-level domain sends the STS header but does not have - * includeSubdomains, HSTS priming requests should still be sent to - * subdomains. - */ -'use strict'; - -var expected_telemetry = { - "histograms": { - "MIXED_CONTENT_HSTS_PRIMING_RESULT": 0, - "MIXED_CONTENT_HSTS_PRIMING_REQUESTS": 1, - }, - "keyed-histograms": { - } -}; - -//jscs:disable -add_task(async function() { - //jscs:enable - Observer.add_observers(Services); - registerCleanupFunction(do_cleanup); - - // add the top-level server - test_servers['localhost-ip'] = { - host: '127.0.0.2', - response: true, - id: 'localhost-ip', - }; - test_settings.block_active.result['localhost-ip'] = 'blocked'; - - let which = "block_active"; - - SetupPrefTestEnvironment(which); - clear_hists(expected_telemetry); - - await execute_test("localhost-ip", test_settings[which].mimetype); - - test_telemetry(expected_telemetry); - - SpecialPowers.popPrefEnv(); -}); diff --git a/dom/security/test/hsts/browser_hsts-priming_no-non-standard-ports.js b/dom/security/test/hsts/browser_hsts-priming_no-non-standard-ports.js deleted file mode 100644 index c332436e3a72..000000000000 --- a/dom/security/test/hsts/browser_hsts-priming_no-non-standard-ports.js +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Description of the test: - * If the top-level domain sends the STS header but does not have - * includeSubdomains, HSTS priming requests should still be sent to - * subdomains. - */ -'use strict'; - -var expected_telemetry = { - "histograms": { - "MIXED_CONTENT_HSTS_PRIMING_RESULT": 1, - "MIXED_CONTENT_HSTS_PRIMING_REQUESTS": 3, - "HSTS_UPGRADE_SOURCE": [ 0,0,1,0,0,0,0,0,0 ] - }, - "keyed-histograms": { - "HSTS_PRIMING_REQUEST_DURATION": { - "success": 1, - }, - } -}; - -//jscs:disable -add_task(async function() { - //jscs:enable - Observer.add_observers(Services); - registerCleanupFunction(do_cleanup); - - // add the top-level server - test_servers['non-standard-port'] = { - host: 'test1.example.com:1234', - response: true, - id: 'non-standard-port', - }; - test_settings.block_active.result['non-standard-port'] = 'blocked'; - - let which = "block_active"; - - SetupPrefTestEnvironment(which); - clear_hists(expected_telemetry); - - await execute_test("non-standard-port", test_settings[which].mimetype); - - await execute_test("prime-hsts", test_settings[which].mimetype); - - ok("prime-hsts" in test_settings[which_test].priming, "Sent priming request on standard port after non-standard was not primed"); - - test_telemetry(expected_telemetry); - - SpecialPowers.popPrefEnv(); -}); diff --git a/dom/security/test/hsts/browser_hsts-priming_timeout.js b/dom/security/test/hsts/browser_hsts-priming_timeout.js deleted file mode 100644 index c2ca72bb7aea..000000000000 --- a/dom/security/test/hsts/browser_hsts-priming_timeout.js +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Description of the test: - * Only one request should be sent per host, even if we run the test more - * than once. - */ -'use strict'; - -var expected_telemetry = { - "histograms": { - "MIXED_CONTENT_HSTS_PRIMING_RESULT": 3, - "MIXED_CONTENT_HSTS_PRIMING_REQUESTS": 3, - }, - "keyed-histograms": { - "HSTS_PRIMING_REQUEST_DURATION": { - "failure": 3, - }, - } -}; - -//jscs:disable -add_task(async function() { - //jscs:enable - Observer.add_observers(Services); - registerCleanupFunction(do_cleanup); - - let which = "timeout"; - - SetupPrefTestEnvironment(which, [["security.mixed_content.hsts_priming_request_timeout", - 1000]]); - clear_hists(expected_telemetry); - - for (let server of Object.keys(test_servers)) { - await execute_test(server, test_settings[which].mimetype); - } - - test_telemetry(expected_telemetry); - - SpecialPowers.popPrefEnv(); -}); diff --git a/dom/security/test/hsts/file_1x1.png b/dom/security/test/hsts/file_1x1.png deleted file mode 100644 index 1ba31ba1a623..000000000000 Binary files a/dom/security/test/hsts/file_1x1.png and /dev/null differ diff --git a/dom/security/test/hsts/file_priming-top.html b/dom/security/test/hsts/file_priming-top.html deleted file mode 100644 index 4a7b1763e1e8..000000000000 --- a/dom/security/test/hsts/file_priming-top.html +++ /dev/null @@ -1,89 +0,0 @@ - - - - Bug 1246540 - - - -

- - - - - diff --git a/dom/security/test/hsts/file_priming.js b/dom/security/test/hsts/file_priming.js deleted file mode 100644 index 023022da67cd..000000000000 --- a/dom/security/test/hsts/file_priming.js +++ /dev/null @@ -1,4 +0,0 @@ -function completed() { - return; -} -completed(); diff --git a/dom/security/test/hsts/file_stylesheet.css b/dom/security/test/hsts/file_stylesheet.css deleted file mode 100644 index 208d16d4213b..000000000000 --- a/dom/security/test/hsts/file_stylesheet.css +++ /dev/null @@ -1 +0,0 @@ -body {} diff --git a/dom/security/test/hsts/file_testserver.sjs b/dom/security/test/hsts/file_testserver.sjs deleted file mode 100644 index 43a8f95991ef..000000000000 --- a/dom/security/test/hsts/file_testserver.sjs +++ /dev/null @@ -1,84 +0,0 @@ -// SJS file for HSTS mochitests - -Components.utils.import("resource://gre/modules/NetUtil.jsm"); -Components.utils.importGlobalProperties(["URLSearchParams"]); - -function loadFromFile(path) { - // Load the HTML to return in the response from file. - // Since it's relative to the cwd of the test runner, we start there and - // append to get to the actual path of the file. - var testFile = - Components.classes["@mozilla.org/file/directory_service;1"]. - getService(Components.interfaces.nsIProperties). - get("CurWorkD", Components.interfaces.nsIFile); - var dirs = path.split("/"); - for (var i = 0; i < dirs.length; i++) { - testFile.append(dirs[i]); - } - var testFileStream = - Components.classes["@mozilla.org/network/file-input-stream;1"]. - createInstance(Components.interfaces.nsIFileInputStream); - testFileStream.init(testFile, -1, 0, 0); - var test = NetUtil.readInputStreamToString(testFileStream, testFileStream.available()); - return test; -} - -function handleRequest(request, response) -{ - const query = new URLSearchParams(request.queryString); - - var timeout = parseInt(query.get('timeout')); - response.processAsync(); - - timer = Components.classes["@mozilla.org/timer;1"].createInstance(Components.interfaces.nsITimer); - timer.initWithCallback(function() - { - if (!response) { - return; - } - - // avoid confusing cache behaviors - response.setHeader("Cache-Control", "no-cache", false); - - redir = query.get('redir'); - if (redir == 'same') { - query.delete("redir"); - response.setStatus(302); - let newURI = request.uri; - newURI.queryString = query.serialize(); - response.setHeader("Location", newURI.spec) - response.write('xyzzy'); - response.finish(); - return; - } - - // if we have a priming header, check for required behavior - // and set header appropriately - if (request.hasHeader('Upgrade-Insecure-Requests')) { - var expected = query.get('primer'); - if (expected == 'prime-hsts' || expected == 'top-level') { - // set it for 5 minutes - response.setHeader("Strict-Transport-Security", "max-age="+(60*5), false); - } else if (expected == 'reject-upgrade') { - response.setHeader("Strict-Transport-Security", "max-age=0", false); - } - response.write('xyzzy'); - response.finish(); - return; - } - - var file = query.get('file'); - if (file) { - var mimetype = unescape(query.get('mimetype')); - response.setHeader("Content-Type", mimetype, false); - let contents = loadFromFile(unescape(file)); - response.write(contents); - response.finish(); - return; - } - - response.setHeader("Content-Type", "application/json", false); - response.write('{}'); - response.finish(); - }, timeout, Components.interfaces.nsITimer.TYPE_ONE_SHOT); -} diff --git a/dom/security/test/hsts/head.js b/dom/security/test/hsts/head.js deleted file mode 100644 index 114f3de23121..000000000000 --- a/dom/security/test/hsts/head.js +++ /dev/null @@ -1,543 +0,0 @@ -/* - * Description of the tests: - * Check that HSTS priming occurs correctly with mixed content - * - * This test uses three hostnames, each of which treats an HSTS priming - * request differently. - * * no-ssl never returns an ssl response - * * reject-upgrade returns an ssl response, but with no STS header - * * prime-hsts returns an ssl response with the appropriate STS header - * - * For each server, test that it response appropriately when the we allow - * or block active or display content, as well as when we send an hsts priming - * request, but do not change the order of mixed-content and HSTS. - * - * Test use http-on-examine-response, so must be run in browser context. - */ -'use strict'; - -var { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components; - -var TOP_URI = "https://example.com/browser/dom/security/test/hsts/file_priming-top.html"; - -var test_servers = { - // a test server that does not support TLS - 'no-ssl': { - host: 'example.co.jp', - response: false, - id: 'no-ssl', - }, - // a test server which does not support STS upgrade - 'reject-upgrade': { - host: 'example.org', - response: true, - id: 'reject-upgrade', - }, - // a test server when sends an STS header when priming - 'prime-hsts': { - host: 'test1.example.com', - response: true, - id: 'prime-hsts' - }, -}; - -var test_settings = { - // mixed active content is allowed, priming will upgrade - allow_active: { - block_active: false, - block_display: false, - use_hsts: true, - send_hsts_priming: true, - type: 'script', - timeout: 0, - result: { - 'no-ssl': 'insecure', - 'reject-upgrade': 'insecure', - 'prime-hsts': 'secure', - }, - }, - // mixed active content is blocked, priming will upgrade - block_active: { - block_active: true, - block_display: false, - use_hsts: true, - send_hsts_priming: true, - type: 'script', - timeout: 0, - result: { - 'no-ssl': 'blocked', - 'reject-upgrade': 'blocked', - 'prime-hsts': 'secure', - }, - }, - // keep the original order of mixed-content and HSTS, but send - // priming requests - hsts_after_mixed: { - block_active: true, - block_display: false, - use_hsts: false, - send_hsts_priming: true, - type: 'script', - timeout: 0, - result: { - 'no-ssl': 'blocked', - 'reject-upgrade': 'blocked', - 'prime-hsts': 'blocked', - }, - }, - // mixed display content is allowed, priming will upgrade - allow_display: { - block_active: true, - block_display: false, - use_hsts: true, - send_hsts_priming: true, - type: 'img', - timeout: 0, - result: { - 'no-ssl': 'insecure', - 'reject-upgrade': 'insecure', - 'prime-hsts': 'secure', - }, - }, - // mixed display content is blocked, priming will upgrade - block_display: { - block_active: true, - block_display: true, - use_hsts: true, - send_hsts_priming: true, - type: 'img', - timeout: 0, - result: { - 'no-ssl': 'blocked', - 'reject-upgrade': 'blocked', - 'prime-hsts': 'secure', - }, - }, - // mixed active content is blocked, priming will upgrade (css) - block_active_css: { - block_active: true, - block_display: true, - use_hsts: true, - send_hsts_priming: true, - type: 'css', - timeout: 0, - result: { - 'no-ssl': 'blocked', - 'reject-upgrade': 'blocked', - 'prime-hsts': 'secure', - }, - }, - // mixed active content is blocked, priming will upgrade - // redirect to the same host - block_active_with_redir_same: { - block_active: true, - block_display: false, - use_hsts: true, - send_hsts_priming: true, - type: 'script', - redir: 'same', - timeout: 0, - result: { - 'no-ssl': 'blocked', - 'reject-upgrade': 'blocked', - 'prime-hsts': 'secure', - }, - }, - // mixed active content is blocked, priming will upgrade - // redirect to the same host - timeout: { - block_active: true, - block_display: true, - use_hsts: true, - send_hsts_priming: true, - type: 'script', - timeout: 100000, - result: { - 'no-ssl': 'blocked', - 'reject-upgrade': 'blocked', - 'prime-hsts': 'blocked', - }, - }, -} -// track which test we are on -var which_test = ""; - -/** - * A stream listener that just forwards all calls - */ -var StreamListener = function(subject) { - let channel = subject.QueryInterface(Ci.nsIHttpChannel); - let traceable = subject.QueryInterface(Ci.nsITraceableChannel); - - this.uri = channel.URI.asciiSpec; - this.listener = traceable.setNewListener(this); - return this; -}; - -// Next three methods are part of `nsIStreamListener` interface and are -// invoked by `nsIInputStreamPump.asyncRead`. -StreamListener.prototype.onDataAvailable = function(request, context, input, offset, count) { - if (request.status == Cr.NS_ERROR_ABORT) { - this.listener = null; - return Cr.NS_SUCCESS; - } - let listener = this.listener; - if (listener) { - try { - let rv = listener.onDataAvailable(request, context, input, offset, count); - if (rv != Cr.NS_ERROR_ABORT) { - // If the channel gets canceled, we sometimes get NS_ERROR_ABORT here. - // Anything else is an error. - return rv; - } - } catch (e) { - if (e != Cr.NS_ERROR_ABORT) { - return e; - } - } - } - return Cr.NS_SUCCESS; -}; - -// Next two methods implement `nsIRequestObserver` interface and are invoked -// by `nsIInputStreamPump.asyncRead`. -StreamListener.prototype.onStartRequest = function(request, context) { - if (request.status == Cr.NS_ERROR_ABORT) { - this.listener = null; - return Cr.NS_SUCCESS; - } - let listener = this.listener; - if (listener) { - try { - let rv = listener.onStartRequest(request, context); - if (rv != Cr.NS_ERROR_ABORT) { - // If the channel gets canceled, we sometimes get NS_ERROR_ABORT here. - // Anything else is an error. - return rv; - } - } catch (e) { - if (e != Cr.NS_ERROR_ABORT) { - return e; - } - } - } - return Cr.NS_SUCCESS; -}; - -// Called to signify the end of an asynchronous request. We only care to -// discover errors. -StreamListener.prototype.onStopRequest = function(request, context, status) { - if (status == Cr.NS_ERROR_ABORT) { - this.listener = null; - return Cr.NS_SUCCESS; - } - let listener = this.listener; - if (listener) { - try { - let rv = listener.onStopRequest(request, context, status); - if (rv != Cr.NS_ERROR_ABORT) { - // If the channel gets canceled, we sometimes get NS_ERROR_ABORT here. - // Anything else is an error. - return rv; - } - } catch (e) { - if (e != Cr.NS_ERROR_ABORT) { - return e; - } - } - } - return Cr.NS_SUCCESS; -}; - -var Observer = { - listeners: {}, - observe: function (subject, topic, data) { - switch (topic) { - case 'console-api-log-event': - return Observer.console_api_log_event(subject, topic, data); - case 'http-on-examine-response': - return Observer.http_on_examine_response(subject, topic, data); - case 'http-on-modify-request': - return Observer.http_on_modify_request(subject, topic, data); - } - throw "Can't handle topic "+topic; - }, - add_observers: function (services, include_on_modify = false) { - services.obs.addObserver(Observer, "console-api-log-event"); - services.obs.addObserver(Observer, "http-on-examine-response"); - services.obs.addObserver(Observer, "http-on-modify-request"); - }, - cleanup: function () { - this.listeners = {}; - }, - // When a load is blocked which results in an error event within a page, the - // test logs to the console. - console_api_log_event: function (subject, topic, data) { - var message = subject.wrappedJSObject.arguments[0]; - // when we are blocked, this will match the message we sent to the console, - // ignore everything else. - var re = RegExp(/^HSTS_PRIMING: Blocked ([-\w]+).*$/); - if (!re.test(message)) { - return; - } - - let id = message.replace(re, '$1'); - let curTest =test_servers[id]; - - if (!curTest) { - ok(false, "HSTS priming got a console message blocked, "+ - "but doesn't match expectations "+id+" (msg="+message); - return; - } - - is("blocked", test_settings[which_test].result[curTest.id], "HSTS priming "+ - which_test+":"+curTest.id+" expected "+ - test_settings[which_test].result[curTest.id]+", got blocked"); - test_settings[which_test].finished[curTest.id] = "blocked"; - }, - get_current_test: function(uri) { - for (let item in test_servers) { - let re = RegExp('https?://'+test_servers[item].host+'.*\/browser/dom/security/test/hsts/file_testserver.sjs'); - if (re.test(uri)) { - return test_servers[item]; - } - } - return null; - }, - http_on_modify_request: function (subject, topic, data) { - let channel = subject.QueryInterface(Ci.nsIHttpChannel); - let uri = channel.URI.asciiSpec; - - let curTest = this.get_current_test(channel.URI.asciiSpec); - - if (!curTest) { - return; - } - - if (!(uri in this.listeners)) { - // Add an nsIStreamListener to ensure that the listener is not NULL - this.listeners[uri] = new StreamListener(subject); - } - - if (channel.requestMethod != 'HEAD') { - return; - } - if (typeof ok === 'undefined') { - // we are in the wrong thread and ok and is not available - return; - } - ok(!(curTest.id in test_settings[which_test].priming), "Already saw a priming request for " + curTest.id); - test_settings[which_test].priming[curTest.id] = true; - }, - // When we see a response come back, peek at the response and test it is secure - // or insecure as needed. Addtionally, watch the response for priming requests. - http_on_examine_response: function (subject, topic, data) { - let channel = subject.QueryInterface(Ci.nsIHttpChannel); - let curTest = this.get_current_test(channel.URI.asciiSpec); - let uri = channel.URI.asciiSpec; - - if (!curTest) { - return; - } - - let result = (channel.URI.asciiSpec.startsWith('https:')) ? "secure" : "insecure"; - - // This is a priming request, go ahead and validate we were supposed to see - // a response from the server - if (channel.requestMethod == 'HEAD') { - is(true, curTest.response, "HSTS priming response found " + curTest.id); - return; - } - - // This is the response to our query, make sure it matches - is(result, test_settings[which_test].result[curTest.id], - "HSTS priming result " + which_test + ":" + curTest.id); - test_settings[which_test].finished[curTest.id] = result; - if (this.listeners[uri]) { - this.listeners[uri] = undefined; - } - }, -}; - -// opens `uri' in a new tab and focuses it. -// returns the newly opened tab -function openTab(uri) { - let tab = BrowserTestUtils.addTab(gBrowser, uri); - - // select tab and make sure its browser is focused - gBrowser.selectedTab = tab; - tab.ownerGlobal.focus(); - - return tab; -} - -function clear_sts_data() { - for (let test in test_servers) { - SpecialPowers.cleanUpSTSData('http://'+test_servers[test].host); - } -} - -var oldCanRecord = Services.telemetry.canRecordExtended; - -function do_cleanup() { - clear_sts_data(); - - Services.obs.removeObserver(Observer, "console-api-log-event"); - Services.obs.removeObserver(Observer, "http-on-examine-response"); - - Services.telemetry.canRecordExtended = oldCanRecord; - - Observer.cleanup(); -} - -function SetupPrefTestEnvironment(which, additional_prefs) { - which_test = which; - clear_sts_data(); - - var settings = test_settings[which]; - // priming counts how many priming requests we saw - settings.priming = {}; - // priming counts how many tests were finished - settings.finished= {}; - - var prefs = [["security.mixed_content.block_active_content", - settings.block_active], - ["security.mixed_content.block_display_content", - settings.block_display], - ["security.mixed_content.use_hsts", - settings.use_hsts], - ["security.mixed_content.send_hsts_priming", - settings.send_hsts_priming], - ]; - - if (additional_prefs) { - for (let idx in additional_prefs) { - prefs.push(additional_prefs[idx]); - } - } - - Services.telemetry.canRecordExtended = true; - - SpecialPowers.pushPrefEnv({'set': prefs}); -} - -// make the top-level test uri -function build_test_uri(base_uri, host, test_id, type, timeout) { - return base_uri + - "?host=" + escape(host) + - "&id=" + escape(test_id) + - "&type=" + escape(type) + - "&timeout=" + escape(timeout) - ; -} - -// open a new tab, load the test, and wait for it to finish -async function execute_test(test, mimetype) { - var src = build_test_uri(TOP_URI, test_servers[test].host, - test, test_settings[which_test].type, - test_settings[which_test].timeout); - - await BrowserTestUtils.withNewTab(src, () => {}); -} - -/* Expected should look something like this: - * The numbers are the sum of all telemetry values. - var expected_telemetry = { - "histograms": { - "MIXED_CONTENT_HSTS_PRIMING_RESULT": 6, - "HSTS_PRIMING_REQUESTS": 10, - "HSTS_UPGRADE_SOURCE": [ 0,0,2,0,0,0,0,0,0 ] - }, - "keyed-histograms": { - "HSTS_PRIMING_REQUEST_DURATION": { - "success": 1, - "failure": 2, - }, - } - }; - */ -function test_telemetry(expected) { - for (let key in expected['histograms']) { - let hs = undefined; - try { - let hist = Services.telemetry.getHistogramById(key); - hs = hist.snapshot(); - hist.clear(); - } catch(e) { - ok(false, "Caught exception trying to get histogram for key " + key + ":" + e); - continue; - } - - if (!hs) { - ok(false, "No histogram found for key " + key); - continue; - } - - if (Array.isArray(expected['histograms'][key])) { - var is_ok = true; - if (expected['histograms'][key].length != hs.counts.length) { - ok(false, "Histogram lengths match"); - continue; - } - - for (let idx in expected['histograms'][key]) { - is_ok = (hs.counts[idx] >= expected['histograms'][key][idx]); - if (!is_ok) { - break; - } - } - ok(is_ok, "Histogram counts match for " + key + " - Got " + hs.counts + ", expected " + expected['histograms'][key]); - } else { - // there may have been other background requests processed - ok(hs.counts.reduce(sum) >= expected['histograms'][key], "Histogram counts match expected, got " + hs.counts.reduce(sum) + ", expected at least " + expected['histograms'][key]); - } - } - - for (let key in expected['keyed-histograms']) { - let hs = undefined; - try { - let hist = Services.telemetry.getKeyedHistogramById(key); - hs = hist.snapshot(); - hist.clear(); - } catch(e) { - ok(false, "Caught exception trying to get histogram for key " + key + " :" + e); - continue; - } - - if (!hs) { - ok(false, "No keyed histogram found for key " + key); - continue; - } - - for (let hist_key in expected['keyed-histograms'][key]) { - ok(hist_key in hs, "Keyed histogram exists with key"); - if (hist_key in hs) { - ok(hs[hist_key].counts.reduce(sum) >= expected['keyed-histograms'][key][hist_key], "Keyed histogram counts match expected got " + hs[hist_key].counts.reduce(sum) + ", expected at least " + expected['keyed-histograms'][key][hist_key]) - } - } - } -} - -function sum(a, b) { - return a+b; -} - -function clear_hists(hists) { - for (let key in hists['histograms']) { - try { - let hist = Services.telemetry.getHistogramById(key); - hist.clear(); - } catch(e) { - continue; - } - } - - for (let key in hists['keyed-histograms']) { - try { - let hist = Services.telemetry.getKeyedHistogramById(key); - hist.clear(); - } catch(e) { - continue; - } - } -} diff --git a/dom/security/test/mixedcontentblocker/test_main.html b/dom/security/test/mixedcontentblocker/test_main.html index a7def4177d17..7b78ab3da0c6 100644 --- a/dom/security/test/mixedcontentblocker/test_main.html +++ b/dom/security/test/mixedcontentblocker/test_main.html @@ -162,9 +162,6 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=62178 } function startTest() { - // Set prefs to use mixed-content before HSTS - SpecialPowers.pushPrefEnv({'set': [["security.mixed_content.use_hsts", false], - ["security.mixed_content.send_hsts_priming", false]]}); //Set the first set of mixed content settings and increment the counter. changePrefs([], function() { //listen for a messages from the mixed content test harness diff --git a/dom/security/test/mixedcontentblocker/test_redirect.html b/dom/security/test/mixedcontentblocker/test_redirect.html index f4aeef3d9895..9a9789722b9c 100644 --- a/dom/security/test/mixedcontentblocker/test_redirect.html +++ b/dom/security/test/mixedcontentblocker/test_redirect.html @@ -36,13 +36,8 @@ function receiveMessage(event) { } function startTest() { - SpecialPowers.pushPrefEnv({ - 'set': [["security.mixed_content.use_hsts", false], - ["security.mixed_content.send_hsts_priming", false]] - }, function () { - let testframe = document.getElementById("testframe"); - testframe.src = PATH + "file_redirect.html"; - }); + let testframe = document.getElementById("testframe"); + testframe.src = PATH + "file_redirect.html"; } diff --git a/dom/security/test/moz.build b/dom/security/test/moz.build index 3729c01d3062..9bd9931be23a 100644 --- a/dom/security/test/moz.build +++ b/dom/security/test/moz.build @@ -31,5 +31,4 @@ BROWSER_CHROME_MANIFESTS += [ 'cors/browser.ini', 'csp/browser.ini', 'general/browser.ini', - 'hsts/browser.ini', ] diff --git a/image/imgLoader.cpp b/image/imgLoader.cpp index a9e1a3813f1d..41eab37de171 100644 --- a/image/imgLoader.cpp +++ b/image/imgLoader.cpp @@ -685,19 +685,6 @@ ShouldLoadCachedImage(imgRequest* aImgRequest, } } - bool sendPriming = false; - bool mixedContentWouldBlock = false; - rv = nsMixedContentBlocker::GetHSTSPrimingFromRequestingContext(contentLocation, - aLoadingContext, &sendPriming, &mixedContentWouldBlock); - if (NS_FAILED(rv)) { - return false; - } - if (sendPriming && mixedContentWouldBlock) { - // if either of the securty checks above would cause a priming request, we - // can't load this image from the cache, so go ahead and return false here - return false; - } - return true; } diff --git a/ipc/glue/BackgroundUtils.cpp b/ipc/glue/BackgroundUtils.cpp index 67f44c8e1137..ba6336f46cc0 100644 --- a/ipc/glue/BackgroundUtils.cpp +++ b/ipc/glue/BackgroundUtils.cpp @@ -398,11 +398,7 @@ LoadInfoToLoadInfoArgs(nsILoadInfo *aLoadInfo, aLoadInfo->GetForcePreflight(), aLoadInfo->GetIsPreflight(), aLoadInfo->GetLoadTriggeredFromExternal(), - aLoadInfo->GetServiceWorkerTaintingSynthesized(), - aLoadInfo->GetForceHSTSPriming(), - aLoadInfo->GetMixedContentWouldBlock(), - aLoadInfo->GetIsHSTSPriming(), - aLoadInfo->GetIsHSTSPrimingUpgrade() + aLoadInfo->GetServiceWorkerTaintingSynthesized() ); return NS_OK; @@ -508,11 +504,7 @@ LoadInfoArgsToLoadInfo(const OptionalLoadInfoArgs& aOptionalLoadInfoArgs, loadInfoArgs.forcePreflight(), loadInfoArgs.isPreflight(), loadInfoArgs.loadTriggeredFromExternal(), - loadInfoArgs.serviceWorkerTaintingSynthesized(), - loadInfoArgs.forceHSTSPriming(), - loadInfoArgs.mixedContentWouldBlock(), - loadInfoArgs.isHSTSPriming(), - loadInfoArgs.isHSTSPrimingUpgrade() + loadInfoArgs.serviceWorkerTaintingSynthesized() ); loadInfo.forget(outLoadInfo); diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js index 7dec0b267ac0..914ab1bdb151 100644 --- a/modules/libpref/init/all.js +++ b/modules/libpref/init/all.js @@ -5794,25 +5794,6 @@ pref("layout.css.servo.enabled", false); pref("layout.css.servo.chrome.enabled", false); #endif -// HSTS Priming -// If a request is mixed-content, send an HSTS priming request to attempt to -// see if it is available over HTTPS. -// Don't change the order of evaluation of mixed-content and HSTS upgrades in -// order to be most compatible with current standards in Release -pref("security.mixed_content.send_hsts_priming", false); -pref("security.mixed_content.use_hsts", false); -#ifdef EARLY_BETA_OR_EARLIER -// Change the order of evaluation so HSTS upgrades happen before -// mixed-content blocking -pref("security.mixed_content.send_hsts_priming", true); -pref("security.mixed_content.use_hsts", true); -#endif -// Approximately 1 week default cache for HSTS priming failures, in seconds -pref("security.mixed_content.hsts_priming_cache_timeout", 604800); -// Force the channel to timeout in 2 seconds if we have not received -// expects a time in milliseconds -pref("security.mixed_content.hsts_priming_request_timeout", 2000); - // TODO: Bug 1324406: Treat 'data:' documents as unique, opaque origins // If true, data: URIs will be treated as unique opaque origins, hence will use // a NullPrincipal as the security context. diff --git a/netwerk/base/LoadInfo.cpp b/netwerk/base/LoadInfo.cpp index 3bf17b4019ce..571d54857773 100644 --- a/netwerk/base/LoadInfo.cpp +++ b/netwerk/base/LoadInfo.cpp @@ -74,10 +74,6 @@ LoadInfo::LoadInfo(nsIPrincipal* aLoadingPrincipal, , mIsPreflight(false) , mLoadTriggeredFromExternal(false) , mServiceWorkerTaintingSynthesized(false) - , mForceHSTSPriming(false) - , mMixedContentWouldBlock(false) - , mIsHSTSPriming(false) - , mIsHSTSPrimingUpgrade(false) { MOZ_ASSERT(mLoadingPrincipal); MOZ_ASSERT(mTriggeringPrincipal); @@ -264,10 +260,6 @@ LoadInfo::LoadInfo(nsPIDOMWindowOuter* aOuterWindow, , mIsPreflight(false) , mLoadTriggeredFromExternal(false) , mServiceWorkerTaintingSynthesized(false) - , mForceHSTSPriming(false) - , mMixedContentWouldBlock(false) - , mIsHSTSPriming(false) - , mIsHSTSPrimingUpgrade(false) { // Top-level loads are never third-party // Grab the information we can out of the window. @@ -346,10 +338,6 @@ LoadInfo::LoadInfo(const LoadInfo& rhs) , mIsPreflight(rhs.mIsPreflight) , mLoadTriggeredFromExternal(rhs.mLoadTriggeredFromExternal) , mServiceWorkerTaintingSynthesized(rhs.mServiceWorkerTaintingSynthesized) - , mForceHSTSPriming(rhs.mForceHSTSPriming) - , mMixedContentWouldBlock(rhs.mMixedContentWouldBlock) - , mIsHSTSPriming(rhs.mIsHSTSPriming) - , mIsHSTSPrimingUpgrade(rhs.mIsHSTSPrimingUpgrade) { } @@ -383,11 +371,7 @@ LoadInfo::LoadInfo(nsIPrincipal* aLoadingPrincipal, bool aForcePreflight, bool aIsPreflight, bool aLoadTriggeredFromExternal, - bool aServiceWorkerTaintingSynthesized, - bool aForceHSTSPriming, - bool aMixedContentWouldBlock, - bool aIsHSTSPriming, - bool aIsHSTSPrimingUpgrade) + bool aServiceWorkerTaintingSynthesized) : mLoadingPrincipal(aLoadingPrincipal) , mTriggeringPrincipal(aTriggeringPrincipal) , mPrincipalToInherit(aPrincipalToInherit) @@ -416,10 +400,6 @@ LoadInfo::LoadInfo(nsIPrincipal* aLoadingPrincipal, , mIsPreflight(aIsPreflight) , mLoadTriggeredFromExternal(aLoadTriggeredFromExternal) , mServiceWorkerTaintingSynthesized(aServiceWorkerTaintingSynthesized) - , mForceHSTSPriming (aForceHSTSPriming) - , mMixedContentWouldBlock(aMixedContentWouldBlock) - , mIsHSTSPriming(aIsHSTSPriming) - , mIsHSTSPrimingUpgrade(aIsHSTSPrimingUpgrade) { // Only top level TYPE_DOCUMENT loads can have a null loadingPrincipal MOZ_ASSERT(mLoadingPrincipal || aContentPolicyType == nsIContentPolicy::TYPE_DOCUMENT); @@ -1068,66 +1048,6 @@ LoadInfo::GetServiceWorkerTaintingSynthesized(bool* aServiceWorkerTaintingSynthe return NS_OK; } -NS_IMETHODIMP -LoadInfo::GetForceHSTSPriming(bool* aForceHSTSPriming) -{ - *aForceHSTSPriming = mForceHSTSPriming; - return NS_OK; -} - -NS_IMETHODIMP -LoadInfo::GetMixedContentWouldBlock(bool *aMixedContentWouldBlock) -{ - *aMixedContentWouldBlock = mMixedContentWouldBlock; - return NS_OK; -} - -void -LoadInfo::SetHSTSPriming(bool aMixedContentWouldBlock) -{ - mForceHSTSPriming = true; - mMixedContentWouldBlock = aMixedContentWouldBlock; -} - -void -LoadInfo::ClearHSTSPriming() -{ - mForceHSTSPriming = false; - mMixedContentWouldBlock = false; -} - -NS_IMETHODIMP -LoadInfo::SetIsHSTSPriming(bool aIsHSTSPriming) -{ - MOZ_ASSERT(aIsHSTSPriming); - mIsHSTSPriming = aIsHSTSPriming; - return NS_OK; -} - -NS_IMETHODIMP -LoadInfo::GetIsHSTSPriming(bool* aIsHSTSPriming) -{ - MOZ_ASSERT(aIsHSTSPriming); - *aIsHSTSPriming = mIsHSTSPriming; - return NS_OK; -} - -NS_IMETHODIMP -LoadInfo::SetIsHSTSPrimingUpgrade(bool aIsHSTSPrimingUpgrade) -{ - MOZ_ASSERT(aIsHSTSPrimingUpgrade); - mIsHSTSPrimingUpgrade = aIsHSTSPrimingUpgrade; - return NS_OK; -} - -NS_IMETHODIMP -LoadInfo::GetIsHSTSPrimingUpgrade(bool* aIsHSTSPrimingUpgrade) -{ - MOZ_ASSERT(aIsHSTSPrimingUpgrade); - *aIsHSTSPrimingUpgrade = mIsHSTSPrimingUpgrade; - return NS_OK; -} - NS_IMETHODIMP LoadInfo::GetTainting(uint32_t* aTaintingOut) { diff --git a/netwerk/base/LoadInfo.h b/netwerk/base/LoadInfo.h index 36b2c18ad269..570384237fb4 100644 --- a/netwerk/base/LoadInfo.h +++ b/netwerk/base/LoadInfo.h @@ -124,11 +124,7 @@ private: bool aForcePreflight, bool aIsPreflight, bool aLoadTriggeredFromExternal, - bool aServiceWorkerTaintingSynthesized, - bool aForceHSTSPriming, - bool aMixedContentWouldBlock, - bool aIsHSTSPriming, - bool aIsHSTSPrimingUpgrade); + bool aServiceWorkerTaintingSynthesized); LoadInfo(const LoadInfo& rhs); NS_IMETHOD GetRedirects(JSContext* aCx, JS::MutableHandle aRedirects, @@ -190,11 +186,6 @@ private: bool mIsPreflight; bool mLoadTriggeredFromExternal; bool mServiceWorkerTaintingSynthesized; - - bool mForceHSTSPriming : 1; - bool mMixedContentWouldBlock : 1; - bool mIsHSTSPriming: 1; - bool mIsHSTSPrimingUpgrade: 1; }; } // namespace net diff --git a/netwerk/base/nsILoadInfo.idl b/netwerk/base/nsILoadInfo.idl index 3a0bda6f07e8..e55aed7af74f 100644 --- a/netwerk/base/nsILoadInfo.idl +++ b/netwerk/base/nsILoadInfo.idl @@ -744,42 +744,6 @@ interface nsILoadInfo : nsISupports */ [infallible] readonly attribute boolean isPreflight; - /** - * When this request would be mixed-content and we do not have an - * entry in the HSTS cache, we send an HSTS priming request to - * determine if it is ok to upgrade the request to HTTPS. - */ - /** - * True if this is a mixed-content load and HSTS priming request will be sent. - */ - [noscript, infallible] readonly attribute boolean forceHSTSPriming; - /** - * Carry the decision whether this load would be blocked by mixed content so - * that if HSTS priming fails, the correct decision can be made. - */ - [noscript, infallible] readonly attribute boolean mixedContentWouldBlock; - - /** - * True if this load is an HSTS priming request. - */ - [noscript, infallible] attribute boolean isHSTSPriming; - - /** - * True if this load was upgraded from HSTS priming - */ - [noscript, infallible] attribute boolean isHSTSPrimingUpgrade; - - /** - * Mark this LoadInfo as needing HSTS Priming - * - * @param wouldBlock Carry the decision of Mixed Content Blocking to be - * applied when HSTS priming is complete. - */ - [noscript, notxpcom, nostdcall] - void setHSTSPriming(in boolean mixeContentWouldBlock); - [noscript, notxpcom, nostdcall] - void clearHSTSPriming(); - /** * Constants reflecting the channel tainting. These are mainly defined here * for script. Internal C++ code should use the enum defined in LoadTainting.h. diff --git a/netwerk/base/nsNetUtil.cpp b/netwerk/base/nsNetUtil.cpp index 9cc62784d390..c57eadc7ddbc 100644 --- a/netwerk/base/nsNetUtil.cpp +++ b/netwerk/base/nsNetUtil.cpp @@ -2807,14 +2807,6 @@ NS_ShouldSecureUpgrade(nsIURI* aURI, aShouldUpgrade = true; return NS_OK; } - - if (aLoadInfo->GetForceHSTSPriming()) { - // don't log requests which might be upgraded due to HSTS Priming - // they get logged in nsHttpChannel::OnHSTSPrimingSucceeded or - // nsHttpChannel::OnHSTSPrimingFailed if the load is allowed to proceed. - aShouldUpgrade = false; - return NS_OK; - } } // enforce Strict-Transport-Security @@ -2844,9 +2836,6 @@ NS_ShouldSecureUpgrade(nsIURI* aURI, case nsISiteSecurityService::SOURCE_ORGANIC_REQUEST: Telemetry::Accumulate(Telemetry::HSTS_UPGRADE_SOURCE, 1); break; - case nsISiteSecurityService::SOURCE_HSTS_PRIMING: - Telemetry::Accumulate(Telemetry::HSTS_UPGRADE_SOURCE, 2); - break; case nsISiteSecurityService::SOURCE_UNKNOWN: default: // record this as an organic request @@ -2861,21 +2850,6 @@ NS_ShouldSecureUpgrade(nsIURI* aURI, Telemetry::Accumulate(Telemetry::HTTP_SCHEME_UPGRADE, 1); } } else { - if (aLoadInfo) { - if (aLoadInfo->GetIsHSTSPriming()) { - // don't log HSTS priming requests - aShouldUpgrade = false; - return NS_OK; - } - - if (aLoadInfo->GetIsHSTSPrimingUpgrade()) { - // if the upgrade occured due to HSTS priming, it was logged in - // nsHttpChannel::OnHSTSPrimingSucceeded before redirect - aShouldUpgrade = false; - return NS_OK; - } - } - Telemetry::Accumulate(Telemetry::HTTP_SCHEME_UPGRADE, 0); } aShouldUpgrade = false; diff --git a/netwerk/ipc/NeckoChannelParams.ipdlh b/netwerk/ipc/NeckoChannelParams.ipdlh index 149117368ae2..011b29c7e52d 100644 --- a/netwerk/ipc/NeckoChannelParams.ipdlh +++ b/netwerk/ipc/NeckoChannelParams.ipdlh @@ -73,10 +73,6 @@ struct LoadInfoArgs bool isPreflight; bool loadTriggeredFromExternal; bool serviceWorkerTaintingSynthesized; - bool forceHSTSPriming; - bool mixedContentWouldBlock; - bool isHSTSPriming; - bool isHSTSPrimingUpgrade; }; /** diff --git a/netwerk/protocol/http/HSTSPrimerListener.cpp b/netwerk/protocol/http/HSTSPrimerListener.cpp deleted file mode 100644 index 5652ceafbf58..000000000000 --- a/netwerk/protocol/http/HSTSPrimerListener.cpp +++ /dev/null @@ -1,396 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ -#include "HttpLog.h" - -#include "nsHttp.h" - -#include "HSTSPrimerListener.h" -#include "nsIHstsPrimingCallback.h" -#include "nsIPrincipal.h" -#include "nsSecurityHeaderParser.h" -#include "nsISiteSecurityService.h" -#include "nsISocketProvider.h" -#include "nsISSLStatus.h" -#include "nsISSLStatusProvider.h" -#include "nsStreamUtils.h" -#include "nsStreamListenerWrapper.h" -#include "nsHttpChannel.h" -#include "LoadInfo.h" -#include "mozilla/Unused.h" -#include "nsQueryObject.h" - -namespace mozilla { -namespace net { - -using namespace mozilla; - -NS_IMPL_ISUPPORTS(HSTSPrimingListener, nsIStreamListener, - nsIRequestObserver, nsIInterfaceRequestor, - nsITimerCallback, nsINamed) - -// default to 2000ms, same as the preference -// security.mixed_content.hsts_priming_request_timeout -uint32_t HSTSPrimingListener::sHSTSPrimingTimeout = 2000; - - -HSTSPrimingListener::HSTSPrimingListener(nsIHstsPrimingCallback* aCallback) - : mCallback(aCallback) -{ - static nsresult rv = - Preferences::AddUintVarCache(&sHSTSPrimingTimeout, - "security.mixed_content.hsts_priming_request_timeout"); - Unused << rv; -} - -NS_IMETHODIMP -HSTSPrimingListener::GetInterface(const nsIID & aIID, void **aResult) -{ - return QueryInterface(aIID, aResult); -} - -void -HSTSPrimingListener::ReportTiming(nsIHstsPrimingCallback* aCallback, nsresult aResult) -{ - nsCOMPtr timingChannel = - do_QueryInterface(aCallback); - if (!timingChannel) { - LOG(("HSTS priming: mCallback is not an nsITimedChannel!")); - return; - } - - TimeStamp channelCreationTime; - nsresult rv = timingChannel->GetChannelCreation(&channelCreationTime); - if (NS_SUCCEEDED(rv) && !channelCreationTime.IsNull()) { - PRUint32 interval = - (PRUint32) (TimeStamp::Now() - channelCreationTime).ToMilliseconds(); - Telemetry::Accumulate(Telemetry::HSTS_PRIMING_REQUEST_DURATION, - (NS_SUCCEEDED(aResult)) ? NS_LITERAL_CSTRING("success") - : NS_LITERAL_CSTRING("failure"), - interval); - } -} - -NS_IMETHODIMP -HSTSPrimingListener::OnStartRequest(nsIRequest *aRequest, - nsISupports *aContext) -{ - nsCOMPtr callback; - callback.swap(mCallback); - - if (mHSTSPrimingTimer) { - Unused << mHSTSPrimingTimer->Cancel(); - mHSTSPrimingTimer = nullptr; - } - - // if callback is null, we have already canceled this request and reported - // the failure - if (!callback) { - return NS_OK; - } - - nsresult primingResult = CheckHSTSPrimingRequestStatus(aRequest); - ReportTiming(callback, primingResult); - - if (NS_FAILED(primingResult)) { - LOG(("HSTS Priming Failed (request was not approved)")); - return callback->OnHSTSPrimingFailed(primingResult, false); - } - - LOG(("HSTS Priming Succeeded (request was approved)")); - return callback->OnHSTSPrimingSucceeded(false); -} - -NS_IMETHODIMP -HSTSPrimingListener::OnStopRequest(nsIRequest *aRequest, - nsISupports *aContext, - nsresult aStatus) -{ - return NS_OK; -} - -nsresult -HSTSPrimingListener::CheckHSTSPrimingRequestStatus(nsIRequest* aRequest) -{ - nsresult status; - nsresult rv = aRequest->GetStatus(&status); - NS_ENSURE_SUCCESS(rv, rv); - if (NS_FAILED(status)) { - return NS_ERROR_CONTENT_BLOCKED; - } - - // Test that things worked on a HTTP level - nsCOMPtr httpChannel = do_QueryInterface(aRequest); - NS_ENSURE_STATE(httpChannel); - nsCOMPtr internal = do_QueryInterface(aRequest); - NS_ENSURE_STATE(internal); - - bool succeedded; - rv = httpChannel->GetRequestSucceeded(&succeedded); - if (NS_FAILED(rv) || !succeedded) { - // If the request did not return a 2XX response, don't process it - return NS_ERROR_CONTENT_BLOCKED; - } - - bool synthesized = false; - RefPtr rawHttpChannel = do_QueryObject(httpChannel); - NS_ENSURE_STATE(rawHttpChannel); - - rv = rawHttpChannel->GetResponseSynthesized(&synthesized); - NS_ENSURE_SUCCESS(rv, rv); - if (synthesized) { - // Don't consider synthesized responses - return NS_ERROR_CONTENT_BLOCKED; - } - - // check to see if the HSTS cache was updated - nsCOMPtr sss = do_GetService(NS_SSSERVICE_CONTRACTID, &rv); - NS_ENSURE_SUCCESS(rv, rv); - - nsCOMPtr uri; - rv = httpChannel->GetURI(getter_AddRefs(uri)); - NS_ENSURE_SUCCESS(rv, rv); - NS_ENSURE_TRUE(uri, NS_ERROR_CONTENT_BLOCKED); - - OriginAttributes originAttributes; - NS_GetOriginAttributes(httpChannel, originAttributes); - - bool hsts; - rv = sss->IsSecureURI(nsISiteSecurityService::HEADER_HSTS, uri, 0, - originAttributes, nullptr, nullptr, &hsts); - NS_ENSURE_SUCCESS(rv, rv); - - if (hsts) { - // An HSTS upgrade was found - return NS_OK; - } - - // There is no HSTS upgrade available - return NS_ERROR_CONTENT_BLOCKED; -} - -/** nsIStreamListener methods **/ - -NS_IMETHODIMP -HSTSPrimingListener::OnDataAvailable(nsIRequest *aRequest, - nsISupports *ctxt, - nsIInputStream *inStr, - uint64_t sourceOffset, - uint32_t count) -{ - uint32_t totalRead; - return inStr->ReadSegments(NS_DiscardSegment, nullptr, count, &totalRead); -} - -/** nsITimerCallback **/ -NS_IMETHODIMP -HSTSPrimingListener::Notify(nsITimer* timer) -{ - nsresult rv; - nsCOMPtr callback; - callback.swap(mCallback); - if (!callback) { - // we already processed this channel - return NS_OK; - } - - ReportTiming(callback, NS_ERROR_HSTS_PRIMING_TIMEOUT); - - if (mPrimingChannel) { - rv = mPrimingChannel->Cancel(NS_ERROR_HSTS_PRIMING_TIMEOUT); - if (NS_FAILED(rv)) { - NS_ERROR("HSTS Priming timed out, and we got an error canceling the priming channel."); - } - } - - rv = callback->OnHSTSPrimingFailed(NS_ERROR_HSTS_PRIMING_TIMEOUT, false); - if (NS_FAILED(rv)) { - NS_ERROR("HSTS Priming timed out, and we got an error reporting the failure."); - } - - return NS_OK; // unused -} - -/** nsINamed **/ -NS_IMETHODIMP -HSTSPrimingListener::GetName(nsACString& aName) -{ - aName.AssignLiteral("HSTSPrimingListener"); - return NS_OK; -} - -// static -nsresult -HSTSPrimingListener::StartHSTSPriming(nsIChannel* aRequestChannel, - nsIHstsPrimingCallback* aCallback) -{ - nsCOMPtr finalChannelURI; - nsresult rv = NS_GetFinalChannelURI(aRequestChannel, getter_AddRefs(finalChannelURI)); - NS_ENSURE_SUCCESS(rv, rv); - - nsCOMPtr uri; - rv = NS_GetSecureUpgradedURI(finalChannelURI, getter_AddRefs(uri)); - NS_ENSURE_SUCCESS(rv,rv); - - // check the HSTS cache - bool hsts; - bool hstsCached; - nsCOMPtr sss = do_GetService(NS_SSSERVICE_CONTRACTID, &rv); - NS_ENSURE_SUCCESS(rv, rv); - - OriginAttributes originAttributes; - NS_GetOriginAttributes(aRequestChannel, originAttributes); - - rv = sss->IsSecureURI(nsISiteSecurityService::HEADER_HSTS, uri, 0, - originAttributes, &hstsCached, nullptr, &hsts); - NS_ENSURE_SUCCESS(rv, rv); - - if (hsts) { - // already saw this host and will upgrade if allowed by preferences - Telemetry::Accumulate(Telemetry::MIXED_CONTENT_HSTS_PRIMING_REQUESTS, - HSTSPrimingRequest::eHSTS_PRIMING_REQUEST_CACHED_HSTS); - return aCallback->OnHSTSPrimingSucceeded(true); - } - - if (hstsCached) { - // there is a non-expired entry in the cache that doesn't allow us to - // upgrade, so go ahead and fail early. - Telemetry::Accumulate(Telemetry::MIXED_CONTENT_HSTS_PRIMING_REQUESTS, - HSTSPrimingRequest::eHSTS_PRIMING_REQUEST_CACHED_NO_HSTS); - return aCallback->OnHSTSPrimingFailed(NS_ERROR_CONTENT_BLOCKED, true); - } - - // Either it wasn't cached or the cached result has expired. Build a - // channel for the HEAD request. - - nsCOMPtr originalLoadInfo = aRequestChannel->GetLoadInfo(); - MOZ_ASSERT(originalLoadInfo, "can not perform HSTS priming without a loadInfo"); - if (!originalLoadInfo) { - return NS_ERROR_FAILURE; - } - - nsCOMPtr loadInfo = static_cast - (originalLoadInfo.get())->CloneForNewRequest(); - loadInfo->SetIsHSTSPriming(true); - - // the LoadInfo must have a security flag set in order to pass through priming - // if none of these security flags are set, go ahead and fail now instead of - // crashing in nsContentSecurityManager::ValidateSecurityFlags - nsSecurityFlags securityMode = loadInfo->GetSecurityMode(); - if (securityMode != nsILoadInfo::SEC_REQUIRE_SAME_ORIGIN_DATA_INHERITS && - securityMode != nsILoadInfo::SEC_REQUIRE_SAME_ORIGIN_DATA_IS_BLOCKED && - securityMode != nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_INHERITS && - securityMode != nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL && - securityMode != nsILoadInfo::SEC_REQUIRE_CORS_DATA_INHERITS) { - return aCallback->OnHSTSPrimingFailed(NS_ERROR_CONTENT_BLOCKED, true); - } - - nsCOMPtr loadGroup; - rv = aRequestChannel->GetLoadGroup(getter_AddRefs(loadGroup)); - NS_ENSURE_SUCCESS(rv, rv); - - nsLoadFlags loadFlags; - rv = aRequestChannel->GetLoadFlags(&loadFlags); - NS_ENSURE_SUCCESS(rv, rv); - - loadFlags &= HttpBaseChannel::INHIBIT_CACHING | - HttpBaseChannel::INHIBIT_PERSISTENT_CACHING | - HttpBaseChannel::LOAD_BYPASS_CACHE | - HttpBaseChannel::LOAD_FROM_CACHE | - HttpBaseChannel::VALIDATE_ALWAYS; - // Priming requests should never be intercepted by service workers and - // are always anonymous. - loadFlags |= nsIChannel::LOAD_BYPASS_SERVICE_WORKER | - nsIRequest::LOAD_ANONYMOUS; - - // Create a new channel to send the priming request - nsCOMPtr primingChannel; - rv = NS_NewChannelInternal(getter_AddRefs(primingChannel), - uri, - loadInfo, - loadGroup, - nullptr, // aCallbacks are set later - loadFlags); - NS_ENSURE_SUCCESS(rv, rv); - - // Set method and headers - nsCOMPtr httpChannel = do_QueryInterface(primingChannel); - if (!httpChannel) { - NS_ERROR("HSTSPrimingListener: Failed to QI to nsIHttpChannel!"); - return NS_ERROR_FAILURE; - } - nsCOMPtr internal = do_QueryInterface(primingChannel); - NS_ENSURE_STATE(internal); - - // Since this is a perfomrance critical request (blocks the page load) we - // want to get the response ASAP. - nsCOMPtr classOfService(do_QueryInterface(primingChannel)); - if (classOfService) { - classOfService->AddClassFlags(nsIClassOfService::UrgentStart); - } - - // Currently using HEAD per the draft, but under discussion to change to GET - // with credentials so if the upgrade is approved the result is already cached. - rv = httpChannel->SetRequestMethod(NS_LITERAL_CSTRING("HEAD")); - NS_ENSURE_SUCCESS(rv, rv); - - rv = httpChannel-> - SetRequestHeader(NS_LITERAL_CSTRING("Upgrade-Insecure-Requests"), - NS_LITERAL_CSTRING("1"), false); - NS_ENSURE_SUCCESS(rv, rv); - - // attempt to set the class of service flags on the new channel - nsCOMPtr requestClass = do_QueryInterface(aRequestChannel); - if (!requestClass) { - NS_ERROR("HSTSPrimingListener: aRequestChannel is not an nsIClassOfService"); - return NS_ERROR_FAILURE; - } - nsCOMPtr primingClass = do_QueryInterface(httpChannel); - if (!primingClass) { - NS_ERROR("HSTSPrimingListener: httpChannel is not an nsIClassOfService"); - return NS_ERROR_FAILURE; - } - - uint32_t classFlags = 0; - rv = requestClass ->GetClassFlags(&classFlags); - NS_ENSURE_SUCCESS(rv, rv); - rv = primingClass->SetClassFlags(classFlags); - NS_ENSURE_SUCCESS(rv, rv); - - // The priming channel should have highest priority so that it completes as - // quickly as possible, allowing the load to proceed. - nsCOMPtr p = do_QueryInterface(primingChannel); - if (p) { - uint32_t priority = nsISupportsPriority::PRIORITY_HIGHEST; - - p->SetPriority(priority); - } - - // Set up listener which will start the original channel - HSTSPrimingListener* listener = new HSTSPrimingListener(aCallback); - // Start priming - rv = primingChannel->AsyncOpen2(listener); - NS_ENSURE_SUCCESS(rv, rv); - listener->mPrimingChannel.swap(primingChannel); - - nsCOMPtr timer; - rv = NS_NewTimerWithCallback(getter_AddRefs(timer), - listener, - sHSTSPrimingTimeout, - nsITimer::TYPE_ONE_SHOT); - if (NS_FAILED(rv)) { - NS_ERROR("HSTS Priming failed to initialize channel cancellation timer"); - } - - listener->mHSTSPrimingTimer.swap(timer); - - Telemetry::Accumulate(Telemetry::MIXED_CONTENT_HSTS_PRIMING_REQUESTS, - HSTSPrimingRequest::eHSTS_PRIMING_REQUEST_SENT); - - return NS_OK; -} - -} // namespace net -} // namespace mozilla diff --git a/netwerk/protocol/http/HSTSPrimerListener.h b/netwerk/protocol/http/HSTSPrimerListener.h deleted file mode 100644 index 11ec69069a00..000000000000 --- a/netwerk/protocol/http/HSTSPrimerListener.h +++ /dev/null @@ -1,162 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -#ifndef HSTSPrimingListener_h__ -#define HSTSPrimingListener_h__ - -#include "nsCOMPtr.h" -#include "nsIChannelEventSink.h" -#include "nsIInterfaceRequestor.h" -#include "nsINamed.h" -#include "nsIStreamListener.h" -#include "nsIThreadRetargetableStreamListener.h" -#include "nsITimer.h" - -#include "mozilla/Attributes.h" - -class nsIPrincipal; -class nsINetworkInterceptController; -class nsIHstsPrimingCallback; - -namespace mozilla { -namespace net { - -class HttpChannelParent; -class nsHttpChannel; - -/* - * How often do we send an HSTS priming request (over all requests) - */ -enum HSTSPrimingRequest { - // No HSTS priming request. The request is not mixed-content, or we have - // already cached the result before nsMixedContentBlocker::ShouldLoad - eHSTS_PRIMING_NO_REQUEST = 0, - // Sent an HSTS priming request - eHSTS_PRIMING_REQUEST_SENT = 1, - // Channel marked for priming, but already had a cached result - eHSTS_PRIMING_REQUEST_CACHED_HSTS = 2, - // Channel marked for priming, but already had a cached result - eHSTS_PRIMING_REQUEST_CACHED_NO_HSTS = 3, - // An error occured setting up the the priming request channel. If the - // priming channel failed in OnstopRequest, there is no HSTS, or the - // channel is redirected, that is recorded by - // MIXED_CONTENT_HSTS_PRIMING_RESULT. - eHSTS_PRIMING_REQUEST_ERROR = 4, - // The channel had no load info, so is ineligible for priming - eHSTS_PRIMING_REQUEST_NO_LOAD_INFO = 5, - // The request was marked for HSTS priming, but was upgraded by - // NS_ShouldSecureUpgrade before HSTS priming was sent. - eHSTS_PRIMING_REQUEST_ALREADY_UPGRADED = 6, -}; - -/* - * How often do we get back an HSTS priming result which upgrades the connection to HTTPS? - */ -enum HSTSPrimingResult { - // This site has been seen before and won't be upgraded - eHSTS_PRIMING_CACHED_NO_UPGRADE = 0, - // This site has been seen before and will be upgraded - eHSTS_PRIMING_CACHED_DO_UPGRADE = 1, - // This site has been seen before and will be blocked - eHSTS_PRIMING_CACHED_BLOCK = 2, - // The request was already upgraded, probably through - // upgrade-insecure-requests - eHSTS_PRIMING_ALREADY_UPGRADED = 3, - // HSTS priming is successful and the connection will be upgraded to HTTPS - eHSTS_PRIMING_SUCCEEDED = 4, - // When priming succeeds, but preferences require preservation of the order - // of mixed-content and hsts, and mixed-content blocks the load - eHSTS_PRIMING_SUCCEEDED_BLOCK = 5, - // When priming succeeds, but preferences require preservation of the order - // of mixed-content and hsts, and mixed-content allows the load over http - eHSTS_PRIMING_SUCCEEDED_HTTP = 6, - // HSTS priming failed, and the load is blocked by mixed-content - eHSTS_PRIMING_FAILED_BLOCK = 7, - // HSTS priming failed, and the load is allowed by mixed-content - eHSTS_PRIMING_FAILED_ACCEPT = 8, - // The HSTS Priming request timed out, and the load is blocked by - // mixed-content - eHSTS_PRIMING_TIMEOUT_BLOCK = 9, - // The HSTS Priming request timed out, and the load is allowed by - // mixed-content - eHSTS_PRIMING_TIMEOUT_ACCEPT = 10, -}; - -////////////////////////////////////////////////////////////////////////// -// Class used as streamlistener and notification callback when -// doing the HEAD request for an HSTS Priming check. Needs to be an -// nsIStreamListener in order to receive events from AsyncOpen2 -class HSTSPrimingListener final : public nsIStreamListener, - public nsIInterfaceRequestor, - public nsITimerCallback, - public nsINamed -{ -public: - explicit HSTSPrimingListener(nsIHstsPrimingCallback* aCallback); - - NS_DECL_ISUPPORTS - NS_DECL_NSISTREAMLISTENER - NS_DECL_NSIREQUESTOBSERVER - NS_DECL_NSIINTERFACEREQUESTOR - NS_DECL_NSITIMERCALLBACK - NS_DECL_NSINAMED - -private: - ~HSTSPrimingListener() {} - - // Only nsHttpChannel can invoke HSTS priming - friend class mozilla::net::nsHttpChannel; - - /** - * Start the HSTS priming request. This will send an anonymous HEAD request to - * the URI aRequestChannel is attempting to load. On success, the new HSTS - * priming channel is allocated in aHSTSPrimingChannel. - * - * @param aRequestChannel the reference channel used to initialze the HSTS - * priming channel - * @param aCallback the callback stored to handle the results of HSTS priming. - * @param aHSTSPrimingChannel if the new HSTS priming channel is allocated - * successfully, it will be placed here. - */ - static nsresult StartHSTSPriming(nsIChannel* aRequestChannel, - nsIHstsPrimingCallback* aCallback); - - /** - * Given a request, return NS_OK if it has resulted in a cached HSTS update. - * We don't need to check for the header as that has already been done for us. - */ - nsresult CheckHSTSPrimingRequestStatus(nsIRequest* aRequest); - - // send telemetry about how long HSTS priming requests take - void ReportTiming(nsIHstsPrimingCallback* aCallback, nsresult aResult); - - /** - * the nsIHttpChannel to notify with the result of HSTS priming. - */ - nsCOMPtr mCallback; - - /** - * Keep a handle to the priming channel so we can cancel it on timeout - */ - nsCOMPtr mPrimingChannel; - - /** - * Keep a handle to the timer around so it can be canceled if we don't time - * out. - */ - nsCOMPtr mHSTSPrimingTimer; - - /** - * How long (in ms) before an HSTS Priming channel times out. - * Preference: security.mixed_content.hsts_priming_request_timeout - */ - static uint32_t sHSTSPrimingTimeout; -}; - - -}} // mozilla::net - -#endif // HSTSPrimingListener_h__ diff --git a/netwerk/protocol/http/HttpChannelChild.cpp b/netwerk/protocol/http/HttpChannelChild.cpp index bf9a32d159d1..b69402c478ba 100644 --- a/netwerk/protocol/http/HttpChannelChild.cpp +++ b/netwerk/protocol/http/HttpChannelChild.cpp @@ -2143,8 +2143,8 @@ NS_IMETHODIMP HttpChannelChild::OnRedirectVerifyCallback(nsresult result) { LOG(("HttpChannelChild::OnRedirectVerifyCallback [this=%p]\n", this)); - nsresult rv; OptionalURIParams redirectURI; + nsresult rv; uint32_t referrerPolicy = REFERRER_POLICY_UNSET; OptionalURIParams referrerURI; @@ -2164,19 +2164,10 @@ HttpChannelChild::OnRedirectVerifyCallback(nsresult result) result = NS_ERROR_DOM_BAD_URI; } - bool forceHSTSPriming = false; - bool mixedContentWouldBlock = false; if (newHttpChannel) { // Must not be called until after redirect observers called. newHttpChannel->SetOriginalURI(mOriginalURI); - nsCOMPtr newLoadInfo; - rv = newHttpChannel->GetLoadInfo(getter_AddRefs(newLoadInfo)); - if (NS_SUCCEEDED(rv) && newLoadInfo) { - forceHSTSPriming = newLoadInfo->GetForceHSTSPriming(); - mixedContentWouldBlock = newLoadInfo->GetMixedContentWouldBlock(); - } - rv = newHttpChannel->GetReferrerPolicy(&referrerPolicy); MOZ_ASSERT(NS_SUCCEEDED(rv)); nsCOMPtr newChannelReferrerURI; @@ -2242,7 +2233,7 @@ HttpChannelChild::OnRedirectVerifyCallback(nsresult result) do_QueryInterface(mRedirectChannelChild); if (newHttpChannelInternal) { nsCOMPtr apiRedirectURI; - nsresult rv = newHttpChannelInternal->GetApiRedirectToURI( + rv = newHttpChannelInternal->GetApiRedirectToURI( getter_AddRefs(apiRedirectURI)); if (NS_SUCCEEDED(rv) && apiRedirectURI) { /* If there was an API redirect of this channel, we need to send it @@ -2269,7 +2260,7 @@ HttpChannelChild::OnRedirectVerifyCallback(nsresult result) if (mIPCOpen) SendRedirect2Verify(result, *headerTuples, loadFlags, referrerPolicy, referrerURI, redirectURI, corsPreflightArgs, - forceHSTSPriming, mixedContentWouldBlock, chooseAppcache); + chooseAppcache); return NS_OK; } diff --git a/netwerk/protocol/http/HttpChannelParent.cpp b/netwerk/protocol/http/HttpChannelParent.cpp index 423bc6acfbdc..3620981ef1c3 100644 --- a/netwerk/protocol/http/HttpChannelParent.cpp +++ b/netwerk/protocol/http/HttpChannelParent.cpp @@ -954,8 +954,6 @@ HttpChannelParent::RecvRedirect2Verify(const nsresult& result, const OptionalURIParams& aReferrerURI, const OptionalURIParams& aAPIRedirectURI, const OptionalCorsPreflightArgs& aCorsPreflightArgs, - const bool& aForceHSTSPriming, - const bool& aMixedContentWouldBlock, const bool& aChooseAppcache) { LOG(("HttpChannelParent::RecvRedirect2Verify [this=%p result=%" PRIx32 "]\n", @@ -998,14 +996,6 @@ HttpChannelParent::RecvRedirect2Verify(const nsresult& result, newInternalChannel->SetCorsPreflightParameters(args.unsafeHeaders()); } - if (aForceHSTSPriming) { - nsCOMPtr newLoadInfo; - rv = newHttpChannel->GetLoadInfo(getter_AddRefs(newLoadInfo)); - if (NS_SUCCEEDED(rv) && newLoadInfo) { - newLoadInfo->SetHSTSPriming(aMixedContentWouldBlock); - } - } - nsCOMPtr referrerUri = DeserializeURI(aReferrerURI); rv = newHttpChannel->SetReferrerWithPolicy(referrerUri, referrerPolicy); MOZ_ASSERT(NS_SUCCEEDED(rv)); diff --git a/netwerk/protocol/http/HttpChannelParent.h b/netwerk/protocol/http/HttpChannelParent.h index bb0e188408fc..fb76a8662387 100644 --- a/netwerk/protocol/http/HttpChannelParent.h +++ b/netwerk/protocol/http/HttpChannelParent.h @@ -188,8 +188,6 @@ protected: const OptionalURIParams& aReferrerURI, const OptionalURIParams& apiRedirectUri, const OptionalCorsPreflightArgs& aCorsPreflightArgs, - const bool& aForceHSTSPriming, - const bool& aMixedContentWouldBlock, const bool& aChooseAppcache) override; virtual mozilla::ipc::IPCResult RecvUpdateAssociatedContentSecurity(const int32_t& broken, const int32_t& no) override; diff --git a/netwerk/protocol/http/InterceptedHttpChannel.cpp b/netwerk/protocol/http/InterceptedHttpChannel.cpp index c7fdd26de3e3..188ed1a172ba 100644 --- a/netwerk/protocol/http/InterceptedHttpChannel.cpp +++ b/netwerk/protocol/http/InterceptedHttpChannel.cpp @@ -7,6 +7,7 @@ #include "InterceptedHttpChannel.h" #include "nsContentSecurityManager.h" #include "nsEscape.h" +#include "mozilla/dom/Performance.h" namespace mozilla { namespace net { diff --git a/netwerk/protocol/http/PHttpChannel.ipdl b/netwerk/protocol/http/PHttpChannel.ipdl index 9d2cf33e41ff..a6543027eeac 100644 --- a/netwerk/protocol/http/PHttpChannel.ipdl +++ b/netwerk/protocol/http/PHttpChannel.ipdl @@ -47,7 +47,6 @@ parent: OptionalURIParams referrerUri, OptionalURIParams apiRedirectTo, OptionalCorsPreflightArgs corsPreflightArgs, - bool forceHSTSPriming, bool mixedContentWouldBlock, bool chooseAppcache); // For document loads we keep this protocol open after child's diff --git a/netwerk/protocol/http/moz.build b/netwerk/protocol/http/moz.build index fab7a40cf180..dbe5dfec4885 100644 --- a/netwerk/protocol/http/moz.build +++ b/netwerk/protocol/http/moz.build @@ -9,7 +9,6 @@ with Files('**'): XPIDL_SOURCES += [ 'nsIBackgroundChannelRegistrar.idl', - 'nsIHstsPrimingCallback.idl', 'nsIHttpActivityObserver.idl', 'nsIHttpAuthenticableChannel.idl', 'nsIHttpAuthenticator.idl', @@ -64,7 +63,6 @@ UNIFIED_SOURCES += [ 'BackgroundChannelRegistrar.cpp', 'CacheControlParser.cpp', 'ConnectionDiagnostics.cpp', - 'HSTSPrimerListener.cpp', 'Http2Compression.cpp', 'Http2Push.cpp', 'Http2Session.cpp', diff --git a/netwerk/protocol/http/nsHttpChannel.cpp b/netwerk/protocol/http/nsHttpChannel.cpp index 7a30b879f8a8..b1b80b8d3137 100644 --- a/netwerk/protocol/http/nsHttpChannel.cpp +++ b/netwerk/protocol/http/nsHttpChannel.cpp @@ -104,7 +104,6 @@ #include "mozilla/MathAlgorithms.h" #include "CacheControlParser.h" #include "nsMixedContentBlocker.h" -#include "HSTSPrimerListener.h" #include "CacheStorageService.h" #include "HttpChannelParent.h" #include "InterceptedHttpChannel.h" @@ -590,7 +589,7 @@ nsHttpChannel::ConnectOnTailUnblock() // Someone has called TriggerNetwork(), meaning we are racing the // network with the cache. mWaitingForProxy = false; - return TryHSTSPriming(); + return ContinueConnect(); } return NS_OK; @@ -630,70 +629,6 @@ nsHttpChannel::ConnectOnTailUnblock() return TriggerNetwork(); } -nsresult -nsHttpChannel::TryHSTSPriming() -{ - bool isHttpScheme; - nsresult rv = mURI->SchemeIs("http", &isHttpScheme); - NS_ENSURE_SUCCESS(rv, rv); - bool isHttpsScheme; - rv = mURI->SchemeIs("https", &isHttpsScheme); - NS_ENSURE_SUCCESS(rv, rv); - - if ((isHttpScheme || isHttpsScheme) && mLoadInfo) { - if (mLoadInfo->GetIsHSTSPriming()) { - // shortcut priming requests so they don't get counted - return ContinueConnect(); - } - - // HSTS priming requires the LoadInfo provided with AsyncOpen2 - bool requireHSTSPriming = - mLoadInfo->GetForceHSTSPriming(); - - if (requireHSTSPriming && - nsMixedContentBlocker::sSendHSTSPriming) { - if (!isHttpsScheme) { - rv = HSTSPrimingListener::StartHSTSPriming(this, this); - - if (NS_FAILED(rv)) { - CloseCacheEntry(false); - Telemetry::Accumulate(Telemetry::MIXED_CONTENT_HSTS_PRIMING_REQUESTS, - HSTSPrimingRequest::eHSTS_PRIMING_REQUEST_ERROR); - return rv; - } - - return NS_OK; - } - - if (!mLoadInfo->GetIsHSTSPrimingUpgrade()) { - // The request was already upgraded, for example by a prior - // successful priming request - LOG(("HSTS Priming: request already upgraded")); - Telemetry::Accumulate(Telemetry::MIXED_CONTENT_HSTS_PRIMING_RESULT, - HSTSPrimingResult::eHSTS_PRIMING_ALREADY_UPGRADED); - - // No HSTS Priming request was sent. - Telemetry::Accumulate(Telemetry::MIXED_CONTENT_HSTS_PRIMING_REQUESTS, - HSTSPrimingRequest::eHSTS_PRIMING_REQUEST_ALREADY_UPGRADED); - } - - mLoadInfo->ClearHSTSPriming(); - return ContinueConnect(); - } - - if (!mLoadInfo->GetIsHSTSPrimingUpgrade()) { - // No HSTS Priming request was sent, and we didn't already record this request - Telemetry::Accumulate(Telemetry::MIXED_CONTENT_HSTS_PRIMING_REQUESTS, - HSTSPrimingRequest::eHSTS_PRIMING_NO_REQUEST); - } - } else { - Telemetry::Accumulate(Telemetry::MIXED_CONTENT_HSTS_PRIMING_REQUESTS, - HSTSPrimingRequest::eHSTS_PRIMING_REQUEST_NO_LOAD_INFO); - } - - return ContinueConnect(); -} - // nsIInputAvailableCallback (nsIStreamTransportService.idl) NS_IMETHODIMP nsHttpChannel::OnInputAvailableComplete(uint64_t size, nsresult status) @@ -761,8 +696,6 @@ nsHttpChannel::ContinueConnect() return NS_OK; } - // If we have had HSTS priming, we need to reevaluate whether we need - // a CORS preflight. Bug: 1272440 // If we need to start a CORS preflight, do it now! // Note that it is important to do this before the early returns below. if (!mIsCorsPreflightDone && mRequireCORSPreflight) { @@ -1898,9 +1831,6 @@ nsHttpChannel::ProcessSingleSecurityHeader(uint32_t aType, NS_GetOriginAttributes(this, originAttributes); uint32_t failureResult; uint32_t headerSource = nsISiteSecurityService::SOURCE_ORGANIC_REQUEST; - if (mLoadInfo && mLoadInfo->GetIsHSTSPriming()) { - headerSource = nsISiteSecurityService::SOURCE_HSTS_PRIMING; - } rv = sss->ProcessHeader(aType, mURI, securityHeader, aSSLStatus, aFlags, headerSource, originAttributes, nullptr, nullptr, &failureResult); @@ -5874,7 +5804,6 @@ NS_INTERFACE_MAP_BEGIN(nsHttpChannel) NS_INTERFACE_MAP_ENTRY(nsICorsPreflightCallback) NS_INTERFACE_MAP_ENTRY(nsIRaceCacheWithNetwork) NS_INTERFACE_MAP_ENTRY(nsITimerCallback) - NS_INTERFACE_MAP_ENTRY(nsIHstsPrimingCallback) NS_INTERFACE_MAP_ENTRY(nsIChannelWithDivertableParentListener) NS_INTERFACE_MAP_ENTRY(nsIRequestTailUnblockCallback) // we have no macro that covers this case. @@ -8663,131 +8592,6 @@ nsHttpChannel::OnPreflightFailed(nsresult aError) return NS_OK; } -//----------------------------------------------------------------------------- -// nsIHstsPrimingCallback functions -//----------------------------------------------------------------------------- - -/* - * May be invoked synchronously if HSTS priming has already been performed - * for the host. - */ -nsresult -nsHttpChannel::OnHSTSPrimingSucceeded(bool aCached) -{ - // If "security.mixed_content.use_hsts" is false, record the result of - // HSTS priming and block or proceed with the load as required by - // mixed-content blocking - bool wouldBlock = mLoadInfo->GetMixedContentWouldBlock(); - // Clear out the HSTS priming flags on the LoadInfo to simplify the logic in - // TryHSTSPriming() - mLoadInfo->ClearHSTSPriming(); - - if (nsMixedContentBlocker::sUseHSTS) { - // redirect the channel to HTTPS if the pref - // "security.mixed_content.use_hsts" is true - LOG(("HSTS Priming succeeded, redirecting to HTTPS [this=%p]", this)); - Telemetry::Accumulate(Telemetry::MIXED_CONTENT_HSTS_PRIMING_RESULT, - (aCached) ? HSTSPrimingResult::eHSTS_PRIMING_CACHED_DO_UPGRADE : - HSTSPrimingResult::eHSTS_PRIMING_SUCCEEDED); - // we have to record this upgrade here since we have already - // been through NS_ShouldSecureUpgrade - Telemetry::Accumulate(Telemetry::HTTP_SCHEME_UPGRADE, 3); - Telemetry::Accumulate(Telemetry::HSTS_UPGRADE_SOURCE, 2); - mLoadInfo->SetIsHSTSPrimingUpgrade(true); - return AsyncCall(&nsHttpChannel::HandleAsyncRedirectChannelToHttps); - } - - // preserve the mixed-content-before-hsts order and block if required - if (wouldBlock) { - LOG(("HSTS Priming succeeded, blocking for mixed-content [this=%p]", - this)); - Telemetry::Accumulate(Telemetry::MIXED_CONTENT_HSTS_PRIMING_RESULT, - HSTSPrimingResult::eHSTS_PRIMING_SUCCEEDED_BLOCK); - CloseCacheEntry(false); - return AsyncAbort(NS_ERROR_CONTENT_BLOCKED); - } - - LOG(("HSTS Priming succeeded, loading insecure: [this=%p]", this)); - Telemetry::Accumulate(Telemetry::MIXED_CONTENT_HSTS_PRIMING_RESULT, - HSTSPrimingResult::eHSTS_PRIMING_SUCCEEDED_HTTP); - - // log HTTP_SCHEME_UPGRADE telemetry - Telemetry::Accumulate(Telemetry::HTTP_SCHEME_UPGRADE, 0); - - nsresult rv = ContinueConnect(); - if (NS_FAILED(rv)) { - CloseCacheEntry(false); - return AsyncAbort(rv); - } - - return NS_OK; -} - -/* - * May be invoked synchronously if HSTS priming has already been performed - * for the host. - */ -nsresult -nsHttpChannel::OnHSTSPrimingFailed(nsresult aError, bool aCached) -{ - bool wouldBlock = mLoadInfo->GetMixedContentWouldBlock(); - // Clear out the HSTS priming flags on the LoadInfo to simplify the logic in - // TryHSTSPriming() - mLoadInfo->ClearHSTSPriming(); - - LOG(("HSTS Priming Failed [this=%p], %s the load", this, - (wouldBlock) ? "blocking" : "allowing")); - if (aError == NS_ERROR_HSTS_PRIMING_TIMEOUT) { - // A priming request was sent, but timed out - Telemetry::Accumulate(Telemetry::MIXED_CONTENT_HSTS_PRIMING_RESULT, - (wouldBlock) ? HSTSPrimingResult::eHSTS_PRIMING_TIMEOUT_BLOCK : - HSTSPrimingResult::eHSTS_PRIMING_TIMEOUT_ACCEPT); - } else if (aCached) { - // Between the time we marked for priming and started the priming request, - // the host was found to not allow the upgrade, probably from another - // priming request. - Telemetry::Accumulate(Telemetry::MIXED_CONTENT_HSTS_PRIMING_RESULT, - (wouldBlock) ? HSTSPrimingResult::eHSTS_PRIMING_CACHED_BLOCK : - HSTSPrimingResult::eHSTS_PRIMING_CACHED_NO_UPGRADE); - } else { - // A priming request was sent, and no HSTS header was found that allows - // the upgrade. - Telemetry::Accumulate(Telemetry::MIXED_CONTENT_HSTS_PRIMING_RESULT, - (wouldBlock) ? HSTSPrimingResult::eHSTS_PRIMING_FAILED_BLOCK : - HSTSPrimingResult::eHSTS_PRIMING_FAILED_ACCEPT); - } - - // Don't visit again for at least - // security.mixed_content.hsts_priming_cache_timeout seconds. - nsISiteSecurityService* sss = gHttpHandler->GetSSService(); - NS_ENSURE_TRUE(sss, NS_ERROR_OUT_OF_MEMORY); - OriginAttributes originAttributes; - NS_GetOriginAttributes(this, originAttributes); - nsresult rv = sss->CacheNegativeHSTSResult(mURI, - nsMixedContentBlocker::sHSTSPrimingCacheTimeout, originAttributes); - if (NS_FAILED(rv)) { - NS_ERROR("nsISiteSecurityService::CacheNegativeHSTSResult failed"); - } - - // If we would block, go ahead and abort with the error provided - if (wouldBlock) { - CloseCacheEntry(false); - return AsyncAbort(aError); - } - - // log HTTP_SCHEME_UPGRADE telemetry - Telemetry::Accumulate(Telemetry::HTTP_SCHEME_UPGRADE, 0); - - // we can continue the load and the UI has been updated as mixed content - rv = ContinueConnect(); - if (NS_FAILED(rv)) { - CloseCacheEntry(false); - return AsyncAbort(rv); - } - - return NS_OK; -} - //----------------------------------------------------------------------------- // AChannelHasDivertableParentChannelAsListener internal functions //----------------------------------------------------------------------------- @@ -9287,8 +9091,8 @@ nsHttpChannel::TriggerNetwork() // If we are waiting for a proxy request, that means we can't trigger // the next step just yet. We need for mConnectionInfo to be non-null - // before we call TryHSTSPriming. OnProxyAvailable will trigger - // BeginConnect, and Connect will call TryHSTSPriming even if it's + // before we call ContinueConnect. OnProxyAvailable will trigger + // BeginConnect, and Connect will call ContinueConnect even if it's // for the cache callbacks. if (mProxyRequest) { LOG((" proxy request in progress. Delaying network trigger.\n")); @@ -9301,7 +9105,7 @@ nsHttpChannel::TriggerNetwork() } LOG((" triggering network\n")); - return TryHSTSPriming(); + return ContinueConnect(); } nsresult diff --git a/netwerk/protocol/http/nsHttpChannel.h b/netwerk/protocol/http/nsHttpChannel.h index f48cc1a78758..a74742e35f61 100644 --- a/netwerk/protocol/http/nsHttpChannel.h +++ b/netwerk/protocol/http/nsHttpChannel.h @@ -29,7 +29,6 @@ #include "nsISupportsPrimitives.h" #include "nsICorsPreflightCallback.h" #include "AlternateServices.h" -#include "nsIHstsPrimingCallback.h" #include "nsIRaceCacheWithNetwork.h" #include "mozilla/extensions/PStreamFilterParent.h" #include "mozilla/Mutex.h" @@ -84,7 +83,6 @@ class nsHttpChannel final : public HttpBaseChannel , public nsSupportsWeakReference , public nsICorsPreflightCallback , public nsIChannelWithDivertableParentListener - , public nsIHstsPrimingCallback , public nsIRaceCacheWithNetwork , public nsIRequestTailUnblockCallback , public nsITimerCallback @@ -104,7 +102,6 @@ public: NS_DECL_NSIAPPLICATIONCACHECONTAINER NS_DECL_NSIAPPLICATIONCACHECHANNEL NS_DECL_NSIASYNCVERIFYREDIRECTCALLBACK - NS_DECL_NSIHSTSPRIMINGCALLBACK NS_DECL_NSITHREADRETARGETABLEREQUEST NS_DECL_NSIDNSLISTENER NS_DECL_NSICHANNELWITHDIVERTABLEPARENTLISTENER @@ -212,9 +209,6 @@ public: /* internal necko use only */ bool noAppCache); MOZ_MUST_USE nsresult ContinueConnect(); - // If the load is mixed-content, build and send an HSTS priming request. - MOZ_MUST_USE nsresult TryHSTSPriming(); - MOZ_MUST_USE nsresult StartRedirectChannelToURI(nsIURI *, uint32_t); // This allows cache entry to be marked as foreign even after channel itself diff --git a/netwerk/protocol/http/nsIHstsPrimingCallback.idl b/netwerk/protocol/http/nsIHstsPrimingCallback.idl deleted file mode 100644 index c873b709925b..000000000000 --- a/netwerk/protocol/http/nsIHstsPrimingCallback.idl +++ /dev/null @@ -1,51 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -#include "nsISupports.idl" - -/** - * HSTS priming attempts to prevent mixed-content by looking for the - * Strict-Transport-Security header as a signal from the server that it is - * safe to upgrade HTTP to HTTPS. - * - * Since mixed-content blocking happens very early in the process in AsyncOpen2, - * the status of mixed-content blocking is stored in the LoadInfo and then used - * to determine whether to send a priming request or not. - * - * This interface is implemented by nsHttpChannel so that it can receive the - * result of HSTS priming. - */ -[builtinclass, uuid(eca6daca-3f2a-4a2a-b3bf-9f24f79bc999)] -interface nsIHstsPrimingCallback : nsISupports -{ - /** - * HSTS priming has succeeded with an STS header, and the site asserts it is - * safe to upgrade the request from HTTP to HTTPS. The request may still be - * blocked based on the user's preferences. - * - * May be invoked synchronously if HSTS priming has already been performed - * for the host. - * - * @param aCached whether the result was already in the HSTS cache - */ - [noscript, nostdcall, must_use] - void onHSTSPrimingSucceeded(in bool aCached); - - /** - * HSTS priming has seen no STS header, the request itself has failed, - * or some other failure which does not constitute a positive signal that the - * site can be upgraded safely to HTTPS. The request may still be allowed - * based on the user's preferences. - * - * May be invoked synchronously if HSTS priming has already been performed - * for the host. - * - * @param aError The error which caused this failure, or NS_ERROR_CONTENT_BLOCKED - * @param aCached whether the result was already in the HSTS cache - */ - [noscript, nostdcall, must_use] - void onHSTSPrimingFailed(in nsresult aError, in bool aCached); -}; diff --git a/security/manager/ssl/nsISiteSecurityService.idl b/security/manager/ssl/nsISiteSecurityService.idl index 1bea092a7d82..702ec2a60a27 100644 --- a/security/manager/ssl/nsISiteSecurityService.idl +++ b/security/manager/ssl/nsISiteSecurityService.idl @@ -99,7 +99,6 @@ interface nsISiteSecurityService : nsISupports const uint32_t SOURCE_UNKNOWN = 0; const uint32_t SOURCE_PRELOAD_LIST = 1; const uint32_t SOURCE_ORGANIC_REQUEST = 2; - const uint32_t SOURCE_HSTS_PRIMING = 3; /** * Parses a given HTTP header and records the results internally. @@ -297,22 +296,6 @@ interface nsISiteSecurityService : nsISupports in boolean aIncludesSubdomains, in int64_t aExpires); - /** - * Mark a host as declining to provide a given security state so that features - * such as HSTS priming will not flood a server with requests. - * - * @param aURI the nsIURI that this applies to - * @param aMaxAge lifetime (in seconds) of this negative cache - * @param aOriginAttributes the origin attributes that isolate this origin, - * (note that this implementation does not isolate - * by userContextId because of the risk of man-in- - * the-middle attacks before trust-on-second-use - * happens). - */ - [noscript, must_use] void cacheNegativeHSTSResult( - in nsIURI aURI, in unsigned long long aMaxAge, - in const_OriginAttributesRef aOriginAttributes); - /** * Returns an enumerator of the nsISiteSecurityService storage. Each item in * the enumeration is a nsISiteSecurityState that can be QueryInterfaced to diff --git a/security/manager/ssl/nsSiteSecurityService.cpp b/security/manager/ssl/nsSiteSecurityService.cpp index e45cc66a2584..64b121dcf9eb 100644 --- a/security/manager/ssl/nsSiteSecurityService.cpp +++ b/security/manager/ssl/nsSiteSecurityService.cpp @@ -129,7 +129,6 @@ public: case SourceUnknown: case SourcePreload: case SourceOrganic: - case SourceHSTSPriming: break; default: return false; @@ -675,21 +674,6 @@ nsSiteSecurityService::SetHSTSState(uint32_t aType, return NS_OK; } -NS_IMETHODIMP -nsSiteSecurityService::CacheNegativeHSTSResult( - nsIURI* aSourceURI, - uint64_t aMaxAge, - const OriginAttributes& aOriginAttributes) -{ - nsAutoCString hostname; - nsresult rv = GetHost(aSourceURI, hostname); - NS_ENSURE_SUCCESS(rv, rv); - // SecurityPropertyNegative results only come from HSTS priming - return SetHSTSState(nsISiteSecurityService::HEADER_HSTS, hostname.get(), - aMaxAge, false, 0, SecurityPropertyNegative, - SourceHSTSPriming, aOriginAttributes); -} - nsresult nsSiteSecurityService::RemoveStateInternal( uint32_t aType, nsIURI* aURI, uint32_t aFlags, @@ -841,7 +825,6 @@ nsSiteSecurityService::ProcessHeader(uint32_t aType, case SourceUnknown: case SourcePreload: case SourceOrganic: - case SourceHSTSPriming: break; default: return NS_ERROR_INVALID_ARG; diff --git a/security/manager/ssl/nsSiteSecurityService.h b/security/manager/ssl/nsSiteSecurityService.h index f06e077fe153..841211c58dd4 100644 --- a/security/manager/ssl/nsSiteSecurityService.h +++ b/security/manager/ssl/nsSiteSecurityService.h @@ -47,7 +47,6 @@ enum SecurityPropertySource { SourceUnknown = nsISiteSecurityService::SOURCE_UNKNOWN, SourcePreload = nsISiteSecurityService::SOURCE_PRELOAD_LIST, SourceOrganic = nsISiteSecurityService::SOURCE_ORGANIC_REQUEST, - SourceHSTSPriming = nsISiteSecurityService::SOURCE_HSTS_PRIMING, }; /** diff --git a/security/manager/ssl/security-prefs.js b/security/manager/ssl/security-prefs.js index b67feb668fa7..8911a9f8cb41 100644 --- a/security/manager/ssl/security-prefs.js +++ b/security/manager/ssl/security-prefs.js @@ -129,22 +129,3 @@ pref("security.ssl.errorReporting.automatic", false); // blacking themselves out by setting a bad pin. (60 days by default) // https://tools.ietf.org/html/rfc7469#section-4.1 pref("security.cert_pinning.max_max_age_seconds", 5184000); - -// HSTS Priming -// If a request is mixed-content, send an HSTS priming request to attempt to -// see if it is available over HTTPS. -// Don't change the order of evaluation of mixed-content and HSTS upgrades in -// order to be most compatible with current standards in Release -pref("security.mixed_content.send_hsts_priming", false); -pref("security.mixed_content.use_hsts", false); -#ifdef EARLY_BETA_OR_EARLIER -// Change the order of evaluation so HSTS upgrades happen before -// mixed-content blocking -pref("security.mixed_content.send_hsts_priming", true); -pref("security.mixed_content.use_hsts", true); -#endif -// Approximately 1 week default cache for HSTS priming failures, in seconds -pref ("security.mixed_content.hsts_priming_cache_timeout", 604800); -// Force the channel to timeout in 2 seconds if we have not received -// expects a time in milliseconds -pref ("security.mixed_content.hsts_priming_request_timeout", 2000); diff --git a/testing/runtimes/mochitest-browser-chrome-e10s.runtimes.json b/testing/runtimes/mochitest-browser-chrome-e10s.runtimes.json index 330c7978b846..e458beeb85d9 100644 --- a/testing/runtimes/mochitest-browser-chrome-e10s.runtimes.json +++ b/testing/runtimes/mochitest-browser-chrome-e10s.runtimes.json @@ -863,11 +863,6 @@ "dom/security/test/cors/browser_CORS-console-warnings.js": 35545, "dom/security/test/csp/browser_manifest-src-override-default-src.js": 3586, "dom/security/test/csp/browser_test_web_manifest.js": 4283, - "dom/security/test/hsts/browser_hsts-priming_allow_active.js": 3604, - "dom/security/test/hsts/browser_hsts-priming_block_active.js": 3685, - "dom/security/test/hsts/browser_hsts-priming_cache-timeout.js": 2657, - "dom/security/test/hsts/browser_hsts-priming_no-duplicates.js": 3260, - "dom/security/test/hsts/browser_hsts-priming_timeout.js": 3048, "dom/tests/browser/browser_ConsoleStorageAPITests.js": 3370, "dom/tests/browser/browser_ConsoleStoragePBTest_perwindowpb.js": 2854, "dom/tests/browser/browser_beforeunload_between_chrome_content.js": 7725, diff --git a/testing/runtimes/mochitest-browser-chrome.runtimes.json b/testing/runtimes/mochitest-browser-chrome.runtimes.json index c4a9220089d4..44ab4de070d9 100644 --- a/testing/runtimes/mochitest-browser-chrome.runtimes.json +++ b/testing/runtimes/mochitest-browser-chrome.runtimes.json @@ -782,17 +782,6 @@ "dom/security/test/contentverifier/browser_verify_content_about_newtab2.js": 7915, "dom/security/test/cors/browser_CORS-console-warnings.js": 22469, "dom/security/test/csp/browser_test_web_manifest.js": 3266, - "dom/security/test/hsts/browser_hsts-priming_allow_active.js": 2437, - "dom/security/test/hsts/browser_hsts-priming_allow_display.js": 1726, - "dom/security/test/hsts/browser_hsts-priming_block_active.js": 2803, - "dom/security/test/hsts/browser_hsts-priming_block_active_css.js": 1771, - "dom/security/test/hsts/browser_hsts-priming_block_active_with_redir_same.js": 2067, - "dom/security/test/hsts/browser_hsts-priming_block_display.js": 1752, - "dom/security/test/hsts/browser_hsts-priming_cache-timeout.js": 3386, - "dom/security/test/hsts/browser_hsts-priming_hsts_after_mixed.js": 2328, - "dom/security/test/hsts/browser_hsts-priming_no-duplicates.js": 2637, - "dom/security/test/hsts/browser_hsts-priming_no-non-standard-ports.js": 3865, - "dom/security/test/hsts/browser_hsts-priming_timeout.js": 3543, "dom/tests/browser/browser_ConsoleAPITests.js": 2336, "dom/tests/browser/browser_ConsoleStorageAPITests.js": 1843, "dom/tests/browser/browser_ConsoleStoragePBTest_perwindowpb.js": 2170, diff --git a/toolkit/components/telemetry/Histograms.json b/toolkit/components/telemetry/Histograms.json index 35cf108275f0..976420feff2c 100644 --- a/toolkit/components/telemetry/Histograms.json +++ b/toolkit/components/telemetry/Histograms.json @@ -10328,45 +10328,6 @@ "n_values": 10, "description": "How often would blocked mixed content be allowed if HSTS upgrades were allowed? 0=display/no-HSTS, 1=display/HSTS, 2=active/no-HSTS, 3=active/HSTS" }, - "MIXED_CONTENT_HSTS_PRIMING_2": { - "record_in_processes": [ "main" ], - "alert_emails": ["seceng-telemetry@mozilla.com"], - "bug_numbers": [1359987], - "expires_in_version": "60", - "kind": "enumerated", - "n_values": 16, - "description": "How often would blocked mixed content be allowed if HSTS upgrades were allowed, including how often would we send an HSTS priming request? 0=passive/HSTS, 1=active/HSTS, 2=passive/no priming, 3=passive/priming, 4=active/no priming, 5=active/priming, 6=passive/will HSTS upgrade, 7=active/will HSTS upgrade" - }, - "MIXED_CONTENT_HSTS_PRIMING_RESULT": { - "record_in_processes": [ "main" ], - "alert_emails": ["seceng-telemetry@mozilla.com"], - "bug_numbers": [1246540], - "expires_in_version": "60", - "kind": "enumerated", - "n_values": 16, - "description": "How often do we get back an HSTS priming result which upgrades the connection to HTTPS? 0=cached (no upgrade), 1=cached (do upgrade), 2=cached (blocked), 3=already upgraded, 4=priming succeeded, 5=priming succeeded (block due to pref), 6=priming succeeded (no upgrade due to pref), 7=priming failed (block), 8=priming failed (accept), 9=timeout (block), 10=timeout (accept)" - }, - "MIXED_CONTENT_HSTS_PRIMING_REQUESTS": { - "record_in_processes": [ "main" ], - "alert_emails": ["seceng-telemetry@mozilla.com"], - "bug_numbers": [1359987], - "expires_in_version": "62", - "kind": "enumerated", - "n_values": 10, - "description": "How often does a request result in HSTS priming? (0=Sent HSTS priming, 1=No priming, 2=Priming skipped due to cached HSTS, 3=Priming skipped due to cached NO HSTS, 4=Priming failed (request error), 5=Priming skipped (missing load info), 6=Priming skipped (already upgraded)" - }, - "HSTS_PRIMING_REQUEST_DURATION": { - "record_in_processes": [ "main" ], - "alert_emails": ["seceng-telemetry@mozilla.com"], - "bug_numbers": [1311893, 1359987], - "expires_in_version": "62", - "kind": "exponential", - "low": 100, - "high": 30000, - "n_buckets": 100, - "keyed": true, - "description": "The amount of time required for HSTS priming requests (ms), keyed by success or failure of the priming request. (success, failure)" - }, "HSTS_UPGRADE_SOURCE": { "record_in_processes": [ "main" ], "alert_emails": ["seceng-telemetry@mozilla.com"], diff --git a/xpcom/base/ErrorList.py b/xpcom/base/ErrorList.py index 02e15b94085d..40a301a232cd 100644 --- a/xpcom/base/ErrorList.py +++ b/xpcom/base/ErrorList.py @@ -450,10 +450,6 @@ with modules["NETWORK"]: # Generic error for non-specific failures during service worker interception errors["NS_ERROR_INTERCEPTION_FAILED"] = FAILURE(100) - # nsIHstsPrimingListener - # Error code for HSTS priming timeout to distinguish from blocking - errors["NS_ERROR_HSTS_PRIMING_TIMEOUT"] = FAILURE(110) - # =======================================================================