diff options
Diffstat (limited to 'netwerk/protocol')
-rw-r--r-- | netwerk/protocol/http/HSTSPrimerListener.cpp | 273 | ||||
-rw-r--r-- | netwerk/protocol/http/HSTSPrimerListener.h | 108 | ||||
-rw-r--r-- | netwerk/protocol/http/HttpChannelChild.cpp | 16 | ||||
-rw-r--r-- | netwerk/protocol/http/HttpChannelParent.cpp | 10 | ||||
-rw-r--r-- | netwerk/protocol/http/HttpChannelParent.h | 2 | ||||
-rw-r--r-- | netwerk/protocol/http/PHttpChannel.ipdl | 1 | ||||
-rw-r--r-- | netwerk/protocol/http/moz.build | 2 | ||||
-rw-r--r-- | netwerk/protocol/http/nsHttpChannel.cpp | 143 | ||||
-rw-r--r-- | netwerk/protocol/http/nsHttpChannel.h | 6 | ||||
-rw-r--r-- | netwerk/protocol/http/nsIHstsPrimingCallback.idl | 50 |
10 files changed, 4 insertions, 607 deletions
diff --git a/netwerk/protocol/http/HSTSPrimerListener.cpp b/netwerk/protocol/http/HSTSPrimerListener.cpp deleted file mode 100644 index 8c9d28d36..000000000 --- a/netwerk/protocol/http/HSTSPrimerListener.cpp +++ /dev/null @@ -1,273 +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 primingResult = CheckHSTSPrimingRequestStatus(aRequest); - nsCOMPtr<nsIHstsPrimingCallback> callback(mCallback); - mCallback = nullptr; - - nsCOMPtr<nsITimedChannel> timingChannel = - do_QueryInterface(callback); - if (timingChannel) { - 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(primingResult)) ? NS_LITERAL_CSTRING("success") - : NS_LITERAL_CSTRING("failure"), - interval); - } - } - - 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<nsIHttpChannel> httpChannel = do_QueryInterface(aRequest); - NS_ENSURE_STATE(httpChannel); - nsCOMPtr<nsIHttpChannelInternal> 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<nsHttpChannel*>(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<nsISiteSecurityService> sss = do_GetService(NS_SSSERVICE_CONTRACTID, &rv); - NS_ENSURE_SUCCESS(rv, rv); - - nsCOMPtr<nsIURI> 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<nsIURI> finalChannelURI; - nsresult rv = NS_GetFinalChannelURI(aRequestChannel, getter_AddRefs(finalChannelURI)); - NS_ENSURE_SUCCESS(rv, rv); - - nsCOMPtr<nsIURI> uri; - rv = NS_GetSecureUpgradedURI(finalChannelURI, getter_AddRefs(uri)); - NS_ENSURE_SUCCESS(rv,rv); - - // check the HSTS cache - bool hsts; - bool cached; - nsCOMPtr<nsISiteSecurityService> 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<nsILoadInfo> originalLoadInfo = aRequestChannel->GetLoadInfo(); - MOZ_ASSERT(originalLoadInfo, "can not perform HSTS priming without a loadInfo"); - if (!originalLoadInfo) { - return NS_ERROR_FAILURE; - } - - nsCOMPtr<nsILoadInfo> loadInfo = static_cast<mozilla::LoadInfo*> - (originalLoadInfo.get())->CloneForNewRequest(); - - // 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<nsILoadGroup> 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<nsIChannel> 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<nsIHttpChannel> 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<nsIClassOfService> requestClass = do_QueryInterface(aRequestChannel); - if (!requestClass) { - NS_ERROR("HSTSPrimingListener: aRequestChannel is not an nsIClassOfService"); - return NS_ERROR_FAILURE; - } - nsCOMPtr<nsIClassOfService> 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 - nsCOMPtr<nsIStreamListener> 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 05089911b..000000000 --- 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<nsIHstsPrimingCallback> mCallback; -}; - - -}} // mozilla::net - -#endif // HSTSPrimingListener_h__ diff --git a/netwerk/protocol/http/HttpChannelChild.cpp b/netwerk/protocol/http/HttpChannelChild.cpp index 6d09135c4..0a1e0f859 100644 --- a/netwerk/protocol/http/HttpChannelChild.cpp +++ b/netwerk/protocol/http/HttpChannelChild.cpp @@ -1681,8 +1681,8 @@ NS_IMETHODIMP HttpChannelChild::OnRedirectVerifyCallback(nsresult result) { LOG(("HttpChannelChild::OnRedirectVerifyCallback [this=%p]\n", this)); - nsresult rv; OptionalURIParams redirectURI; + nsresult rv; nsCOMPtr<nsIHttpChannel> newHttpChannel = do_QueryInterface(mRedirectChannelChild); @@ -1697,18 +1697,9 @@ 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<nsILoadInfo> newLoadInfo; - rv = newHttpChannel->GetLoadInfo(getter_AddRefs(newLoadInfo)); - if (NS_SUCCEEDED(rv) && newLoadInfo) { - forceHSTSPriming = newLoadInfo->GetForceHSTSPriming(); - mixedContentWouldBlock = newLoadInfo->GetMixedContentWouldBlock(); - } } if (mRedirectingForSubsequentSynthesizedResponse) { @@ -1756,7 +1747,7 @@ HttpChannelChild::OnRedirectVerifyCallback(nsresult result) do_QueryInterface(mRedirectChannelChild); if (newHttpChannelInternal) { nsCOMPtr<nsIURI> 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 @@ -1780,8 +1771,7 @@ HttpChannelChild::OnRedirectVerifyCallback(nsresult result) if (mIPCOpen) SendRedirect2Verify(result, *headerTuples, loadFlags, redirectURI, - corsPreflightArgs, forceHSTSPriming, - mixedContentWouldBlock, chooseAppcache); + corsPreflightArgs, chooseAppcache); return NS_OK; } diff --git a/netwerk/protocol/http/HttpChannelParent.cpp b/netwerk/protocol/http/HttpChannelParent.cpp index 90ed597a6..d1c67f01b 100644 --- a/netwerk/protocol/http/HttpChannelParent.cpp +++ b/netwerk/protocol/http/HttpChannelParent.cpp @@ -733,8 +733,6 @@ HttpChannelParent::RecvRedirect2Verify(const nsresult& result, const uint32_t& loadFlags, const OptionalURIParams& aAPIRedirectURI, const OptionalCorsPreflightArgs& aCorsPreflightArgs, - const bool& aForceHSTSPriming, - const bool& aMixedContentWouldBlock, const bool& aChooseAppcache) { LOG(("HttpChannelParent::RecvRedirect2Verify [this=%p result=%x]\n", @@ -774,14 +772,6 @@ HttpChannelParent::RecvRedirect2Verify(const nsresult& result, newInternalChannel->SetCorsPreflightParameters(args.unsafeHeaders()); } - if (aForceHSTSPriming) { - nsCOMPtr<nsILoadInfo> newLoadInfo; - rv = newHttpChannel->GetLoadInfo(getter_AddRefs(newLoadInfo)); - if (NS_SUCCEEDED(rv) && newLoadInfo) { - newLoadInfo->SetHSTSPriming(aMixedContentWouldBlock); - } - } - nsCOMPtr<nsIApplicationCacheChannel> appCacheChannel = do_QueryInterface(newHttpChannel); if (appCacheChannel) { diff --git a/netwerk/protocol/http/HttpChannelParent.h b/netwerk/protocol/http/HttpChannelParent.h index 56854bb55..91f9bac8b 100644 --- a/netwerk/protocol/http/HttpChannelParent.h +++ b/netwerk/protocol/http/HttpChannelParent.h @@ -162,8 +162,6 @@ protected: const uint32_t& loadFlags, const OptionalURIParams& apiRedirectUri, const OptionalCorsPreflightArgs& aCorsPreflightArgs, - const bool& aForceHSTSPriming, - const bool& aMixedContentWouldBlock, const bool& aChooseAppcache) override; virtual bool RecvUpdateAssociatedContentSecurity(const int32_t& broken, const int32_t& no) override; diff --git a/netwerk/protocol/http/PHttpChannel.ipdl b/netwerk/protocol/http/PHttpChannel.ipdl index 1eb25a403..c77a53e40 100644 --- a/netwerk/protocol/http/PHttpChannel.ipdl +++ b/netwerk/protocol/http/PHttpChannel.ipdl @@ -47,7 +47,6 @@ parent: async Redirect2Verify(nsresult result, RequestHeaderTuples changedHeaders, uint32_t loadFlags, 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 e13101aa0..1368ee707 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', @@ -58,7 +57,6 @@ UNIFIED_SOURCES += [ 'AltDataOutputStreamParent.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 9107b16e8..7bcec146d 100644 --- a/netwerk/protocol/http/nsHttpChannel.cpp +++ b/netwerk/protocol/http/nsHttpChannel.cpp @@ -100,7 +100,6 @@ #include "mozilla/net/Predictor.h" #include "CacheControlParser.h" #include "nsMixedContentBlocker.h" -#include "HSTSPrimerListener.h" #include "CacheStorageService.h" namespace mozilla { namespace net { @@ -465,50 +464,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 && @@ -4283,7 +4244,7 @@ nsHttpChannel::OnCacheEntryAvailableInternal(nsICacheEntry *entry, return NS_OK; } - return TryHSTSPriming(); + return ContinueConnect(); } nsresult @@ -5699,7 +5660,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)) ) { @@ -8186,107 +8146,6 @@ nsHttpChannel::OnPreflightFailed(nsresult aError) } //----------------------------------------------------------------------------- -// 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 - // security.mixed_content.hsts_priming_cache_timeout seconds. - nsISiteSecurityService* sss = gHttpHandler->GetSSService(); - NS_ENSURE_TRUE(sss, NS_ERROR_OUT_OF_MEMORY); - nsresult rv = sss->CacheNegativeHSTSResult(mURI, - nsMixedContentBlocker::sHSTSPrimingCacheTimeout); - 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); - } - - // 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 cb8925d04..3a322e8e2 100644 --- a/netwerk/protocol/http/nsHttpChannel.h +++ b/netwerk/protocol/http/nsHttpChannel.h @@ -28,7 +28,6 @@ #include "nsISupportsPrimitives.h" #include "nsICorsPreflightCallback.h" #include "AlternateServices.h" -#include "nsIHstsPrimingCallback.h" class nsDNSPrefetch; class nsICancelable; @@ -76,7 +75,6 @@ class nsHttpChannel final : public HttpBaseChannel , public nsSupportsWeakReference , public nsICorsPreflightCallback , public nsIChannelWithDivertableParentListener - , public nsIHstsPrimingCallback { public: NS_DECL_ISUPPORTS_INHERITED @@ -92,7 +90,6 @@ public: NS_DECL_NSIAPPLICATIONCACHECONTAINER NS_DECL_NSIAPPLICATIONCACHECHANNEL NS_DECL_NSIASYNCVERIFYREDIRECTCALLBACK - NS_DECL_NSIHSTSPRIMINGCALLBACK NS_DECL_NSITHREADRETARGETABLEREQUEST NS_DECL_NSIDNSLISTENER NS_DECL_NSICHANNELWITHDIVERTABLEPARENTLISTENER @@ -211,9 +208,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/nsIHstsPrimingCallback.idl b/netwerk/protocol/http/nsIHstsPrimingCallback.idl deleted file mode 100644 index 01f53a5b2..000000000 --- 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); -}; |