mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-26 02:17:34 +09:00
Remove support and tests for HSTS priming from the tree. Fixes #384
This commit is contained in:
parent
96a0af1be8
commit
d4ac94cf3e
56 changed files with 26 additions and 1812 deletions
|
|
@ -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
|
||||
|
|
@ -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__
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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',
|
||||
|
|
|
|||
|
|
@ -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)) ) {
|
||||
|
|
@ -8185,107 +8145,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
|
||||
// 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
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
};
|
||||
Loading…
Add table
Add a link
Reference in a new issue