Bug 1323644 - Isolate the HSTS and HPKP storage by first party domain (DOM/DocShell) r=baku,ckerschb
MozReview-Commit-ID: AZUfZffsLxu
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -4989,37 +4989,40 @@ nsDocShell::DisplayLoadError(nsresult aE
if (errorClass == nsINSSErrorsService::ERROR_CLASS_BAD_CERT) {
error.AssignLiteral("nssBadCert");
// If this is an HTTP Strict Transport Security host or a pinned host
// and the certificate is bad, don't allow overrides (RFC 6797 section
// 12.1, HPKP draft spec section 2.6).
uint32_t flags =
UsePrivateBrowsing() ? nsISocketProvider::NO_PERMANENT_STORAGE : 0;
+ OriginAttributes originAttributes;
+ originAttributes.Inherit(mOriginAttributes);
bool isStsHost = false;
bool isPinnedHost = false;
if (XRE_IsParentProcess()) {
nsCOMPtr<nsISiteSecurityService> sss =
do_GetService(NS_SSSERVICE_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
rv = sss->IsSecureURI(nsISiteSecurityService::HEADER_HSTS, aURI,
- flags, nullptr, &isStsHost);
+ flags, originAttributes, nullptr, &isStsHost);
NS_ENSURE_SUCCESS(rv, rv);
rv = sss->IsSecureURI(nsISiteSecurityService::HEADER_HPKP, aURI,
- flags, nullptr, &isPinnedHost);
+ flags, originAttributes, nullptr,
+ &isPinnedHost);
NS_ENSURE_SUCCESS(rv, rv);
} else {
mozilla::dom::ContentChild* cc =
mozilla::dom::ContentChild::GetSingleton();
mozilla::ipc::URIParams uri;
SerializeURI(aURI, uri);
cc->SendIsSecureURI(nsISiteSecurityService::HEADER_HSTS, uri, flags,
- &isStsHost);
+ originAttributes, &isStsHost);
cc->SendIsSecureURI(nsISiteSecurityService::HEADER_HPKP, uri, flags,
- &isPinnedHost);
+ originAttributes, &isPinnedHost);
}
if (Preferences::GetBool(
"browser.xul.error_pages.expert_bad_cert", false)) {
cssClass.AssignLiteral("expertBadCert");
}
// HSTS/pinning takes precedence over the expert bad cert pref. We
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -3364,44 +3364,47 @@ ContentParent::RecvNSSU2FTokenSign(nsTAr
free(buffer);
if (NS_FAILED(rv)) {
return IPC_FAIL_NO_REASON(this);
}
return IPC_OK();
}
mozilla::ipc::IPCResult
-ContentParent::RecvIsSecureURI(const uint32_t& type,
- const URIParams& uri,
- const uint32_t& flags,
- bool* isSecureURI)
+ContentParent::RecvIsSecureURI(const uint32_t& aType,
+ const URIParams& aURI,
+ const uint32_t& aFlags,
+ const OriginAttributes& aOriginAttributes,
+ bool* aIsSecureURI)
{
nsCOMPtr<nsISiteSecurityService> sss(do_GetService(NS_SSSERVICE_CONTRACTID));
if (!sss) {
return IPC_FAIL_NO_REASON(this);
}
- nsCOMPtr<nsIURI> ourURI = DeserializeURI(uri);
+ nsCOMPtr<nsIURI> ourURI = DeserializeURI(aURI);
if (!ourURI) {
return IPC_FAIL_NO_REASON(this);
}
- nsresult rv = sss->IsSecureURI(type, ourURI, flags, nullptr, isSecureURI);
+ nsresult rv = sss->IsSecureURI(aType, ourURI, aFlags, aOriginAttributes, nullptr,
+ aIsSecureURI);
if (NS_FAILED(rv)) {
return IPC_FAIL_NO_REASON(this);
}
return IPC_OK();
}
mozilla::ipc::IPCResult
-ContentParent::RecvAccumulateMixedContentHSTS(const URIParams& aURI, const bool& aActive, const bool& aHSTSPriming)
+ContentParent::RecvAccumulateMixedContentHSTS(const URIParams& aURI, const bool& aActive, const bool& aHSTSPriming,
+ const OriginAttributes& aOriginAttributes)
{
nsCOMPtr<nsIURI> ourURI = DeserializeURI(aURI);
if (!ourURI) {
return IPC_FAIL_NO_REASON(this);
}
- nsMixedContentBlocker::AccumulateMixedContentHSTS(ourURI, aActive, aHSTSPriming);
+ nsMixedContentBlocker::AccumulateMixedContentHSTS(ourURI, aActive, aHSTSPriming, aOriginAttributes);
return IPC_OK();
}
mozilla::ipc::IPCResult
ContentParent::RecvLoadURIExternal(const URIParams& uri,
PBrowserParent* windowContext)
{
nsCOMPtr<nsIExternalProtocolService> extProtService(do_GetService(NS_EXTERNALPROTOCOLSERVICE_CONTRACTID));
--- a/dom/ipc/ContentParent.h
+++ b/dom/ipc/ContentParent.h
@@ -799,21 +799,24 @@ private:
nsTArray<uint8_t>* aRegistration) override;
virtual mozilla::ipc::IPCResult RecvNSSU2FTokenSign(nsTArray<uint8_t>&& aApplication,
nsTArray<uint8_t>&& aChallenge,
nsTArray<uint8_t>&& aKeyHandle,
nsTArray<uint8_t>* aSignature) override;
virtual mozilla::ipc::IPCResult RecvIsSecureURI(const uint32_t& aType, const URIParams& aURI,
- const uint32_t& aFlags, bool* aIsSecureURI) override;
+ const uint32_t& aFlags,
+ const OriginAttributes& aOriginAttributes,
+ bool* aIsSecureURI) override;
virtual mozilla::ipc::IPCResult RecvAccumulateMixedContentHSTS(const URIParams& aURI,
const bool& aActive,
- const bool& aHSTSPriming) override;
+ const bool& aHSTSPriming,
+ const OriginAttributes& aOriginAttributes) override;
virtual bool DeallocPHalParent(PHalParent*) override;
virtual bool
DeallocPHeapSnapshotTempFileHelperParent(PHeapSnapshotTempFileHelperParent*) override;
virtual PCycleCollectWithLogsParent*
AllocPCycleCollectWithLogsParent(const bool& aDumpAllTraces,
--- a/dom/ipc/PContent.ipdl
+++ b/dom/ipc/PContent.ipdl
@@ -785,20 +785,22 @@ parent:
* |challenge| The Challenge to satisfy in the response.
* |keyHandle| The Key Handle opaque object to use.
* |signature| The resulting signature.
*/
sync NSSU2FTokenSign(uint8_t[] application, uint8_t[] challenge,
uint8_t[] keyHandle)
returns (uint8_t[] signature);
- sync IsSecureURI(uint32_t type, URIParams uri, uint32_t flags)
+ sync IsSecureURI(uint32_t aType, URIParams aURI, uint32_t aFlags,
+ OriginAttributes aOriginAttributes)
returns (bool isSecureURI);
- async AccumulateMixedContentHSTS(URIParams uri, bool active, bool hasHSTSPriming);
+ async AccumulateMixedContentHSTS(URIParams aURI, bool aActive, bool aHasHSTSPriming,
+ OriginAttributes aOriginAttributes);
nested(inside_cpow) async PHal();
async PHeapSnapshotTempFileHelper();
async PNecko();
async PPrinting();
--- a/dom/security/nsMixedContentBlocker.cpp
+++ b/dom/security/nsMixedContentBlocker.cpp
@@ -859,25 +859,32 @@ nsMixedContentBlocker::ShouldLoad(bool a
// If there is no securityUI, document doesn't have a security state.
// Allow load and return early.
if (!securityUI) {
*aDecision = nsIContentPolicy::ACCEPT;
return NS_OK;
}
nsresult stateRV = securityUI->GetState(&state);
+ OriginAttributes originAttributes;
+ if (principal) {
+ originAttributes.Inherit(principal->OriginAttributesRef());
+ } else if (aRequestPrincipal) {
+ originAttributes.Inherit(aRequestPrincipal->OriginAttributesRef());
+ }
+
bool doHSTSPriming = false;
if (IsEligibleForHSTSPriming(aContentLocation)) {
bool hsts = false;
bool cached = false;
nsCOMPtr<nsISiteSecurityService> sss =
do_GetService(NS_SSSERVICE_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
rv = sss->IsSecureURI(nsISiteSecurityService::HEADER_HSTS, aContentLocation,
- 0, &cached, &hsts);
+ 0, originAttributes, &cached, &hsts);
NS_ENSURE_SUCCESS(rv, rv);
if (hsts && sUseHSTS) {
// assume we will be upgraded later
*aDecision = ACCEPT;
return NS_OK;
}
@@ -902,24 +909,26 @@ nsMixedContentBlocker::ShouldLoad(bool a
// is not blocked (e.g., for images). For more detail, see:
// https://bugzilla.mozilla.org/show_bug.cgi?id=1198572#c19
//
// We do not count requests aHadInsecureImageRedirect=true, since these are
// just an artifact of the image caching system.
bool active = (classification == eMixedScript);
if (!aHadInsecureImageRedirect) {
if (XRE_IsParentProcess()) {
- AccumulateMixedContentHSTS(innerContentLocation, active, doHSTSPriming);
+ AccumulateMixedContentHSTS(innerContentLocation, active, doHSTSPriming,
+ originAttributes);
} 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, doHSTSPriming,
+ originAttributes);
}
}
}
// set hasMixedContentObjectSubrequest on this object if necessary
if (aContentType == TYPE_OBJECT_SUBREQUEST) {
rootDoc->SetHasMixedContentObjectSubrequest(true);
}
@@ -1092,32 +1101,35 @@ enum MixedContentHSTSPrimingState {
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, bool aHasHSTSPriming,
+ const OriginAttributes& aOriginAttributes)
{
// This method must only be called in the parent, because
// nsSiteSecurityService is only available in the parent
if (!XRE_IsParentProcess()) {
MOZ_ASSERT(false);
return;
}
bool hsts;
nsresult rv;
nsCOMPtr<nsISiteSecurityService> sss = do_GetService(NS_SSSERVICE_CONTRACTID, &rv);
if (NS_FAILED(rv)) {
return;
}
- rv = sss->IsSecureURI(nsISiteSecurityService::HEADER_HSTS, aURI, 0, nullptr, &hsts);
+ rv = sss->IsSecureURI(nsISiteSecurityService::HEADER_HSTS, aURI, 0,
+ aOriginAttributes, nullptr, &hsts);
if (NS_FAILED(rv)) {
return;
}
// states: would upgrade, would prime, hsts info cached
// active, passive
//
if (!aActive) {
--- a/dom/security/nsMixedContentBlocker.h
+++ b/dom/security/nsMixedContentBlocker.h
@@ -23,16 +23,18 @@ enum MixedContentTypes {
eMixedDisplay
};
#include "nsIContentPolicy.h"
#include "nsIChannel.h"
#include "nsIChannelEventSink.h"
#include "imgRequest.h"
+using mozilla::OriginAttributes;
+
class nsILoadInfo; // forward declaration
class nsMixedContentBlocker : public nsIContentPolicy,
public nsIChannelEventSink
{
private:
virtual ~nsMixedContentBlocker();
@@ -58,17 +60,18 @@ public:
nsIURI* aRequestingLocation,
nsISupports* aRequestingContext,
const nsACString& aMimeGuess,
nsISupports* aExtra,
nsIPrincipal* aRequestPrincipal,
int16_t* aDecision);
static void AccumulateMixedContentHSTS(nsIURI* aURI,
bool aActive,
- bool aHasHSTSPriming);
+ bool aHasHSTSPriming,
+ const OriginAttributes& aOriginAttributes);
/* If the document associated with aRequestingContext requires priming for
* aURI, propagate that to the LoadInfo so the HttpChannel will find out about
* it.
*
* @param aURI The URI associated with the load
* @param aRequestingContext the requesting context passed to ShouldLoad
* @param aLoadInfo the LoadInfo for the load
*/