From a7c8429fc4e884579c334cc7b544723982cf61fa Mon Sep 17 00:00:00 2001 From: Iris Hsiao Date: Wed, 27 Jul 2016 11:15:52 +0800 Subject: [PATCH] Backed out changeset d7e39be85498 (bug 1246540) for Mochitest failures --- docshell/base/nsDocShell.cpp | 23 +- dom/base/nsIDocument.h | 43 +-- dom/ipc/ContentParent.cpp | 6 +- dom/ipc/ContentParent.h | 3 +- dom/ipc/PContent.ipdl | 2 +- dom/security/moz.build | 1 - dom/security/nsContentSecurityManager.cpp | 12 +- dom/security/nsMixedContentBlocker.cpp | 152 +-------- dom/security/nsMixedContentBlocker.h | 20 +- dom/security/test/hsts/browser.ini | 9 - .../test/hsts/browser_hsts-priming_main.js | 295 ------------------ dom/security/test/hsts/file_1x1.png | Bin 17811 -> 0 bytes dom/security/test/hsts/file_priming-top.html | 84 ----- dom/security/test/hsts/file_priming.js | 4 - dom/security/test/hsts/file_stylesheet.css | 0 dom/security/test/hsts/file_testserver.sjs | 66 ---- .../test/mixedcontentblocker/test_main.html | 3 - dom/security/test/moz.build | 1 - ipc/glue/BackgroundUtils.cpp | 9 +- netwerk/base/LoadInfo.cpp | 40 +-- netwerk/base/LoadInfo.h | 7 +- netwerk/base/nsILoadInfo.idl | 26 -- netwerk/base/nsNetUtil.cpp | 2 +- netwerk/base/security-prefs.js | 12 - netwerk/ipc/NeckoChannelParams.ipdlh | 2 - netwerk/protocol/http/HSTSPrimerListener.cpp | 249 --------------- netwerk/protocol/http/HSTSPrimerListener.h | 108 ------- netwerk/protocol/http/moz.build | 2 - netwerk/protocol/http/nsHttpChannel.cpp | 140 +-------- netwerk/protocol/http/nsHttpChannel.h | 6 - netwerk/protocol/http/nsHttpHandler.cpp | 3 +- .../protocol/http/nsIHstsPrimingCallback.idl | 50 --- .../manager/ssl/SSLServerCertVerification.cpp | 2 - .../manager/ssl/nsISiteSecurityService.idl | 18 +- .../manager/ssl/nsSiteSecurityService.cpp | 67 +--- security/manager/ssl/nsSiteSecurityService.h | 6 +- .../content/SpecialPowersObserverAPI.js | 5 +- toolkit/components/telemetry/Histograms.json | 16 - 38 files changed, 49 insertions(+), 1445 deletions(-) delete mode 100644 dom/security/test/hsts/browser.ini delete mode 100644 dom/security/test/hsts/browser_hsts-priming_main.js delete mode 100644 dom/security/test/hsts/file_1x1.png delete mode 100644 dom/security/test/hsts/file_priming-top.html delete mode 100644 dom/security/test/hsts/file_priming.js delete mode 100644 dom/security/test/hsts/file_stylesheet.css delete mode 100644 dom/security/test/hsts/file_testserver.sjs delete mode 100644 netwerk/protocol/http/HSTSPrimerListener.cpp delete mode 100644 netwerk/protocol/http/HSTSPrimerListener.h delete mode 100644 netwerk/protocol/http/nsIHstsPrimingCallback.idl diff --git a/docshell/base/nsDocShell.cpp b/docshell/base/nsDocShell.cpp index 57fb2889881d..807b24f1bab1 100644 --- a/docshell/base/nsDocShell.cpp +++ b/docshell/base/nsDocShell.cpp @@ -4966,10 +4966,10 @@ nsDocShell::DisplayLoadError(nsresult aError, nsIURI* aURI, do_GetService(NS_SSSERVICE_CONTRACTID, &rv); NS_ENSURE_SUCCESS(rv, rv); rv = sss->IsSecureURI(nsISiteSecurityService::HEADER_HSTS, aURI, - flags, nullptr, &isStsHost); + flags, &isStsHost); NS_ENSURE_SUCCESS(rv, rv); rv = sss->IsSecureURI(nsISiteSecurityService::HEADER_HPKP, aURI, - flags, nullptr, &isPinnedHost); + flags, &isPinnedHost); NS_ENSURE_SUCCESS(rv, rv); } else { mozilla::dom::ContentChild* cc = @@ -9848,25 +9848,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(context); - NS_ENSURE_TRUE(docShell, NS_OK); - 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 owner(aOwner); // // Get an owner from the current document if necessary. Note that we only diff --git a/dom/base/nsIDocument.h b/dom/base/nsIDocument.h index b90b523f6f7f..4b06e3485b3b 100644 --- a/dom/base/nsIDocument.h +++ b/dom/base/nsIDocument.h @@ -21,8 +21,7 @@ #include "nsIUUIDGenerator.h" #include "nsPIDOMWindow.h" // for use in inline functions #include "nsPropertyTable.h" // for member -#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/dom/DocumentBinding.h" @@ -167,13 +166,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 @@ -357,34 +349,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. */ @@ -2905,11 +2869,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; nsCString mCharacterSet; diff --git a/dom/ipc/ContentParent.cpp b/dom/ipc/ContentParent.cpp index 08b0a7d0cfa2..99255b7e616d 100644 --- a/dom/ipc/ContentParent.cpp +++ b/dom/ipc/ContentParent.cpp @@ -4289,18 +4289,18 @@ ContentParent::RecvIsSecureURI(const uint32_t& type, if (!ourURI) { return false; } - nsresult rv = sss->IsSecureURI(type, ourURI, flags, isSecureURI, nullptr); + nsresult rv = sss->IsSecureURI(type, ourURI, flags, isSecureURI); return NS_SUCCEEDED(rv); } bool -ContentParent::RecvAccumulateMixedContentHSTS(const URIParams& aURI, const bool& aActive, const bool& aHSTSPriming) +ContentParent::RecvAccumulateMixedContentHSTS(const URIParams& aURI, const bool& aActive) { nsCOMPtr ourURI = DeserializeURI(aURI); if (!ourURI) { return false; } - nsMixedContentBlocker::AccumulateMixedContentHSTS(ourURI, aActive, aHSTSPriming); + nsMixedContentBlocker::AccumulateMixedContentHSTS(ourURI, aActive); return true; } diff --git a/dom/ipc/ContentParent.h b/dom/ipc/ContentParent.h index 3ab260adc652..a2fc7f359ab5 100644 --- a/dom/ipc/ContentParent.h +++ b/dom/ipc/ContentParent.h @@ -822,8 +822,7 @@ private: const uint32_t& aFlags, bool* aIsSecureURI) override; virtual bool RecvAccumulateMixedContentHSTS(const URIParams& aURI, - const bool& aActive, - const bool& aHSTSPriming) override; + const bool& aActive) override; virtual bool DeallocPHalParent(PHalParent*) override; diff --git a/dom/ipc/PContent.ipdl b/dom/ipc/PContent.ipdl index 6e6d929a2995..278b7f2d5f55 100644 --- a/dom/ipc/PContent.ipdl +++ b/dom/ipc/PContent.ipdl @@ -821,7 +821,7 @@ parent: sync IsSecureURI(uint32_t type, URIParams uri, uint32_t flags) returns (bool isSecureURI); - async AccumulateMixedContentHSTS(URIParams uri, bool active, bool hasHSTSPriming); + async AccumulateMixedContentHSTS(URIParams uri, bool active); sync GetLookAndFeelCache() returns (LookAndFeelInt[] lookAndFeelIntCache); diff --git a/dom/security/moz.build b/dom/security/moz.build index 00f7376a85ab..e24403433c74 100644 --- a/dom/security/moz.build +++ b/dom/security/moz.build @@ -20,7 +20,6 @@ EXPORTS.mozilla.dom += [ EXPORTS += [ 'nsContentSecurityManager.h', - 'nsMixedContentBlocker.h', ] UNIFIED_SOURCES += [ diff --git a/dom/security/nsContentSecurityManager.cpp b/dom/security/nsContentSecurityManager.cpp index 88682a68b20e..2ddc8d1a6ec7 100644 --- a/dom/security/nsContentSecurityManager.cpp +++ b/dom/security/nsContentSecurityManager.cpp @@ -6,8 +6,6 @@ #include "nsContentUtils.h" #include "nsCORSListenerProxy.h" #include "nsIStreamListener.h" -#include "nsIDocument.h" -#include "nsMixedContentBlocker.h" #include "mozilla/dom/Element.h" @@ -383,14 +381,6 @@ DoContentSecurityChecks(nsIChannel* aChannel, nsILoadInfo* aLoadInfo) if (NS_CP_REJECTED(shouldLoad)) { return NS_ERROR_CONTENT_BLOCKED; } - - if (nsMixedContentBlocker::sSendHSTSPriming) { - rv = nsMixedContentBlocker::MarkLoadInfoForPriming(uri, - requestingContext, - aLoadInfo); - return rv; - } - return NS_OK; } @@ -501,7 +491,7 @@ nsContentSecurityManager::AsyncOnChannelRedirect(nsIChannel* aOldChannel, rv = nsContentUtils::GetSecurityManager()-> CheckLoadURIWithPrincipal(oldPrincipal, newOriginalURI, flags); } - NS_ENSURE_SUCCESS(rv, rv); + NS_ENSURE_SUCCESS(rv, rv); aCb->OnRedirectVerifyCallback(NS_OK); return NS_OK; diff --git a/dom/security/nsMixedContentBlocker.cpp b/dom/security/nsMixedContentBlocker.cpp index 4a6762b9b7f6..86a78f69c329 100644 --- a/dom/security/nsMixedContentBlocker.cpp +++ b/dom/security/nsMixedContentBlocker.cpp @@ -54,11 +54,6 @@ bool nsMixedContentBlocker::sBlockMixedScript = 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; - // 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. @@ -200,14 +195,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"); } nsMixedContentBlocker::~nsMixedContentBlocker() @@ -254,6 +241,8 @@ LogMixedContentMessage(MixedContentTypes aClassification, messageLookupKey.get(), strings, ArrayLength(strings)); } + + /* nsIChannelEventSink implementation * This code is called when a request is redirected. * We check the channel associated with the new uri is allowed to load @@ -477,6 +466,7 @@ nsMixedContentBlocker::ShouldLoad(bool aHadInsecureImageRedirect, *aDecision = ACCEPT; return NS_OK; + // Static display content is considered moderate risk for mixed content so // these will be blocked according to the mixed display preference case TYPE_IMAGE: @@ -510,6 +500,7 @@ nsMixedContentBlocker::ShouldLoad(bool aHadInsecureImageRedirect, // This content policy works as a whitelist. default: MOZ_ASSERT(false, "Mixed content of unknown type"); + break; } // Make sure to get the URI the load started with. No need to check @@ -689,9 +680,7 @@ nsMixedContentBlocker::ShouldLoad(bool aHadInsecureImageRedirect, bool isHttpScheme = false; rv = innerContentLocation->SchemeIs("http", &isHttpScheme); NS_ENSURE_SUCCESS(rv, rv); - nsIDocument* document = docShell->GetDocument(); - MOZ_ASSERT(document, "Expected a document"); - if (isHttpScheme && document->GetUpgradeInsecureRequests(isPreload)) { + if (isHttpScheme && docShell->GetDocument()->GetUpgradeInsecureRequests(isPreload)) { *aDecision = ACCEPT; return NS_OK; } @@ -702,7 +691,7 @@ nsMixedContentBlocker::ShouldLoad(bool aHadInsecureImageRedirect, // Block all non secure loads in case the CSP directive is present. Please note // that at this point we already know, based on |schemeSecure| that the load is // not secure, so we can bail out early at this point. - if (document->GetBlockAllMixedContent(isPreload)) { + if (docShell->GetDocument()->GetBlockAllMixedContent(isPreload)) { // log a message to the console before returning. nsAutoCString spec; rv = aContentLocation->GetSpec(spec); @@ -717,7 +706,7 @@ nsMixedContentBlocker::ShouldLoad(bool aHadInsecureImageRedirect, 0, // aLineNumber 0, // aColumnNumber nsIScriptError::errorFlag, "CSP", - document->InnerWindowID()); + docShell->GetDocument()->InnerWindowID()); *aDecision = REJECT_REQUEST; return NS_OK; } @@ -810,34 +799,6 @@ nsMixedContentBlocker::ShouldLoad(bool aHadInsecureImageRedirect, } nsresult stateRV = securityUI->GetState(&state); - bool doHSTSPriming = false; - if (isHttpScheme) { - 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, &cached, &hsts); - NS_ENSURE_SUCCESS(rv, rv); - - if (hsts && sUseHSTS) { - // assume we will be upgraded later - *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 // whether HSTS would have fixed things by making the content location @@ -853,14 +814,14 @@ nsMixedContentBlocker::ShouldLoad(bool aHadInsecureImageRedirect, bool active = (classification == eMixedScript); if (!aHadInsecureImageRedirect) { if (XRE_IsParentProcess()) { - AccumulateMixedContentHSTS(innerContentLocation, active, doHSTSPriming); + AccumulateMixedContentHSTS(innerContentLocation, active); } else { // Ask the parent process to do the same call mozilla::dom::ContentChild* cc = mozilla::dom::ContentChild::GetSingleton(); if (cc) { mozilla::ipc::URIParams uri; SerializeURI(innerContentLocation, uri); - cc->SendAccumulateMixedContentHSTS(uri, active, doHSTSPriming); + cc->SendAccumulateMixedContentHSTS(uri, active); } } } @@ -903,13 +864,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); @@ -955,13 +910,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()) { @@ -976,6 +925,7 @@ nsMixedContentBlocker::ShouldLoad(bool aHadInsecureImageRedirect, } return NS_OK; } + } else { // The content is not blocked by the mixed content prefs. @@ -1026,24 +976,10 @@ 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 -}; - // Record information on when HSTS would have made mixed content not mixed // content (regardless of whether it was actually blocked) void -nsMixedContentBlocker::AccumulateMixedContentHSTS(nsIURI* aURI, bool aActive, bool aHasHSTSPriming) +nsMixedContentBlocker::AccumulateMixedContentHSTS(nsIURI* aURI, bool aActive) { // This method must only be called in the parent, because // nsSiteSecurityService is only available in the parent @@ -1058,88 +994,28 @@ nsMixedContentBlocker::AccumulateMixedContentHSTS(nsIURI* aURI, bool aActive, bo if (NS_FAILED(rv)) { return; } - rv = sss->IsSecureURI(nsISiteSecurityService::HEADER_HSTS, aURI, 0, nullptr, &hsts); + rv = sss->IsSecureURI(nsISiteSecurityService::HEADER_HSTS, aURI, 0, &hsts); if (NS_FAILED(rv)) { return; } - // states: would upgrade, would prime, hsts info cached - // active, passive - // if (!aActive) { if (!hsts) { Telemetry::Accumulate(Telemetry::MIXED_CONTENT_HSTS, MCB_HSTS_PASSIVE_NO_HSTS); - if (aHasHSTSPriming) { - Telemetry::Accumulate(Telemetry::MIXED_CONTENT_HSTS_PRIMING, - eMCB_HSTS_PASSIVE_DO_PRIMING); - } else { - Telemetry::Accumulate(Telemetry::MIXED_CONTENT_HSTS_PRIMING, - eMCB_HSTS_PASSIVE_NO_PRIMING); - } } else { Telemetry::Accumulate(Telemetry::MIXED_CONTENT_HSTS, MCB_HSTS_PASSIVE_WITH_HSTS); - Telemetry::Accumulate(Telemetry::MIXED_CONTENT_HSTS_PRIMING, - 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, - eMCB_HSTS_ACTIVE_DO_PRIMING); - } else { - Telemetry::Accumulate(Telemetry::MIXED_CONTENT_HSTS_PRIMING, - eMCB_HSTS_ACTIVE_NO_PRIMING); - } } else { Telemetry::Accumulate(Telemetry::MIXED_CONTENT_HSTS, MCB_HSTS_ACTIVE_WITH_HSTS); - Telemetry::Accumulate(Telemetry::MIXED_CONTENT_HSTS_PRIMING, - eMCB_HSTS_ACTIVE_WITH_HSTS); } } } - -//static -nsresult -nsMixedContentBlocker::MarkLoadInfoForPriming(nsIURI* aURI, - nsISupports* aRequestingContext, - nsILoadInfo* aLoadInfo) -{ - // 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; - } - nsIDocument* document = docShell->GetDocument(); - if (!document) { - return NS_OK; - } - - HSTSPrimingState status = document->GetHSTSPrimingStateForLocation(innerURI); - // set it on the loadInfo - if (status != HSTSPrimingState::eNO_HSTS_PRIMING) { - aLoadInfo->SetHSTSPriming(status == HSTSPrimingState::eHSTS_PRIMING_BLOCK); - } - - return NS_OK; -} diff --git a/dom/security/nsMixedContentBlocker.h b/dom/security/nsMixedContentBlocker.h index 3857082e22cd..216466fd83b2 100644 --- a/dom/security/nsMixedContentBlocker.h +++ b/dom/security/nsMixedContentBlocker.h @@ -28,8 +28,6 @@ enum MixedContentTypes { #include "nsIChannelEventSink.h" #include "imgRequest.h" -class nsILoadInfo; // forward declaration - class nsMixedContentBlocker : public nsIContentPolicy, public nsIChannelEventSink { @@ -61,25 +59,9 @@ public: nsISupports* aExtra, nsIPrincipal* aRequestPrincipal, int16_t* aDecision); - static void AccumulateMixedContentHSTS(nsIURI* aURI, - bool aActive, - bool aHasHSTSPriming); - /* 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); - + static void AccumulateMixedContentHSTS(nsIURI* aURI, bool aActive); static bool sBlockMixedScript; static bool sBlockMixedDisplay; - static bool sUseHSTS; - static bool sSendHSTSPriming; }; #endif /* nsMixedContentBlocker_h___ */ diff --git a/dom/security/test/hsts/browser.ini b/dom/security/test/hsts/browser.ini deleted file mode 100644 index 6fe1ec38bffe..000000000000 --- a/dom/security/test/hsts/browser.ini +++ /dev/null @@ -1,9 +0,0 @@ -[DEFAULT] -support-files = - file_priming-top.html - file_testserver.sjs - file_1x1.png - file_priming.js - file_stylesheet.css - -[browser_hsts-priming_main.js] diff --git a/dom/security/test/hsts/browser_hsts-priming_main.js b/dom/security/test/hsts/browser_hsts-priming_main.js deleted file mode 100644 index 3b8b32fde643..000000000000 --- a/dom/security/test/hsts/browser_hsts-priming_main.js +++ /dev/null @@ -1,295 +0,0 @@ -/* - * Description of the test: - * 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. - * - * This test uses http-on-examine-response, so must be run in browser context. - */ -'use strict'; - -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' - }, -}; -// The number of priming responses we expect to see -var priming_count = 2; - -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', - 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', - 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', - 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', - 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', - 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: false, - use_hsts: true, - send_hsts_priming: true, - type: 'css', - 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', - result: { - 'no-ssl': 'blocked', - 'reject-upgrade': 'blocked', - 'prime-hsts': 'secure', - }, - }, -} -// track which test we are on -var which_test = ""; - -const Observer = { - 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); - } - throw "Can't handle topic "+topic; - }, - // 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"; - }, - // 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 curTest = null; - let channel = subject.QueryInterface(Ci.nsIHttpChannel); - for (let item in test_servers) { - let re = RegExp('https?://'+test_servers[item].host); - if (re.test(channel.URI.asciiSpec)) { - curTest = test_servers[item]; - break; - } - } - - 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); - test_settings[which_test].priming[curTest.id] = true; - 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; - }, -}; - -// opens `uri' in a new tab and focuses it. -// returns the newly opened tab -function openTab(uri) { - let tab = gBrowser.addTab(uri); - - // select tab and make sure its browser is focused - gBrowser.selectedTab = tab; - tab.ownerDocument.defaultView.focus(); - - return tab; -} - -function clear_sts_data() { - for (let test in test_servers) { - SpecialPowers.cleanUpSTSData('http://'+test_servers[test].host); - } -} - -function do_cleanup() { - clear_sts_data(); - - Services.obs.removeObserver(Observer, "console-api-log-event"); - Services.obs.removeObserver(Observer, "http-on-examine-response"); -} - -function SetupPrefTestEnvironment(which) { - 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= {}; - - SpecialPowers.pushPrefEnv({'set': [["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]]}); -} - -// make the top-level test uri -function build_test_uri(base_uri, host, test_id, type) { - return base_uri + - "?host=" + escape(host) + - "&id=" + escape(test_id) + - "&type=" + escape(type); -} - -// open a new tab, load the test, and wait for it to finish -function execute_test(test, mimetype) { - var src = build_test_uri(TOP_URI, test_servers[test].host, - test, test_settings[which_test].type); - - let tab = openTab(src); - test_servers[test]['tab'] = tab; - - let browser = gBrowser.getBrowserForTab(tab); - yield BrowserTestUtils.browserLoaded(browser); - - gBrowser.removeTab(tab); -} - -//jscs:disable -add_task(function*() { - //jscs:enable - Services.obs.addObserver(Observer, "console-api-log-event", false); - Services.obs.addObserver(Observer, "http-on-examine-response", false); - registerCleanupFunction(do_cleanup); - - for (let which of Object.keys(test_settings)) { - SetupPrefTestEnvironment(which); - - for (let server of Object.keys(test_servers)) { - yield execute_test(server, test_settings[which].mimetype); - } - - 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 1ba31ba1a62313908f41f844a9fb2e74663a4cd2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17811 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 - - - 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 e69de29bb2d1..000000000000 diff --git a/dom/security/test/hsts/file_testserver.sjs b/dom/security/test/hsts/file_testserver.sjs deleted file mode 100644 index d5cd6b17a06e..000000000000 --- a/dom/security/test/hsts/file_testserver.sjs +++ /dev/null @@ -1,66 +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.nsILocalFile); - 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); - - 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) - } - - // avoid confusing cache behaviors - response.setHeader("Cache-Control", "no-cache", false); - - // 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') { - // 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(''); - return; - } - - var file = query.get('file'); - if (file) { - var mimetype = unescape(query.get('mimetype')); - response.setHeader("Content-Type", mimetype, false); - response.write(loadFromFile(unescape(file))); - return; - } - - response.setHeader("Content-Type", "application/json", false); - response.write('{}'); -} diff --git a/dom/security/test/mixedcontentblocker/test_main.html b/dom/security/test/mixedcontentblocker/test_main.html index 249ead1ebf5a..dfec03fa9794 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. //Enable and for the test. changePrefs([[ "dom.image.srcset.enabled", true ], [ "dom.image.picture.enabled", true ]], diff --git a/dom/security/test/moz.build b/dom/security/test/moz.build index 80e86b6c006f..74f0fefef75d 100644 --- a/dom/security/test/moz.build +++ b/dom/security/test/moz.build @@ -27,5 +27,4 @@ MOCHITEST_CHROME_MANIFESTS += [ BROWSER_CHROME_MANIFESTS += [ 'contentverifier/browser.ini', 'csp/browser.ini', - 'hsts/browser.ini', ] diff --git a/ipc/glue/BackgroundUtils.cpp b/ipc/glue/BackgroundUtils.cpp index 9ccd4c6ee16a..8d6af9977543 100644 --- a/ipc/glue/BackgroundUtils.cpp +++ b/ipc/glue/BackgroundUtils.cpp @@ -263,9 +263,7 @@ LoadInfoToLoadInfoArgs(nsILoadInfo *aLoadInfo, redirectChain, aLoadInfo->CorsUnsafeHeaders(), aLoadInfo->GetForcePreflight(), - aLoadInfo->GetIsPreflight(), - aLoadInfo->GetForceHSTSPriming(), - aLoadInfo->GetMixedContentWouldBlock()); + aLoadInfo->GetIsPreflight()); return NS_OK; } @@ -331,10 +329,7 @@ LoadInfoArgsToLoadInfo(const OptionalLoadInfoArgs& aOptionalLoadInfoArgs, redirectChain, loadInfoArgs.corsUnsafeHeaders(), loadInfoArgs.forcePreflight(), - loadInfoArgs.isPreflight(), - loadInfoArgs.forceHSTSPriming(), - loadInfoArgs.mixedContentWouldBlock() - ); + loadInfoArgs.isPreflight()); loadInfo.forget(outLoadInfo); return NS_OK; diff --git a/netwerk/base/LoadInfo.cpp b/netwerk/base/LoadInfo.cpp index 7cf515257104..0cfad010b87d 100644 --- a/netwerk/base/LoadInfo.cpp +++ b/netwerk/base/LoadInfo.cpp @@ -60,8 +60,6 @@ LoadInfo::LoadInfo(nsIPrincipal* aLoadingPrincipal, , mIsThirdPartyContext(false) , mForcePreflight(false) , mIsPreflight(false) - , mForceHSTSPriming(false) - , mMixedContentWouldBlock(false) { MOZ_ASSERT(mLoadingPrincipal); MOZ_ASSERT(mTriggeringPrincipal); @@ -215,8 +213,6 @@ LoadInfo::LoadInfo(nsPIDOMWindowOuter* aOuterWindow, , mIsThirdPartyContext(false) // NB: TYPE_DOCUMENT implies not third-party. , mForcePreflight(false) , mIsPreflight(false) - , mForceHSTSPriming(false) - , mMixedContentWouldBlock(false) { // Top-level loads are never third-party // Grab the information we can out of the window. @@ -269,8 +265,6 @@ LoadInfo::LoadInfo(const LoadInfo& rhs) , mCorsUnsafeHeaders(rhs.mCorsUnsafeHeaders) , mForcePreflight(rhs.mForcePreflight) , mIsPreflight(rhs.mIsPreflight) - , mForceHSTSPriming(rhs.mForceHSTSPriming) - , mMixedContentWouldBlock(rhs.mMixedContentWouldBlock) { } @@ -294,9 +288,7 @@ LoadInfo::LoadInfo(nsIPrincipal* aLoadingPrincipal, nsTArray>& aRedirectChain, const nsTArray& aCorsUnsafeHeaders, bool aForcePreflight, - bool aIsPreflight, - bool aForceHSTSPriming, - bool aMixedContentWouldBlock) + bool aIsPreflight) : mLoadingPrincipal(aLoadingPrincipal) , mTriggeringPrincipal(aTriggeringPrincipal) , mSecurityFlags(aSecurityFlags) @@ -316,8 +308,6 @@ LoadInfo::LoadInfo(nsIPrincipal* aLoadingPrincipal, , mCorsUnsafeHeaders(aCorsUnsafeHeaders) , mForcePreflight(aForcePreflight) , mIsPreflight(aIsPreflight) - , mForceHSTSPriming (aForceHSTSPriming) - , mMixedContentWouldBlock(aMixedContentWouldBlock) { // Only top level TYPE_DOCUMENT loads can have a null loadingPrincipal MOZ_ASSERT(mLoadingPrincipal || aContentPolicyType == nsIContentPolicy::TYPE_DOCUMENT); @@ -770,34 +760,6 @@ LoadInfo::GetIsPreflight(bool* aIsPreflight) 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::GetTainting(uint32_t* aTaintingOut) { diff --git a/netwerk/base/LoadInfo.h b/netwerk/base/LoadInfo.h index 6ccb35b02f28..91e5b6559748 100644 --- a/netwerk/base/LoadInfo.h +++ b/netwerk/base/LoadInfo.h @@ -104,9 +104,7 @@ private: nsTArray>& aRedirectChain, const nsTArray& aUnsafeHeaders, bool aForcePreflight, - bool aIsPreflight, - bool aForceHSTSPriming, - bool aMixedContentWouldBlock); + bool aIsPreflight); LoadInfo(const LoadInfo& rhs); friend nsresult @@ -147,9 +145,6 @@ private: nsTArray mCorsUnsafeHeaders; bool mForcePreflight; bool mIsPreflight; - - bool mForceHSTSPriming : 1; - bool mMixedContentWouldBlock : 1; }; } // namespace net diff --git a/netwerk/base/nsILoadInfo.idl b/netwerk/base/nsILoadInfo.idl index d0b42a8e5724..7b10d4c611f6 100644 --- a/netwerk/base/nsILoadInfo.idl +++ b/netwerk/base/nsILoadInfo.idl @@ -541,32 +541,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; - - /** - * 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 d69ade341695..50b57d59419c 100644 --- a/netwerk/base/nsNetUtil.cpp +++ b/netwerk/base/nsNetUtil.cpp @@ -2339,7 +2339,7 @@ NS_ShouldSecureUpgrade(nsIURI* aURI, bool isStsHost = false; uint32_t flags = aPrivateBrowsing ? nsISocketProvider::NO_PERMANENT_STORAGE : 0; rv = sss->IsSecureURI(nsISiteSecurityService::HEADER_HSTS, aURI, flags, - nullptr, &isStsHost); + &isStsHost); // if the SSS check fails, it's likely because this load is on a // malformed URI or something else in the setup is wrong, so any error diff --git a/netwerk/base/security-prefs.js b/netwerk/base/security-prefs.js index 0fd640a0ca36..c47f351fcfaa 100644 --- a/netwerk/base/security-prefs.js +++ b/netwerk/base/security-prefs.js @@ -97,15 +97,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); - -// If a request is mixed-content, send an HSTS priming request to attempt to -// see if it is available over HTTPS. -pref("security.mixed_content.send_hsts_priming", true); -#ifdef RELEASE_BUILD -// Don't change the order of evaluation of mixed-content and HSTS upgrades -pref("security.mixed_content.use_hsts", false); -#else -// Change the order of evaluation so HSTS upgrades happen before -// mixed-content blocking -pref("security.mixed_content.use_hsts", true); -#endif diff --git a/netwerk/ipc/NeckoChannelParams.ipdlh b/netwerk/ipc/NeckoChannelParams.ipdlh index 1c500aa0a381..982d39349c7c 100644 --- a/netwerk/ipc/NeckoChannelParams.ipdlh +++ b/netwerk/ipc/NeckoChannelParams.ipdlh @@ -49,8 +49,6 @@ struct LoadInfoArgs nsCString[] corsUnsafeHeaders; bool forcePreflight; bool isPreflight; - bool forceHSTSPriming; - bool mixedContentWouldBlock; }; /** diff --git a/netwerk/protocol/http/HSTSPrimerListener.cpp b/netwerk/protocol/http/HSTSPrimerListener.cpp deleted file mode 100644 index 83c29fe47595..000000000000 --- a/netwerk/protocol/http/HSTSPrimerListener.cpp +++ /dev/null @@ -1,249 +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 "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 "nsHttpChannel.h" -#include "LoadInfo.h" - -namespace mozilla { -namespace net { - -using namespace mozilla; - -NS_IMPL_ISUPPORTS(HSTSPrimingListener, nsIStreamListener, - nsIRequestObserver, nsIInterfaceRequestor) - -NS_IMETHODIMP -HSTSPrimingListener::GetInterface(const nsIID & aIID, void **aResult) -{ - return QueryInterface(aIID, aResult); -} - -NS_IMETHODIMP -HSTSPrimingListener::OnStartRequest(nsIRequest *aRequest, - nsISupports *aContext) -{ - nsresult rv = CheckHSTSPrimingRequestStatus(aRequest); - nsCOMPtr callback(mCallback); - mCallback = nullptr; - - if (NS_FAILED(rv)) { - LOG(("HSTS Priming Failed (request was not approved)")); - return callback->OnHSTSPrimingFailed(rv, 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; - nsHttpChannel* rawHttpChannel = static_cast(httpChannel.get()); - 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); - - bool hsts; - rv = sss->IsSecureURI(nsISiteSecurityService::HEADER_HSTS, uri, 0, 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); -} - -// 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 = finalChannelURI->Clone(getter_AddRefs(uri)); - NS_ENSURE_SUCCESS(rv, rv); - rv = uri->SetScheme(NS_LITERAL_CSTRING("https")); - NS_ENSURE_SUCCESS(rv, rv); - - // check the HSTS cache - bool hsts; - bool cached; - nsCOMPtr sss = do_GetService(NS_SSSERVICE_CONTRACTID, &rv); - NS_ENSURE_SUCCESS(rv, rv); - rv = sss->IsSecureURI(nsISiteSecurityService::HEADER_HSTS, uri, 0, &cached, &hsts); - NS_ENSURE_SUCCESS(rv, rv); - - if (hsts) { - // already saw this host and will upgrade if allowed by preferences - return aCallback->OnHSTSPrimingSucceeded(true); - } - - if (cached) { - // there is a non-expired entry in the cache that doesn't allow us to - // upgrade, so go ahead and fail early. - 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(); - - 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; - } - - // 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: aRequestChannel 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); - - // Set up listener which will start the original channel - RefPtr primingListener = - new HSTSPrimingListener(aCallback); - - // Start priming - rv = primingChannel->AsyncOpen2(primingListener); - NS_ENSURE_SUCCESS(rv, rv); - - 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 05089911bfe7..000000000000 --- a/netwerk/protocol/http/HSTSPrimerListener.h +++ /dev/null @@ -1,108 +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 "nsIStreamListener.h" -#include "nsIThreadRetargetableStreamListener.h" - -#include "mozilla/Attributes.h" - -class nsIPrincipal; -class nsINetworkInterceptController; -class nsIHstsPrimingCallback; - -namespace mozilla { -namespace net { - -class HttpChannelParent; -class nsHttpChannel; - -/* - * 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 -}; - -////////////////////////////////////////////////////////////////////////// -// 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: - explicit HSTSPrimingListener(nsIHstsPrimingCallback* aCallback) - : mCallback(aCallback) - { - } - - NS_DECL_ISUPPORTS - NS_DECL_NSISTREAMLISTENER - NS_DECL_NSIREQUESTOBSERVER - NS_DECL_NSIINTERFACEREQUESTOR - -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); - - /** - * the nsIHttpChannel to notify with the result of HSTS priming. - */ - nsCOMPtr mCallback; -}; - - -}} // mozilla::net - -#endif // HSTSPrimingListener_h__ diff --git a/netwerk/protocol/http/moz.build b/netwerk/protocol/http/moz.build index 47c99fd9656b..89bd6cdd9774 100644 --- a/netwerk/protocol/http/moz.build +++ b/netwerk/protocol/http/moz.build @@ -5,7 +5,6 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. XPIDL_SOURCES += [ - 'nsIHstsPrimingCallback.idl', 'nsIHttpActivityObserver.idl', 'nsIHttpAuthenticableChannel.idl', 'nsIHttpAuthenticator.idl', @@ -55,7 +54,6 @@ SOURCES += [ UNIFIED_SOURCES += [ '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 33f92534a3de..9c653ed3d3b6 100644 --- a/netwerk/protocol/http/nsHttpChannel.cpp +++ b/netwerk/protocol/http/nsHttpChannel.cpp @@ -98,8 +98,6 @@ #include "nsISocketProvider.h" #include "mozilla/net/Predictor.h" #include "CacheControlParser.h" -#include "nsMixedContentBlocker.h" -#include "HSTSPrimerListener.h" namespace mozilla { namespace net { @@ -407,50 +405,12 @@ nsHttpChannel::Connect() // otherwise, let's just proceed without using the cache. } - return TryHSTSPriming(); -} - -nsresult -nsHttpChannel::TryHSTSPriming() -{ - if (mLoadInfo) { - // HSTS priming requires the LoadInfo provided with AsyncOpen2 - bool requireHSTSPriming = - mLoadInfo->GetForceHSTSPriming(); - - if (requireHSTSPriming && - nsMixedContentBlocker::sSendHSTSPriming && - mInterceptCache == DO_NOT_INTERCEPT) { - bool isHttpsScheme; - nsresult rv = mURI->SchemeIs("https", &isHttpsScheme); - NS_ENSURE_SUCCESS(rv, rv); - if (!isHttpsScheme) { - rv = HSTSPrimingListener::StartHSTSPriming(this, this); - - if (NS_FAILED(rv)) { - CloseCacheEntry(false); - return rv; - } - - return NS_OK; - } - - // The request was already upgraded, for example by - // upgrade-insecure-requests or a prior successful priming request - Telemetry::Accumulate(Telemetry::MIXED_CONTENT_HSTS_PRIMING_RESULT, - HSTSPrimingResult::eHSTS_PRIMING_ALREADY_UPGRADED); - mLoadInfo->ClearHSTSPriming(); - } - } - return ContinueConnect(); } nsresult nsHttpChannel::ContinueConnect() { - // 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 && @@ -4058,7 +4018,7 @@ nsHttpChannel::OnCacheEntryAvailableInternal(nsICacheEntry *entry, return NS_OK; } - return TryHSTSPriming(); + return ContinueConnect(); } nsresult @@ -5398,7 +5358,6 @@ NS_INTERFACE_MAP_BEGIN(nsHttpChannel) NS_INTERFACE_MAP_ENTRY(nsIDNSListener) NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference) NS_INTERFACE_MAP_ENTRY(nsICorsPreflightCallback) - NS_INTERFACE_MAP_ENTRY(nsIHstsPrimingCallback) NS_INTERFACE_MAP_ENTRY(nsIChannelWithDivertableParentListener) // we have no macro that covers this case. if (aIID.Equals(NS_GET_IID(nsHttpChannel)) ) { @@ -7719,103 +7678,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 (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); - return AsyncCall(&nsHttpChannel::HandleAsyncRedirectChannelToHttps); - } - - // 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(); - - // 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); - - 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(); - - LOG(("HSTS Priming Failed [this=%p], %s the load", this, - (wouldBlock) ? "blocking" : "allowing")); - 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 one day - nsISiteSecurityService* sss = gHttpHandler->GetSSService(); - NS_ENSURE_TRUE(sss, NS_ERROR_OUT_OF_MEMORY); - nsresult rv = sss->CacheNegativeHSTSResult(mURI, 24 * 60 * 60); - NS_WARN_IF(NS_FAILED(rv)); - - // If we would block, go ahead and abort with the error provided - if (wouldBlock) { - CloseCacheEntry(false); - return AsyncAbort(aError); - } - - // 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 //----------------------------------------------------------------------------- diff --git a/netwerk/protocol/http/nsHttpChannel.h b/netwerk/protocol/http/nsHttpChannel.h index 3b5ce48d45c4..4f317f41cbf8 100644 --- a/netwerk/protocol/http/nsHttpChannel.h +++ b/netwerk/protocol/http/nsHttpChannel.h @@ -27,7 +27,6 @@ #include "nsIStreamListener.h" #include "nsISupportsPrimitives.h" #include "nsICorsPreflightCallback.h" -#include "nsIHstsPrimingCallback.h" class nsDNSPrefetch; class nsICancelable; @@ -75,7 +74,6 @@ class nsHttpChannel final : public HttpBaseChannel , public nsSupportsWeakReference , public nsICorsPreflightCallback , public nsIChannelWithDivertableParentListener - , public nsIHstsPrimingCallback { public: NS_DECL_ISUPPORTS_INHERITED @@ -91,7 +89,6 @@ public: NS_DECL_NSIAPPLICATIONCACHECONTAINER NS_DECL_NSIAPPLICATIONCACHECHANNEL NS_DECL_NSIASYNCVERIFYREDIRECTCALLBACK - NS_DECL_NSIHSTSPRIMINGCALLBACK NS_DECL_NSITHREADRETARGETABLEREQUEST NS_DECL_NSIDNSLISTENER NS_DECL_NSICHANNELWITHDIVERTABLEPARENTLISTENER @@ -206,9 +203,6 @@ public: /* internal necko use only */ nsresult OpenCacheEntry(bool usingSSL); nsresult ContinueConnect(); - // If the load is mixed-content, build and send an HSTS priming request. - nsresult TryHSTSPriming(); - nsresult StartRedirectChannelToURI(nsIURI *, uint32_t); // This allows cache entry to be marked as foreign even after channel itself diff --git a/netwerk/protocol/http/nsHttpHandler.cpp b/netwerk/protocol/http/nsHttpHandler.cpp index 181dffb31e8e..9fcd8cbc2fcb 100644 --- a/netwerk/protocol/http/nsHttpHandler.cpp +++ b/netwerk/protocol/http/nsHttpHandler.cpp @@ -2244,8 +2244,7 @@ nsHttpHandler::SpeculativeConnectInternal(nsIURI *aURI, flags |= nsISocketProvider::NO_PERMANENT_STORAGE; nsCOMPtr clone; if (NS_SUCCEEDED(sss->IsSecureURI(nsISiteSecurityService::HEADER_HSTS, - aURI, flags, nullptr, &isStsHost)) && - isStsHost) { + aURI, flags, &isStsHost)) && isStsHost) { if (NS_SUCCEEDED(NS_GetSecureUpgradedURI(aURI, getter_AddRefs(clone)))) { aURI = clone.get(); diff --git a/netwerk/protocol/http/nsIHstsPrimingCallback.idl b/netwerk/protocol/http/nsIHstsPrimingCallback.idl deleted file mode 100644 index 0e45901738c7..000000000000 --- a/netwerk/protocol/http/nsIHstsPrimingCallback.idl +++ /dev/null @@ -1,50 +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] - 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] - void onHSTSPrimingFailed(in nsresult aError, in bool aCached); -}; diff --git a/security/manager/ssl/SSLServerCertVerification.cpp b/security/manager/ssl/SSLServerCertVerification.cpp index 22d20ae99edd..794efc244bea 100644 --- a/security/manager/ssl/SSLServerCertVerification.cpp +++ b/security/manager/ssl/SSLServerCertVerification.cpp @@ -506,7 +506,6 @@ CertErrorRunnable::CheckCertOverrides() nsresult nsrv = sss->IsSecureHost(nsISiteSecurityService::HEADER_HSTS, mInfoObject->GetHostNameRaw(), mProviderFlags, - nullptr, &strictTransportSecurityEnabled); if (NS_FAILED(nsrv)) { MOZ_LOG(gPIPNSSLog, LogLevel::Debug, @@ -517,7 +516,6 @@ CertErrorRunnable::CheckCertOverrides() nsrv = sss->IsSecureHost(nsISiteSecurityService::HEADER_HPKP, mInfoObject->GetHostNameRaw(), mProviderFlags, - nullptr, &hasPinningInformation); if (NS_FAILED(nsrv)) { MOZ_LOG(gPIPNSSLog, LogLevel::Debug, diff --git a/security/manager/ssl/nsISiteSecurityService.idl b/security/manager/ssl/nsISiteSecurityService.idl index a1ebcd40ead8..0eca3041ad47 100644 --- a/security/manager/ssl/nsISiteSecurityService.idl +++ b/security/manager/ssl/nsISiteSecurityService.idl @@ -115,13 +115,10 @@ interface nsISiteSecurityService : nsISupports * @param aHost the hostname (punycode) to query for state. * @param aFlags options for this request as defined in nsISocketProvider: * NO_PERMANENT_STORAGE - * @param aCached true if we have cached information regarding whether or not - * the host is HSTS, false otherwise. */ boolean isSecureHost(in uint32_t aType, in string aHost, - in uint32_t aFlags, - [optional] out boolean aCached); + in uint32_t aFlags); /** * Checks whether or not the URI's hostname has a given security state set. @@ -136,11 +133,8 @@ interface nsISiteSecurityService : nsISupports * @param aURI the URI to query for STS state. * @param aFlags options for this request as defined in nsISocketProvider: * NO_PERMANENT_STORAGE - * @param aCached true if we have cached information regarding whether or not - * the host is HSTS, false otherwise. */ - boolean isSecureURI(in uint32_t aType, in nsIURI aURI, in uint32_t aFlags, - [optional] out boolean aCached); + boolean isSecureURI(in uint32_t aType, in nsIURI aURI, in uint32_t aFlags); /** * Removes all security state by resetting to factory-original settings. @@ -180,14 +174,6 @@ interface nsISiteSecurityService : nsISupports in unsigned long aMaxAge, in unsigned long aPinCount, [array, size_is(aPinCount)] in string aSha256Pins); - /** - * 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 aHost the hostname (punycode) that this applies to - * @param aMaxAge lifetime (in seconds) of this negative cache - */ - [noscript] void cacheNegativeHSTSResult(in nsIURI aURI, in unsigned long long aMaxAge); }; %{C++ diff --git a/security/manager/ssl/nsSiteSecurityService.cpp b/security/manager/ssl/nsSiteSecurityService.cpp index c8a4635536af..b3df457ff52e 100644 --- a/security/manager/ssl/nsSiteSecurityService.cpp +++ b/security/manager/ssl/nsSiteSecurityService.cpp @@ -314,8 +314,7 @@ nsSiteSecurityService::SetHSTSState(uint32_t aType, nsIURI* aSourceURI, int64_t maxage, bool includeSubdomains, - uint32_t flags, - SecurityPropertyState aHSTSState) + uint32_t flags) { // If max-age is zero, that's an indication to immediately remove the // security state, so here's a shortcut. @@ -323,12 +322,8 @@ nsSiteSecurityService::SetHSTSState(uint32_t aType, return RemoveState(aType, aSourceURI, flags); } - MOZ_ASSERT((aHSTSState == SecurityPropertySet - || aHSTSState == SecurityPropertyNegative), - "HSTS State must be SecurityPropertySet or SecurityPropertyNegative"); - int64_t expiretime = ExpireTimeFromMaxAge(maxage); - SiteHSTSState siteState(expiretime, aHSTSState, includeSubdomains); + SiteHSTSState siteState(expiretime, SecurityPropertySet, includeSubdomains); nsAutoCString stateString; siteState.ToString(stateString); nsAutoCString hostname; @@ -347,14 +342,6 @@ nsSiteSecurityService::SetHSTSState(uint32_t aType, return NS_OK; } -NS_IMETHODIMP -nsSiteSecurityService::CacheNegativeHSTSResult(nsIURI* aSourceURI, - uint64_t aMaxAge) -{ - return SetHSTSState(nsISiteSecurityService::HEADER_HSTS, aSourceURI, - aMaxAge, false, 0, SecurityPropertyNegative); -} - NS_IMETHODIMP nsSiteSecurityService::RemoveState(uint32_t aType, nsIURI* aURI, uint32_t aFlags) @@ -877,7 +864,7 @@ nsSiteSecurityService::ProcessSTSHeader(nsIURI* aSourceURI, // record the successfully parsed header data. nsresult rv = SetHSTSState(aType, aSourceURI, maxAge, foundIncludeSubdomains, - aFlags, SecurityPropertySet); + aFlags); if (NS_FAILED(rv)) { SSSLOG(("SSS: failed to set STS state")); if (aFailureResult) { @@ -901,8 +888,7 @@ nsSiteSecurityService::ProcessSTSHeader(nsIURI* aSourceURI, NS_IMETHODIMP nsSiteSecurityService::IsSecureURI(uint32_t aType, nsIURI* aURI, - uint32_t aFlags, bool* aCached, - bool* aResult) + uint32_t aFlags, bool* aResult) { // Child processes are not allowed direct access to this. if (!XRE_IsParentProcess() && aType != nsISiteSecurityService::HEADER_HSTS) { @@ -926,7 +912,7 @@ nsSiteSecurityService::IsSecureURI(uint32_t aType, nsIURI* aURI, return NS_OK; } - return IsSecureHost(aType, hostname.get(), aFlags, aCached, aResult); + return IsSecureHost(aType, hostname.get(), aFlags, aResult); } int STSPreloadCompare(const void *key, const void *entry) @@ -956,8 +942,7 @@ nsSiteSecurityService::GetPreloadListEntry(const char *aHost) NS_IMETHODIMP nsSiteSecurityService::IsSecureHost(uint32_t aType, const char* aHost, - uint32_t aFlags, bool* aCached, - bool* aResult) + uint32_t aFlags, bool* aResult) { // Child processes are not allowed direct access to this. if (!XRE_IsParentProcess() && aType != nsISiteSecurityService::HEADER_HSTS) { @@ -974,9 +959,6 @@ nsSiteSecurityService::IsSecureHost(uint32_t aType, const char* aHost, // set default in case if we can't find any STS information *aResult = false; - if (aCached) { - *aCached = false; - } /* An IP address never qualifies as a secure URI. */ if (HostIsIPAddress(aHost)) { @@ -1002,9 +984,6 @@ nsSiteSecurityService::IsSecureHost(uint32_t aType, const char* aHost, nsAutoCString host(PublicKeyPinningService::CanonicalizeHostname(aHost)); if (host.EqualsLiteral("chart.apis.google.com") || StringEndsWith(host, NS_LITERAL_CSTRING(".chart.apis.google.com"))) { - if (aCached) { - *aCached = true; - } return NS_OK; } @@ -1028,17 +1007,9 @@ nsSiteSecurityService::IsSecureHost(uint32_t aType, const char* aHost, if (siteState.mHSTSState != SecurityPropertyUnset) { SSSLOG(("Found entry for %s", host.get())); bool expired = siteState.IsExpired(aType); - if (!expired) { - if (aCached) { - *aCached = true; - } - if (siteState.mHSTSState == SecurityPropertySet) { - *aResult = true; - return NS_OK; - } else if (siteState.mHSTSState == SecurityPropertyNegative) { - *aResult = false; - return NS_OK; - } + if (!expired && siteState.mHSTSState == SecurityPropertySet) { + *aResult = true; + return NS_OK; } // If the entry is expired and not in the preload list, we can remove it. @@ -1051,9 +1022,6 @@ nsSiteSecurityService::IsSecureHost(uint32_t aType, const char* aHost, else if (GetPreloadListEntry(host.get())) { SSSLOG(("%s is a preloaded STS host", host.get())); *aResult = true; - if (aCached) { - *aCached = true; - } return NS_OK; } @@ -1086,17 +1054,9 @@ nsSiteSecurityService::IsSecureHost(uint32_t aType, const char* aHost, if (siteState.mHSTSState != SecurityPropertyUnset) { SSSLOG(("Found entry for %s", subdomain)); bool expired = siteState.IsExpired(aType); - if (!expired) { - if (aCached) { - *aCached = true; - } - if (siteState.mHSTSState == SecurityPropertySet) { - *aResult = siteState.mHSTSIncludeSubdomains; - break; - } else if (siteState.mHSTSState == SecurityPropertyNegative) { - *aResult = false; - break; - } + if (!expired && siteState.mHSTSState == SecurityPropertySet) { + *aResult = siteState.mHSTSIncludeSubdomains; + break; } // If the entry is expired and not in the preload list, we can remove it. @@ -1110,9 +1070,6 @@ nsSiteSecurityService::IsSecureHost(uint32_t aType, const char* aHost, if (preload->mIncludeSubdomains) { SSSLOG(("%s is a preloaded STS host", subdomain)); *aResult = true; - if (aCached) { - *aCached = true; - } break; } } diff --git a/security/manager/ssl/nsSiteSecurityService.h b/security/manager/ssl/nsSiteSecurityService.h index 08396964d642..cba010917cb6 100644 --- a/security/manager/ssl/nsSiteSecurityService.h +++ b/security/manager/ssl/nsSiteSecurityService.h @@ -34,8 +34,7 @@ class nsISSLStatus; enum SecurityPropertyState { SecurityPropertyUnset = 0, SecurityPropertySet = 1, - SecurityPropertyKnockout = 2, - SecurityPropertyNegative = 3 + SecurityPropertyKnockout = 2 }; /** @@ -129,8 +128,7 @@ protected: private: nsresult GetHost(nsIURI *aURI, nsACString &aResult); nsresult SetHSTSState(uint32_t aType, nsIURI* aSourceURI, int64_t maxage, - bool includeSubdomains, uint32_t flags, - SecurityPropertyState aHSTSState); + bool includeSubdomains, uint32_t flags); nsresult ProcessHeaderInternal(uint32_t aType, nsIURI* aSourceURI, const char* aHeader, nsISSLStatus* aSSLStatus, uint32_t aFlags, uint64_t* aMaxAge, diff --git a/testing/specialpowers/content/SpecialPowersObserverAPI.js b/testing/specialpowers/content/SpecialPowersObserverAPI.js index e47c478f871c..f2e2d550cfa8 100644 --- a/testing/specialpowers/content/SpecialPowersObserverAPI.js +++ b/testing/specialpowers/content/SpecialPowersObserverAPI.js @@ -324,10 +324,10 @@ SpecialPowersObserverAPI.prototype = { case "BOOL": if (aMessage.json.op == "get") return(prefs.getBoolPref(prefName)); - else + else return(prefs.setBoolPref(prefName, prefValue)); case "INT": - if (aMessage.json.op == "get") + if (aMessage.json.op == "get") return(prefs.getIntPref(prefName)); else return(prefs.setIntPref(prefName, prefValue)); @@ -563,7 +563,6 @@ SpecialPowersObserverAPI.prototype = { let sss = Cc["@mozilla.org/ssservice;1"]. getService(Ci.nsISiteSecurityService); sss.removeState(Ci.nsISiteSecurityService.HEADER_HSTS, uri, flags); - return undefined; } case "SPLoadExtension": { diff --git a/toolkit/components/telemetry/Histograms.json b/toolkit/components/telemetry/Histograms.json index 9b62f25b5dbf..778c44c508c0 100644 --- a/toolkit/components/telemetry/Histograms.json +++ b/toolkit/components/telemetry/Histograms.json @@ -7316,22 +7316,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": { - "alert_emails": ["seceng@mozilla.org"], - "bug_numbers": [1246540], - "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=display/no-HSTS, 1=display/HSTS, 2=active/no-HSTS, 3=active/HSTS, 4=display/no-HSTS-priming, 5=display/do-HSTS-priming, 6=active/no-HSTS-priming, 7=active/do-HSTS-priming" - }, - "MIXED_CONTENT_HSTS_PRIMING_RESULT": { - "alert_emails": ["seceng@mozilla.org"], - "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)" - }, "MIXED_CONTENT_OBJECT_SUBREQUEST": { "alert_emails": ["seceng@mozilla.org"], "bug_numbers": [1244116],