diff --git a/caps/BasePrincipal.cpp b/caps/BasePrincipal.cpp index 78b09bb249..c59ca5e37c 100644 --- a/caps/BasePrincipal.cpp +++ b/caps/BasePrincipal.cpp @@ -343,7 +343,8 @@ OriginAttributes::IsFirstPartyEnabled() return sFirstPartyIsolation; } -BasePrincipal::BasePrincipal() +BasePrincipal::BasePrincipal(PrincipalKind aKind) + : mKind(aKind) {} BasePrincipal::~BasePrincipal() diff --git a/caps/BasePrincipal.h b/caps/BasePrincipal.h index dd60d33746..1fa95b786e 100644 --- a/caps/BasePrincipal.h +++ b/caps/BasePrincipal.h @@ -251,7 +251,14 @@ public: class BasePrincipal : public nsJSPrincipals { public: - BasePrincipal(); + enum PrincipalKind { + eNullPrincipal, + eCodebasePrincipal, + eExpandedPrincipal, + eSystemPrincipal + }; + + explicit BasePrincipal(PrincipalKind aKind); enum DocumentDomainConsideration { DontConsiderDocumentDomain, ConsiderDocumentDomain}; bool Subsumes(nsIPrincipal* aOther, DocumentDomainConsideration aConsideration); @@ -301,17 +308,19 @@ public: uint32_t PrivateBrowsingId() const { return mOriginAttributes.mPrivateBrowsingId; } bool IsInIsolatedMozBrowserElement() const { return mOriginAttributes.mInIsolatedMozBrowser; } - enum PrincipalKind { - eNullPrincipal, - eCodebasePrincipal, - eExpandedPrincipal, - eSystemPrincipal - }; - - virtual PrincipalKind Kind() = 0; + PrincipalKind Kind() const { return mKind; } already_AddRefed CloneStrippingUserContextIdAndFirstPartyDomain(); + /** + * Returns true if this principal's CSP should override a document's CSP for + * loads that it triggers. Currently true only for expanded principals which + * subsume the document principal. + */ + bool OverridesCSP(nsIPrincipal* aDocumentPrincipal) { + return mKind == eExpandedPrincipal && Subsumes(aDocumentPrincipal, DontConsiderDocumentDomain); + } + protected: virtual ~BasePrincipal(); @@ -333,6 +342,7 @@ protected: nsCOMPtr mCSP; nsCOMPtr mPreloadCSP; PrincipalOriginAttributes mOriginAttributes; + PrincipalKind mKind; }; } // namespace mozilla diff --git a/caps/nsNullPrincipal.h b/caps/nsNullPrincipal.h index b294747730..01800cf4ce 100644 --- a/caps/nsNullPrincipal.h +++ b/caps/nsNullPrincipal.h @@ -36,7 +36,9 @@ public: // This should only be used by deserialization, and the factory constructor. // Other consumers should use the Create and CreateWithInheritedAttributes // methods. - nsNullPrincipal() {} + nsNullPrincipal() + : BasePrincipal(eNullPrincipal) + {} NS_DECL_NSISERIALIZABLE @@ -60,8 +62,6 @@ public: virtual nsresult GetScriptLocation(nsACString &aStr) override; - PrincipalKind Kind() override { return eNullPrincipal; } - protected: virtual ~nsNullPrincipal() {} diff --git a/caps/nsPrincipal.cpp b/caps/nsPrincipal.cpp index 169ee0cb8c..00ac01ecbe 100644 --- a/caps/nsPrincipal.cpp +++ b/caps/nsPrincipal.cpp @@ -64,10 +64,11 @@ nsPrincipal::InitializeStatics() } nsPrincipal::nsPrincipal() - : mCodebaseImmutable(false) + : BasePrincipal(eCodebasePrincipal) + , mCodebaseImmutable(false) , mDomainImmutable(false) , mInitialized(false) -{ } +{} nsPrincipal::~nsPrincipal() { @@ -514,6 +515,7 @@ struct OriginComparator nsExpandedPrincipal::nsExpandedPrincipal(nsTArray> &aWhiteList, const PrincipalOriginAttributes& aAttrs) + : BasePrincipal(eExpandedPrincipal) { // We force the principals to be sorted by origin so that nsExpandedPrincipal // origins can have a canonical form. diff --git a/caps/nsPrincipal.h b/caps/nsPrincipal.h index c122952c70..7acbf2520f 100644 --- a/caps/nsPrincipal.h +++ b/caps/nsPrincipal.h @@ -46,8 +46,6 @@ public: */ static void InitializeStatics(); - PrincipalKind Kind() override { return eCodebasePrincipal; } - nsCOMPtr mDomain; nsCOMPtr mCodebase; // If mCodebaseImmutable is true, mCodebase is non-null and immutable @@ -82,8 +80,6 @@ public: virtual nsresult GetScriptLocation(nsACString &aStr) override; nsresult GetOriginInternal(nsACString& aOrigin) override; - PrincipalKind Kind() override { return eExpandedPrincipal; } - protected: virtual ~nsExpandedPrincipal(); diff --git a/caps/nsSystemPrincipal.h b/caps/nsSystemPrincipal.h index 5faec50cfd..35c64d8cbd 100644 --- a/caps/nsSystemPrincipal.h +++ b/caps/nsSystemPrincipal.h @@ -36,7 +36,9 @@ public: NS_IMETHOD GetBaseDomain(nsACString& aBaseDomain) override; nsresult GetOriginInternal(nsACString& aOrigin) override; - nsSystemPrincipal() {} + nsSystemPrincipal() + : BasePrincipal(eSystemPrincipal) + {} virtual nsresult GetScriptLocation(nsACString &aStr) override; @@ -52,8 +54,6 @@ protected: { return true; } - - PrincipalKind Kind() override { return eSystemPrincipal; } }; #endif // nsSystemPrincipal_h__ diff --git a/dom/security/nsCSPService.cpp b/dom/security/nsCSPService.cpp index ec32889acf..eab7f48478 100644 --- a/dom/security/nsCSPService.cpp +++ b/dom/security/nsCSPService.cpp @@ -140,12 +140,18 @@ CSPService::ShouldLoad(uint32_t aContentType, return NS_OK; } - // query the principal of the document; if no document is passed, then - // fall back to using the requestPrincipal (e.g. service workers do not - // pass a document). + // Find a principal to retrieve the CSP from. If we don't have a context node + // (because, for instance, the load originates in a service worker), or the + // requesting principal's CSP overrides our document CSP, use the request + // principal. Otherwise, use the document principal. nsCOMPtr node(do_QueryInterface(aRequestContext)); - nsCOMPtr principal = node ? node->NodePrincipal() - : aRequestPrincipal; + nsCOMPtr principal; + if (!node || (aRequestPrincipal && + BasePrincipal::Cast(aRequestPrincipal)->OverridesCSP(node->NodePrincipal()))) { + principal = aRequestPrincipal; + } else { + principal = node->NodePrincipal(); + } if (!principal) { // if we can't query a principal, then there is nothing to do. return NS_OK;