diff --git a/caps/BasePrincipal.cpp b/caps/BasePrincipal.cpp index ebc8dbb2ab6f..8a3a334acb1d 100644 --- a/caps/BasePrincipal.cpp +++ b/caps/BasePrincipal.cpp @@ -455,37 +455,6 @@ BasePrincipal::CloneStrippingUserContextIdAndFirstPartyDomain() { return BasePrincipal::CreateCodebasePrincipal(uri, attrs); } -already_AddRefed BasePrincipal::CloneForcingFirstPartyDomain( - nsIURI* aURI) { - if (NS_WARN_IF(!IsCodebasePrincipal())) { - return nullptr; - } - - OriginAttributes attrs = OriginAttributesRef(); - // XXX this is slow. Maybe we should consider to make it faster. - attrs.SetFirstPartyDomain(false, aURI, true /* aForced */); - - return CloneForcingOriginAttributes(attrs); -} - -already_AddRefed BasePrincipal::CloneForcingOriginAttributes( - const OriginAttributes& aOriginAttributes) { - if (NS_WARN_IF(!IsCodebasePrincipal())) { - return nullptr; - } - - nsAutoCString originNoSuffix; - nsresult rv = GetOriginNoSuffix(originNoSuffix); - NS_ENSURE_SUCCESS(rv, nullptr); - - nsIURI* uri = static_cast(this)->mCodebase; - RefPtr copy = new ContentPrincipal(); - rv = copy->Init(uri, aOriginAttributes, originNoSuffix); - NS_ENSURE_SUCCESS(rv, nullptr); - - return copy.forget(); -} - extensions::WebExtensionPolicy* BasePrincipal::ContentScriptAddonPolicy() { if (!Is()) { return nullptr; diff --git a/caps/BasePrincipal.h b/caps/BasePrincipal.h index e93bfab318dc..27a497b66aaa 100644 --- a/caps/BasePrincipal.h +++ b/caps/BasePrincipal.h @@ -169,11 +169,6 @@ class BasePrincipal : public nsJSPrincipals { already_AddRefed CloneStrippingUserContextIdAndFirstPartyDomain(); - already_AddRefed CloneForcingFirstPartyDomain(nsIURI* aURI); - - already_AddRefed CloneForcingOriginAttributes( - const OriginAttributes& aOriginAttributes); - // If this is an add-on content script principal, returns its AddonPolicy. // Otherwise returns null. extensions::WebExtensionPolicy* ContentScriptAddonPolicy(); diff --git a/caps/OriginAttributes.cpp b/caps/OriginAttributes.cpp index 4d7ddf1b1480..f1e86011df92 100644 --- a/caps/OriginAttributes.cpp +++ b/caps/OriginAttributes.cpp @@ -38,11 +38,11 @@ void OriginAttributes::InitPrefs() { } void OriginAttributes::SetFirstPartyDomain(const bool aIsTopLevelDocument, - nsIURI* aURI, bool aForced) { + nsIURI* aURI) { bool isFirstPartyEnabled = IsFirstPartyEnabled(); - // If the prefs are off or this is not a top level load, bail out. - if ((!isFirstPartyEnabled || !aIsTopLevelDocument) && !aForced) { + // If the pref is off or this is not a top level load, bail out. + if (!isFirstPartyEnabled || !aIsTopLevelDocument) { return; } diff --git a/caps/OriginAttributes.h b/caps/OriginAttributes.h index 582265b29006..0e6a1dc14d01 100644 --- a/caps/OriginAttributes.h +++ b/caps/OriginAttributes.h @@ -25,8 +25,7 @@ class OriginAttributes : public dom::OriginAttributesDictionary { explicit OriginAttributes(const OriginAttributesDictionary& aOther) : OriginAttributesDictionary(aOther) {} - void SetFirstPartyDomain(const bool aIsTopLevelDocument, nsIURI* aURI, - bool aForced = false); + void SetFirstPartyDomain(const bool aIsTopLevelDocument, nsIURI* aURI); void SetFirstPartyDomain(const bool aIsTopLevelDocument, const nsACString& aDomain); diff --git a/caps/nsIScriptSecurityManager.idl b/caps/nsIScriptSecurityManager.idl index ccf8a8fa747b..03b08cef0a6a 100644 --- a/caps/nsIScriptSecurityManager.idl +++ b/caps/nsIScriptSecurityManager.idl @@ -197,7 +197,6 @@ interface nsIScriptSecurityManager : nsISupports in nsIURI aTargetURI, in boolean reportError, in boolean fromPrivateWindow); - /** * Get the principal for the given channel. This will typically be the * channel owner if there is one, and the codebase principal for the @@ -205,23 +204,6 @@ interface nsIScriptSecurityManager : nsISupports */ nsIPrincipal getChannelResultPrincipal(in nsIChannel aChannel); - /** - * Get the storage principal for the given channel. This is basically the - * same of getChannelResultPrincipal() execept for trackers, where we - * return a principal with a different OriginAttributes. - */ - nsIPrincipal getChannelResultStoragePrincipal(in nsIChannel aChannel); - - /** - * This method does getChannelResultPrincipal() + - * getChannelResultStoragePrincipal(). - * This method is mainly done for Document::Reset(). There are no other - * reasons to use this method. - */ - void getChannelResultPrincipals(in nsIChannel aChannel, - out nsIPrincipal aPrincipal, - out nsIPrincipal aStoragePrincipal); - /** * Temporary API until bug 1220687 is fixed. * diff --git a/caps/nsScriptSecurityManager.cpp b/caps/nsScriptSecurityManager.cpp index 64d0f6609260..535c4d902a0b 100644 --- a/caps/nsScriptSecurityManager.cpp +++ b/caps/nsScriptSecurityManager.cpp @@ -7,7 +7,6 @@ #include "nsScriptSecurityManager.h" #include "mozilla/ArrayUtils.h" -#include "mozilla/StoragePrincipalHelper.h" #include "xpcpublic.h" #include "XPCWrapper.h" @@ -246,33 +245,6 @@ nsresult nsScriptSecurityManager::GetChannelResultPrincipalIfNotSandboxed( /*aIgnoreSandboxing*/ true); } -NS_IMETHODIMP -nsScriptSecurityManager::GetChannelResultStoragePrincipal( - nsIChannel* aChannel, nsIPrincipal** aPrincipal) { - nsCOMPtr principal; - nsresult rv = GetChannelResultPrincipal(aChannel, getter_AddRefs(principal), - /*aIgnoreSandboxing*/ false); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - - return StoragePrincipalHelper::Create(aChannel, principal, aPrincipal); -} - -NS_IMETHODIMP -nsScriptSecurityManager::GetChannelResultPrincipals( - nsIChannel* aChannel, nsIPrincipal** aPrincipal, - nsIPrincipal** aStoragePrincipal) { - nsresult rv = GetChannelResultPrincipal(aChannel, aPrincipal, - /*aIgnoreSandboxing*/ false); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - - return StoragePrincipalHelper::Create(aChannel, *aPrincipal, - aStoragePrincipal); -} - static void InheritAndSetCSPOnPrincipalIfNeeded(nsIChannel* aChannel, nsIPrincipal* aPrincipal) { // loading a data: URI into an iframe, or loading frame[srcdoc] need diff --git a/dom/base/Document.cpp b/dom/base/Document.cpp index a84368f7ad3d..7000333b3db4 100644 --- a/dom/base/Document.cpp +++ b/dom/base/Document.cpp @@ -1923,32 +1923,23 @@ bool Document::IsVisibleConsideringAncestors() const { void Document::Reset(nsIChannel* aChannel, nsILoadGroup* aLoadGroup) { nsCOMPtr uri; nsCOMPtr principal; - nsCOMPtr storagePrincipal; if (aChannel) { // Note: this code is duplicated in XULDocument::StartDocumentLoad and - // nsScriptSecurityManager::GetChannelResultPrincipals. + // nsScriptSecurityManager::GetChannelResultPrincipal. // Note: this should match nsDocShell::OnLoadingSite NS_GetFinalChannelURI(aChannel, getter_AddRefs(uri)); nsIScriptSecurityManager* securityManager = nsContentUtils::GetSecurityManager(); if (securityManager) { - securityManager->GetChannelResultPrincipals( - aChannel, getter_AddRefs(principal), - getter_AddRefs(storagePrincipal)); + securityManager->GetChannelResultPrincipal(aChannel, + getter_AddRefs(principal)); } } - bool equal = principal->Equals(storagePrincipal); - principal = MaybeDowngradePrincipal(principal); - if (equal) { - storagePrincipal = principal; - } else { - storagePrincipal = MaybeDowngradePrincipal(storagePrincipal); - } - ResetToURI(uri, aLoadGroup, principal, storagePrincipal); + ResetToURI(uri, aLoadGroup, principal); // Note that, since mTiming does not change during a reset, the // navigationStart time remains unchanged and therefore any future new @@ -2040,10 +2031,8 @@ void Document::DisconnectNodeTree() { } void Document::ResetToURI(nsIURI* aURI, nsILoadGroup* aLoadGroup, - nsIPrincipal* aPrincipal, - nsIPrincipal* aStoragePrincipal) { + nsIPrincipal* aPrincipal) { MOZ_ASSERT(aURI, "Null URI passed to ResetToURI"); - MOZ_ASSERT(!!aPrincipal == !!aStoragePrincipal); MOZ_LOG(gDocumentLeakPRLog, LogLevel::Debug, ("DOCUMENT %p ResetToURI %s", this, aURI->GetSpecOrDefault().get())); @@ -2073,7 +2062,7 @@ void Document::ResetToURI(nsIURI* aURI, nsILoadGroup* aLoadGroup, // This ensures that, during teardown, the document and the dying window // (which already nulled out its document pointer and cached the principal) // have matching principals. - SetPrincipals(nullptr, nullptr); + SetPrincipal(nullptr); // Clear the original URI so SetDocumentURI sets it. mOriginalURI = nullptr; @@ -2121,7 +2110,7 @@ void Document::ResetToURI(nsIURI* aURI, nsILoadGroup* aLoadGroup, // Now get our new principal if (aPrincipal) { - SetPrincipals(aPrincipal, aStoragePrincipal); + SetPrincipal(aPrincipal); } else { nsIScriptSecurityManager* securityManager = nsContentUtils::GetSecurityManager(); @@ -2141,7 +2130,7 @@ void Document::ResetToURI(nsIURI* aURI, nsILoadGroup* aLoadGroup, nsresult rv = securityManager->GetLoadContextCodebasePrincipal( mDocumentURI, loadContext, getter_AddRefs(principal)); if (NS_SUCCEEDED(rv)) { - SetPrincipals(principal, principal); + SetPrincipal(principal); } } } @@ -2804,7 +2793,7 @@ nsresult Document::InitCSP(nsIChannel* aChannel) { if (needNewNullPrincipal) { principal = NullPrincipal::CreateWithInheritedAttributes(principal); principal->SetCsp(csp); - SetPrincipals(principal, principal); + SetPrincipal(principal); } // ----- Enforce frame-ancestor policy on any applied policies @@ -3028,9 +3017,7 @@ void Document::RemoveFromIdTable(Element* aElement, nsAtom* aId) { } } -void Document::SetPrincipals(nsIPrincipal* aNewPrincipal, - nsIPrincipal* aNewStoragePrincipal) { - MOZ_ASSERT(!!aNewPrincipal == !!aNewStoragePrincipal); +void Document::SetPrincipal(nsIPrincipal* aNewPrincipal) { if (aNewPrincipal && mAllowDNSPrefetch && sDisablePrefetchHTTPSPref) { nsCOMPtr uri; aNewPrincipal->GetURI(getter_AddRefs(uri)); @@ -3040,7 +3027,6 @@ void Document::SetPrincipals(nsIPrincipal* aNewPrincipal, } } mNodeInfoManager->SetDocumentPrincipal(aNewPrincipal); - mIntrinsicStoragePrincipal = aNewStoragePrincipal; #ifdef DEBUG // Validate that the docgroup is set correctly by calling its getter and @@ -8207,8 +8193,7 @@ nsresult Document::CloneDocHelper(Document* clone) const { } clone->mChannel = channel; if (uri) { - clone->ResetToURI(uri, loadGroup, NodePrincipal(), - EffectiveStoragePrincipal()); + clone->ResetToURI(uri, loadGroup, NodePrincipal()); } clone->SetContainer(mDocumentContainer); @@ -8222,7 +8207,7 @@ nsresult Document::CloneDocHelper(Document* clone) const { // them. clone->SetDocumentURI(Document::GetDocumentURI()); clone->SetChromeXHRDocURI(mChromeXHRDocURI); - clone->SetPrincipals(NodePrincipal(), EffectiveStoragePrincipal()); + clone->SetPrincipal(NodePrincipal()); clone->mDocumentBaseURI = mDocumentBaseURI; clone->SetChromeXHRDocBaseURI(mChromeXHRDocBaseURI); @@ -12844,23 +12829,5 @@ nsICookieSettings* Document::CookieSettings() { return mCookieSettings; } -nsIPrincipal* Document::EffectiveStoragePrincipal() const { - if (!StaticPrefs::privacy_storagePrincipal_enabledForTrackers()) { - return NodePrincipal(); - } - - nsContentUtils::StorageAccess access = - nsContentUtils::StorageAllowedForDocument(this); - - // Let's use the storage principal only if we need to partition the cookie - // jar. When the permission is granted, access will be different and the - // normal principal will be used. - if (access != nsContentUtils::StorageAccess::ePartitionedOrDeny) { - return NodePrincipal(); - } - - return mIntrinsicStoragePrincipal; -} - } // namespace dom } // namespace mozilla diff --git a/dom/base/Document.h b/dom/base/Document.h index c5c0620bb150..df3f7932cdbc 100644 --- a/dom/base/Document.h +++ b/dom/base/Document.h @@ -523,15 +523,9 @@ class Document : public nsINode, return DocumentOrShadowRoot::SetValueMissingState(aName, aValue); } - nsIPrincipal* EffectiveStoragePrincipal() const; - // nsIScriptObjectPrincipal nsIPrincipal* GetPrincipal() final { return NodePrincipal(); } - nsIPrincipal* GetEffectiveStoragePrincipal() final { - return EffectiveStoragePrincipal(); - } - // EventTarget void GetEventTargetParent(EventChainPreVisitor& aVisitor) override; EventListenerManager* GetOrCreateListenerManager() override; @@ -731,10 +725,10 @@ class Document : public nsINode, void SetReferrer(const nsACString& aReferrer) { mReferrer = aReferrer; } /** - * Set the principals responsible for this document. Chances are, you do not - * want to be using this. + * Set the principal responsible for this document. Chances are, + * you do not want to be using this. */ - void SetPrincipals(nsIPrincipal* aPrincipal, nsIPrincipal* aStoragePrincipal); + void SetPrincipal(nsIPrincipal* aPrincipal); /** * Get the list of ancestor principals for a document. This is the same as @@ -2092,13 +2086,12 @@ class Document : public nsINode, virtual void Reset(nsIChannel* aChannel, nsILoadGroup* aLoadGroup); /** - * Reset this document to aURI, aLoadGroup, aPrincipal and aStoragePrincipal. - * aURI must not be null. If aPrincipal is null, a codebase principal based - * on aURI will be used. + * Reset this document to aURI, aLoadGroup, and aPrincipal. aURI must not be + * null. If aPrincipal is null, a codebase principal based on aURI will be + * used. */ virtual void ResetToURI(nsIURI* aURI, nsILoadGroup* aLoadGroup, - nsIPrincipal* aPrincipal, - nsIPrincipal* aStoragePrincipal); + nsIPrincipal* aPrincipal); /** * Set the container (docshell) for this document. Virtual so that @@ -4741,9 +4734,6 @@ class Document : public nsINode, bool mInRDMPane; - // The principal to use for the storage area of this document. - nsCOMPtr mIntrinsicStoragePrincipal; - public: // Needs to be public because the bindings code pokes at it. js::ExpandoAndGeneration mExpandoAndGeneration; diff --git a/dom/base/nsContentUtils.cpp b/dom/base/nsContentUtils.cpp index 50fd8fc93b8e..4a48372128a4 100644 --- a/dom/base/nsContentUtils.cpp +++ b/dom/base/nsContentUtils.cpp @@ -8226,7 +8226,7 @@ nsContentUtils::StorageAccess nsContentUtils::StorageAllowedForWindow( // static, public nsContentUtils::StorageAccess nsContentUtils::StorageAllowedForDocument( - const Document* aDoc) { + Document* aDoc) { MOZ_ASSERT(aDoc); if (nsPIDOMWindowInner* inner = aDoc->GetInnerWindow()) { diff --git a/dom/base/nsContentUtils.h b/dom/base/nsContentUtils.h index 4e524885a596..28ddcaf7dc55 100644 --- a/dom/base/nsContentUtils.h +++ b/dom/base/nsContentUtils.h @@ -2995,7 +2995,7 @@ class nsContentUtils { * the window's extant document has not been set yet. The code in * StorageAllowedForWindow(), however, will not work in these cases. */ - static StorageAccess StorageAllowedForDocument(const Document* aDoc); + static StorageAccess StorageAllowedForDocument(Document* aDoc); /* * Checks if storage should be allowed for a new window with the given diff --git a/dom/base/nsGlobalWindowInner.cpp b/dom/base/nsGlobalWindowInner.cpp index 659c623a2792..0804942ab1a3 100644 --- a/dom/base/nsGlobalWindowInner.cpp +++ b/dom/base/nsGlobalWindowInner.cpp @@ -1128,7 +1128,6 @@ void nsGlobalWindowInner::FreeInnerObjects() { if (mDoc) { // Remember the document's principal and URI. mDocumentPrincipal = mDoc->NodePrincipal(); - mDocumentStoragePrincipal = mDoc->EffectiveStoragePrincipal(); mDocumentURI = mDoc->GetDocumentURI(); mDocBaseURI = mDoc->GetDocBaseURI(); @@ -1358,7 +1357,6 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(nsGlobalWindowInner) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mApplicationCache) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mIndexedDB) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDocumentPrincipal) - NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDocumentStoragePrincipal) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mTabChild) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDoc) @@ -1462,7 +1460,6 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsGlobalWindowInner) NS_IMPL_CYCLE_COLLECTION_UNLINK(mIndexedDB) } NS_IMPL_CYCLE_COLLECTION_UNLINK(mDocumentPrincipal) - NS_IMPL_CYCLE_COLLECTION_UNLINK(mDocumentStoragePrincipal) NS_IMPL_CYCLE_COLLECTION_UNLINK(mTabChild) NS_IMPL_CYCLE_COLLECTION_UNLINK(mDoc) @@ -2051,29 +2048,6 @@ nsIPrincipal* nsGlobalWindowInner::GetPrincipal() { return nullptr; } -nsIPrincipal* nsGlobalWindowInner::GetEffectiveStoragePrincipal() { - if (mDoc) { - // If we have a document, get the principal from the document - return mDoc->EffectiveStoragePrincipal(); - } - - if (mDocumentStoragePrincipal) { - return mDocumentStoragePrincipal; - } - - // If we don't have a storage principal and we don't have a document we ask - // the parent window for the storage principal. - - nsCOMPtr objPrincipal = - do_QueryInterface(GetParentInternal()); - - if (objPrincipal) { - return objPrincipal->GetEffectiveStoragePrincipal(); - } - - return nullptr; -} - //***************************************************************************** // nsGlobalWindowInner::nsIDOMWindow //***************************************************************************** @@ -2821,9 +2795,10 @@ bool nsGlobalWindowInner::MayResolve(jsid aId) { return WebIDLGlobalNameHash::MayResolve(aId); } -void nsGlobalWindowInner::GetOwnPropertyNames( - JSContext* aCx, JS::MutableHandleVector aNames, bool aEnumerableOnly, - ErrorResult& aRv) { +void nsGlobalWindowInner::GetOwnPropertyNames(JSContext* aCx, + JS::MutableHandleVector aNames, + bool aEnumerableOnly, + ErrorResult& aRv) { if (aEnumerableOnly) { // The names we would return from here get defined on the window via one of // two codepaths. The ones coming from the WebIDLGlobalNameHash will end up @@ -6897,9 +6872,6 @@ void nsGlobalWindowInner::StorageAccessGranted() { object->EnsureObserver(); } } - - // Reset the IndexedDB factory. - mIndexedDB = nullptr; } mozilla::dom::TabGroup* nsPIDOMWindowInner::TabGroup() { diff --git a/dom/base/nsGlobalWindowInner.h b/dom/base/nsGlobalWindowInner.h index 6975c69eb9e6..c026bc252e9a 100644 --- a/dom/base/nsGlobalWindowInner.h +++ b/dom/base/nsGlobalWindowInner.h @@ -260,8 +260,6 @@ class nsGlobalWindowInner final : public mozilla::dom::EventTarget, // nsIScriptObjectPrincipal virtual nsIPrincipal* GetPrincipal() override; - virtual nsIPrincipal* GetEffectiveStoragePrincipal() override; - // nsIDOMWindow NS_DECL_NSIDOMWINDOW @@ -1296,8 +1294,6 @@ class nsGlobalWindowInner final : public mozilla::dom::EventTarget, RefPtr mVisualViewport; nsCOMPtr mDocumentPrincipal; - nsCOMPtr mDocumentStoragePrincipal; - // mTabChild is only ever populated in the content process. nsCOMPtr mTabChild; diff --git a/dom/base/nsGlobalWindowOuter.cpp b/dom/base/nsGlobalWindowOuter.cpp index 3db2319be1de..c3917c8a4880 100644 --- a/dom/base/nsGlobalWindowOuter.cpp +++ b/dom/base/nsGlobalWindowOuter.cpp @@ -476,9 +476,8 @@ class nsOuterWindowProxy : public MaybeCrossOriginObject { * "proxy" is the WindowProxy object involved. It may not be same-compartment * with cx. */ - bool getOwnEnumerablePropertyKeys( - JSContext* cx, JS::Handle proxy, - JS::MutableHandleVector props) const override; + bool getOwnEnumerablePropertyKeys(JSContext* cx, JS::Handle proxy, + JS::MutableHandleVector props) const override; /** * Hook used by SpiderMonkey to implement Object.prototype.toString. @@ -734,9 +733,9 @@ bool nsOuterWindowProxy::definePropertySameOrigin( return true; } -bool nsOuterWindowProxy::ownPropertyKeys( - JSContext* cx, JS::Handle proxy, - JS::MutableHandleVector props) const { +bool nsOuterWindowProxy::ownPropertyKeys(JSContext* cx, + JS::Handle proxy, + JS::MutableHandleVector props) const { // Just our indexed stuff followed by our "normal" own property names. if (!AppendIndexedPropertyNames(proxy, props)) { return false; @@ -939,8 +938,7 @@ bool nsOuterWindowProxy::set(JSContext* cx, JS::Handle proxy, } bool nsOuterWindowProxy::getOwnEnumerablePropertyKeys( - JSContext* cx, JS::Handle proxy, - JS::MutableHandleVector props) const { + JSContext* cx, JS::Handle proxy, JS::MutableHandleVector props) const { // We could just stop overring getOwnEnumerablePropertyKeys and let our // superclasses deal (by falling back on the BaseProxyHandler implementation // that uses a combination of ownPropertyKeys and getOwnPropertyDescriptor to @@ -1403,7 +1401,6 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(nsGlobalWindowOuter) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mLocalStorage) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSuspendedDoc) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDocumentPrincipal) - NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDocumentStoragePrincipal) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDoc) // Traverse stuff from nsPIDOMWindow @@ -1430,7 +1427,6 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsGlobalWindowOuter) NS_IMPL_CYCLE_COLLECTION_UNLINK(mLocalStorage) NS_IMPL_CYCLE_COLLECTION_UNLINK(mSuspendedDoc) NS_IMPL_CYCLE_COLLECTION_UNLINK(mDocumentPrincipal) - NS_IMPL_CYCLE_COLLECTION_UNLINK(mDocumentStoragePrincipal) NS_IMPL_CYCLE_COLLECTION_UNLINK(mDoc) // Unlink stuff from nsPIDOMWindow @@ -1898,8 +1894,6 @@ nsresult nsGlobalWindowOuter::SetNewDocument(Document* aDocument, bool aForceReuseInnerWindow) { MOZ_ASSERT(mDocumentPrincipal == nullptr, "mDocumentPrincipal prematurely set!"); - MOZ_ASSERT(mDocumentStoragePrincipal == nullptr, - "mDocumentStoragePrincipal prematurely set!"); MOZ_ASSERT(aDocument); // Bail out early if we're in process of closing down the window. @@ -2452,7 +2446,6 @@ void nsGlobalWindowOuter::DetachFromDocShell() { // Remember the document's principal and URI. mDocumentPrincipal = mDoc->NodePrincipal(); - mDocumentStoragePrincipal = mDoc->EffectiveStoragePrincipal(); mDocumentURI = mDoc->GetDocumentURI(); // Release our document reference @@ -2768,29 +2761,6 @@ nsIPrincipal* nsGlobalWindowOuter::GetPrincipal() { return nullptr; } -nsIPrincipal* nsGlobalWindowOuter::GetEffectiveStoragePrincipal() { - if (mDoc) { - // If we have a document, get the principal from the document - return mDoc->EffectiveStoragePrincipal(); - } - - if (mDocumentStoragePrincipal) { - return mDocumentStoragePrincipal; - } - - // If we don't have a storage principal and we don't have a document we ask - // the parent window for the storage principal. - - nsCOMPtr objPrincipal = - do_QueryInterface(GetParentInternal()); - - if (objPrincipal) { - return objPrincipal->GetEffectiveStoragePrincipal(); - } - - return nullptr; -} - //***************************************************************************** // nsGlobalWindowOuter::nsIDOMWindow //***************************************************************************** diff --git a/dom/base/nsGlobalWindowOuter.h b/dom/base/nsGlobalWindowOuter.h index 1f9e3998c743..50b38f91ef6f 100644 --- a/dom/base/nsGlobalWindowOuter.h +++ b/dom/base/nsGlobalWindowOuter.h @@ -247,8 +247,6 @@ class nsGlobalWindowOuter final : public mozilla::dom::EventTarget, // nsIScriptObjectPrincipal virtual nsIPrincipal* GetPrincipal() override; - virtual nsIPrincipal* GetEffectiveStoragePrincipal() override; - // nsIDOMWindow NS_DECL_NSIDOMWINDOW @@ -1100,7 +1098,6 @@ class nsGlobalWindowOuter final : public mozilla::dom::EventTarget, RefPtr mLocalStorage; nsCOMPtr mDocumentPrincipal; - nsCOMPtr mDocumentStoragePrincipal; #ifdef DEBUG uint32_t mSerial; diff --git a/dom/base/nsIScriptObjectPrincipal.h b/dom/base/nsIScriptObjectPrincipal.h index 48087f395684..4207086542b4 100644 --- a/dom/base/nsIScriptObjectPrincipal.h +++ b/dom/base/nsIScriptObjectPrincipal.h @@ -26,8 +26,6 @@ class nsIScriptObjectPrincipal : public nsISupports { NS_DECLARE_STATIC_IID_ACCESSOR(NS_ISCRIPTOBJECTPRINCIPAL_IID) virtual nsIPrincipal* GetPrincipal() = 0; - - virtual nsIPrincipal* GetEffectiveStoragePrincipal() = 0; }; NS_DEFINE_STATIC_IID_ACCESSOR(nsIScriptObjectPrincipal, diff --git a/dom/broadcastchannel/BroadcastChannel.cpp b/dom/broadcastchannel/BroadcastChannel.cpp index d249a63ed211..230088b80480 100644 --- a/dom/broadcastchannel/BroadcastChannel.cpp +++ b/dom/broadcastchannel/BroadcastChannel.cpp @@ -48,12 +48,11 @@ class BroadcastChannelMessage final : public StructuredCloneDataNoTransfers { namespace { -nsIPrincipal* GetStoragePrincipalFromThreadSafeWorkerRef( +nsIPrincipal* GetPrincipalFromThreadSafeWorkerRef( ThreadSafeWorkerRef* aWorkerRef) { - nsIPrincipal* storagePrincipal = - aWorkerRef->Private()->GetEffectiveStoragePrincipal(); - if (storagePrincipal) { - return storagePrincipal; + nsIPrincipal* principal = aWorkerRef->Private()->GetPrincipal(); + if (principal) { + return principal; } // Walk up to our containing page @@ -62,19 +61,19 @@ nsIPrincipal* GetStoragePrincipalFromThreadSafeWorkerRef( wp = wp->GetParent(); } - return wp->GetEffectiveStoragePrincipal(); + return wp->GetPrincipal(); } class InitializeRunnable final : public WorkerMainThreadRunnable { public: InitializeRunnable(ThreadSafeWorkerRef* aWorkerRef, nsACString& aOrigin, - PrincipalInfo& aStoragePrincipalInfo, ErrorResult& aRv) + PrincipalInfo& aPrincipalInfo, ErrorResult& aRv) : WorkerMainThreadRunnable( aWorkerRef->Private(), NS_LITERAL_CSTRING("BroadcastChannel :: Initialize")), mWorkerRef(aWorkerRef), mOrigin(aOrigin), - mStoragePrincipalInfo(aStoragePrincipalInfo), + mPrincipalInfo(aPrincipalInfo), mRv(aRv) { MOZ_ASSERT(mWorkerRef); } @@ -82,19 +81,18 @@ class InitializeRunnable final : public WorkerMainThreadRunnable { bool MainThreadRun() override { MOZ_ASSERT(NS_IsMainThread()); - nsIPrincipal* storagePrincipal = - GetStoragePrincipalFromThreadSafeWorkerRef(mWorkerRef); - if (!storagePrincipal) { + nsIPrincipal* principal = GetPrincipalFromThreadSafeWorkerRef(mWorkerRef); + if (!principal) { mRv.Throw(NS_ERROR_FAILURE); return true; } - mRv = PrincipalToPrincipalInfo(storagePrincipal, &mStoragePrincipalInfo); + mRv = PrincipalToPrincipalInfo(principal, &mPrincipalInfo); if (NS_WARN_IF(mRv.Failed())) { return true; } - mRv = storagePrincipal->GetOrigin(mOrigin); + mRv = principal->GetOrigin(mOrigin); if (NS_WARN_IF(mRv.Failed())) { return true; } @@ -117,7 +115,7 @@ class InitializeRunnable final : public WorkerMainThreadRunnable { private: RefPtr mWorkerRef; nsACString& mOrigin; - PrincipalInfo& mStoragePrincipalInfo; + PrincipalInfo& mPrincipalInfo; ErrorResult& mRv; }; @@ -229,9 +227,7 @@ already_AddRefed BroadcastChannel::Constructor( RefPtr bc = new BroadcastChannel(global, aChannel); nsAutoCString origin; - PrincipalInfo storagePrincipalInfo; - - nsContentUtils::StorageAccess storageAccess; + PrincipalInfo principalInfo; if (NS_IsMainThread()) { nsCOMPtr window = do_QueryInterface(global); @@ -247,29 +243,29 @@ already_AddRefed BroadcastChannel::Constructor( return nullptr; } - nsCOMPtr sop = do_QueryInterface(incumbent); - if (NS_WARN_IF(!sop)) { - aRv.Throw(NS_ERROR_FAILURE); - return nullptr; - } - - nsIPrincipal* storagePrincipal = sop->GetEffectiveStoragePrincipal(); - if (!storagePrincipal) { + nsIPrincipal* principal = incumbent->PrincipalOrNull(); + if (!principal) { aRv.Throw(NS_ERROR_UNEXPECTED); return nullptr; } - aRv = storagePrincipal->GetOrigin(origin); + // We want to allow opaque origins. + if (!principal->GetIsNullPrincipal() && + nsContentUtils::StorageAllowedForWindow(window) <= + nsContentUtils::StorageAccess::eDeny) { + aRv.Throw(NS_ERROR_DOM_SECURITY_ERR); + return nullptr; + } + + aRv = principal->GetOrigin(origin); if (NS_WARN_IF(aRv.Failed())) { return nullptr; } - aRv = PrincipalToPrincipalInfo(storagePrincipal, &storagePrincipalInfo); + aRv = PrincipalToPrincipalInfo(principal, &principalInfo); if (NS_WARN_IF(aRv.Failed())) { return nullptr; } - - storageAccess = nsContentUtils::StorageAllowedForWindow(window); } else { JSContext* cx = aGlobal.Context(); @@ -288,23 +284,19 @@ already_AddRefed BroadcastChannel::Constructor( RefPtr tsr = new ThreadSafeWorkerRef(workerRef); RefPtr runnable = - new InitializeRunnable(tsr, origin, storagePrincipalInfo, aRv); + new InitializeRunnable(tsr, origin, principalInfo, aRv); runnable->Dispatch(Canceling, aRv); if (aRv.Failed()) { return nullptr; } - storageAccess = workerPrivate->StorageAccess(); - bc->mWorkerRef = workerRef; - } + if (principalInfo.type() != PrincipalInfo::TNullPrincipalInfo && + !workerPrivate->IsStorageAllowed()) { + aRv.Throw(NS_ERROR_DOM_SECURITY_ERR); + return nullptr; + } - // We want to allow opaque origins. - if (storagePrincipalInfo.type() != PrincipalInfo::TNullPrincipalInfo && - (storageAccess == nsContentUtils::StorageAccess::eDeny || - (storageAccess == nsContentUtils::StorageAccess::ePartitionedOrDeny && - !StaticPrefs::privacy_storagePrincipal_enabledForTrackers()))) { - aRv.Throw(NS_ERROR_DOM_SECURITY_ERR); - return nullptr; + bc->mWorkerRef = std::move(workerRef); } // Register this component to PBackground. @@ -316,7 +308,7 @@ already_AddRefed BroadcastChannel::Constructor( } PBroadcastChannelChild* actor = actorChild->SendPBroadcastChannelConstructor( - storagePrincipalInfo, origin, nsString(aChannel)); + principalInfo, origin, nsString(aChannel)); bc->mActor = static_cast(actor); MOZ_ASSERT(bc->mActor); diff --git a/dom/cache/CacheStorage.cpp b/dom/cache/CacheStorage.cpp index 24598a98bc5e..99f0f8949279 100644 --- a/dom/cache/CacheStorage.cpp +++ b/dom/cache/CacheStorage.cpp @@ -567,23 +567,21 @@ OpenMode CacheStorage::GetOpenMode() const { bool CacheStorage::HasStorageAccess() const { NS_ASSERT_OWNINGTHREAD(CacheStorage); - nsContentUtils::StorageAccess access; - if (NS_IsMainThread()) { nsCOMPtr window = do_QueryInterface(mGlobal); if (NS_WARN_IF(!window)) { return true; } - access = nsContentUtils::StorageAllowedForWindow(window); - } else { - WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate(); - MOZ_ASSERT(workerPrivate); - - access = workerPrivate->StorageAccess(); + nsContentUtils::StorageAccess access = + nsContentUtils::StorageAllowedForWindow(window); + return access > nsContentUtils::StorageAccess::ePrivateBrowsing; } - return access > nsContentUtils::StorageAccess::ePrivateBrowsing; + WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate(); + MOZ_ASSERT(workerPrivate); + + return workerPrivate->IsStorageAllowed(); } } // namespace cache diff --git a/dom/clients/manager/ClientSource.cpp b/dom/clients/manager/ClientSource.cpp index a66059e5185d..4df62090bae5 100644 --- a/dom/clients/manager/ClientSource.cpp +++ b/dom/clients/manager/ClientSource.cpp @@ -206,8 +206,7 @@ void ClientSource::WorkerExecutionReady(WorkerPrivate* aWorkerPrivate) { // execution ready. We can't reliably determine what our storage policy // is before execution ready, unfortunately. if (mController.isSome()) { - MOZ_DIAGNOSTIC_ASSERT(aWorkerPrivate->StorageAccess() > - nsContentUtils::StorageAccess::ePrivateBrowsing || + MOZ_DIAGNOSTIC_ASSERT(aWorkerPrivate->IsStorageAllowed() || StringBeginsWith(aWorkerPrivate->ScriptURL(), NS_LITERAL_STRING("blob:"))); } @@ -381,8 +380,7 @@ void ClientSource::SetController( nsContentUtils::StorageAllowedForWindow(GetInnerWindow()) == nsContentUtils::StorageAccess::eAllow); } else if (GetWorkerPrivate()) { - MOZ_DIAGNOSTIC_ASSERT(GetWorkerPrivate()->StorageAccess() > - nsContentUtils::StorageAccess::ePrivateBrowsing || + MOZ_DIAGNOSTIC_ASSERT(GetWorkerPrivate()->IsStorageAllowed() || StringBeginsWith(GetWorkerPrivate()->ScriptURL(), NS_LITERAL_STRING("blob:"))); } @@ -437,8 +435,7 @@ RefPtr ClientSource::Control( nsContentUtils::StorageAccess::eAllow; } else if (GetWorkerPrivate()) { // Local URL workers and workers with access to storage cna be controlled. - controlAllowed = GetWorkerPrivate()->StorageAccess() > - nsContentUtils::StorageAccess::ePrivateBrowsing || + controlAllowed = GetWorkerPrivate()->IsStorageAllowed() || StringBeginsWith(GetWorkerPrivate()->ScriptURL(), NS_LITERAL_STRING("blob:")); } @@ -651,7 +648,13 @@ nsresult ClientSource::SnapshotState(ClientState* aStateOut) { return NS_ERROR_DOM_INVALID_STATE_ERR; } - *aStateOut = ClientState(ClientWorkerState(workerPrivate->StorageAccess())); + // Workers only keep a boolean for storage access at the moment. + // Map this back to eAllow or eDeny for now. + nsContentUtils::StorageAccess storage = + workerPrivate->IsStorageAllowed() ? nsContentUtils::StorageAccess::eAllow + : nsContentUtils::StorageAccess::eDeny; + + *aStateOut = ClientState(ClientWorkerState(storage)); return NS_OK; } diff --git a/dom/html/nsHTMLDocument.cpp b/dom/html/nsHTMLDocument.cpp index ba48cd947729..26a8b1c6f8b2 100644 --- a/dom/html/nsHTMLDocument.cpp +++ b/dom/html/nsHTMLDocument.cpp @@ -222,11 +222,10 @@ void nsHTMLDocument::Reset(nsIChannel* aChannel, nsILoadGroup* aLoadGroup) { } void nsHTMLDocument::ResetToURI(nsIURI* aURI, nsILoadGroup* aLoadGroup, - nsIPrincipal* aPrincipal, - nsIPrincipal* aStoragePrincipal) { + nsIPrincipal* aPrincipal) { mLoadFlags = nsIRequest::LOAD_NORMAL; - Document::ResetToURI(aURI, aLoadGroup, aPrincipal, aStoragePrincipal); + Document::ResetToURI(aURI, aLoadGroup, aPrincipal); mImages = nullptr; mApplets = nullptr; @@ -1030,14 +1029,7 @@ void nsHTMLDocument::GetCookie(nsAString& aCookie, ErrorResult& rv) { return; } - nsContentUtils::StorageAccess storageAccess = - nsContentUtils::StorageAllowedForDocument(this); - if (storageAccess == nsContentUtils::StorageAccess::eDeny) { - return; - } - - if (storageAccess == nsContentUtils::StorageAccess::ePartitionedOrDeny && - !StaticPrefs::privacy_storagePrincipal_enabledForTrackers()) { + if (nsContentUtils::StorageDisabledByAntiTracking(this, nullptr)) { return; } @@ -1090,14 +1082,7 @@ void nsHTMLDocument::SetCookie(const nsAString& aCookie, ErrorResult& rv) { return; } - nsContentUtils::StorageAccess storageAccess = - nsContentUtils::StorageAllowedForDocument(this); - if (storageAccess == nsContentUtils::StorageAccess::eDeny) { - return; - } - - if (storageAccess == nsContentUtils::StorageAccess::ePartitionedOrDeny && - !StaticPrefs::privacy_storagePrincipal_enabledForTrackers()) { + if (nsContentUtils::StorageDisabledByAntiTracking(this, nullptr)) { return; } diff --git a/dom/html/nsHTMLDocument.h b/dom/html/nsHTMLDocument.h index 2efbe12d42d0..c580e750a8f8 100644 --- a/dom/html/nsHTMLDocument.h +++ b/dom/html/nsHTMLDocument.h @@ -56,8 +56,7 @@ class nsHTMLDocument : public mozilla::dom::Document, public nsIHTMLDocument { // Document virtual void Reset(nsIChannel* aChannel, nsILoadGroup* aLoadGroup) override; virtual void ResetToURI(nsIURI* aURI, nsILoadGroup* aLoadGroup, - nsIPrincipal* aPrincipal, - nsIPrincipal* aStoragePrincipal) override; + nsIPrincipal* aPrincipal) override; virtual nsresult StartDocumentLoad(const char* aCommand, nsIChannel* aChannel, nsILoadGroup* aLoadGroup, diff --git a/dom/indexedDB/IDBFactory.cpp b/dom/indexedDB/IDBFactory.cpp index dc096d831b5d..f5f261e96541 100644 --- a/dom/indexedDB/IDBFactory.cpp +++ b/dom/indexedDB/IDBFactory.cpp @@ -301,19 +301,14 @@ nsresult IDBFactory::AllowedForWindowInternal(nsPIDOMWindowInner* aWindow, // the factory callsite records whether the browser is in private browsing. // and thus we don't have to respect that setting here. IndexedDB has no // concept of session-local storage, and thus ignores it. - if (access == nsContentUtils::StorageAccess::eDeny) { - return NS_ERROR_DOM_SECURITY_ERR; - } - - if (access == nsContentUtils::StorageAccess::ePartitionedOrDeny && - !StaticPrefs::privacy_storagePrincipal_enabledForTrackers()) { + if (access <= nsContentUtils::StorageAccess::eDeny) { return NS_ERROR_DOM_SECURITY_ERR; } nsCOMPtr sop = do_QueryInterface(aWindow); MOZ_ASSERT(sop); - nsCOMPtr principal = sop->GetEffectiveStoragePrincipal(); + nsCOMPtr principal = sop->GetPrincipal(); if (NS_WARN_IF(!principal)) { return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR; } diff --git a/dom/serviceworkers/ServiceWorkerPrivate.cpp b/dom/serviceworkers/ServiceWorkerPrivate.cpp index bd7a5e47d0de..5953f978b51e 100644 --- a/dom/serviceworkers/ServiceWorkerPrivate.cpp +++ b/dom/serviceworkers/ServiceWorkerPrivate.cpp @@ -1729,12 +1729,10 @@ nsresult ServiceWorkerPrivate::SpawnWorkerIfNeeded(WakeUpReason aWhy, } info.mLoadingPrincipal = info.mPrincipal; - // StoragePrincipal for ServiceWorkers is equal to mPrincipal because, at the - // moment, ServiceWorkers are not exposed in partitioned contexts. - info.mStoragePrincipal = info.mPrincipal; - - info.mStorageAccess = + nsContentUtils::StorageAccess access = nsContentUtils::StorageAllowedForServiceWorker(info.mPrincipal); + info.mStorageAllowed = + access > nsContentUtils::StorageAccess::ePrivateBrowsing; info.mCookieSettings = mozilla::net::CookieSettings::Create(); MOZ_ASSERT(info.mCookieSettings); @@ -1755,8 +1753,7 @@ nsresult ServiceWorkerPrivate::SpawnWorkerIfNeeded(WakeUpReason aWhy, WorkerPrivate::OverrideLoadInfoLoadGroup(info, info.mPrincipal); - rv = info.SetPrincipalsOnMainThread(info.mPrincipal, info.mStoragePrincipal, - info.mLoadGroup); + rv = info.SetPrincipalOnMainThread(info.mPrincipal, info.mLoadGroup); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } diff --git a/dom/webidl/Document.webidl b/dom/webidl/Document.webidl index 7db7b248956f..8a0553297abf 100644 --- a/dom/webidl/Document.webidl +++ b/dom/webidl/Document.webidl @@ -15,7 +15,6 @@ * https://wicg.github.io/feature-policy/#policy */ -interface Principal; interface WindowProxy; interface nsISupports; interface URI; @@ -359,10 +358,6 @@ partial interface Document { [CEReactions, NewObject, Throws, Func="IsChromeOrXBL"] Element createXULElement(DOMString localName, optional (ElementCreationOptions or DOMString) options); - // The principal to use for the storage area of this document - [ChromeOnly] - readonly attribute Principal effectiveStoragePrincipal; - // Touch bits // XXXbz I can't find the sane spec for this stuff, so just cribbing // from our xpidl for now. diff --git a/dom/workers/ScriptLoader.cpp b/dom/workers/ScriptLoader.cpp index 59d5ff5f3b9d..80fbbe77f2c6 100644 --- a/dom/workers/ScriptLoader.cpp +++ b/dom/workers/ScriptLoader.cpp @@ -1188,7 +1188,7 @@ class ScriptLoaderRunnable final : public nsIRunnable, public nsINamed { // URL must exactly match the final worker script URL in order to // properly set the referrer header on fetch/xhr requests. If bug 1340694 // is ever fixed this can be removed. - rv = mWorkerPrivate->SetPrincipalsFromChannel(channel); + rv = mWorkerPrivate->SetPrincipalFromChannel(channel); NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr csp = mWorkerPrivate->GetCSP(); @@ -1296,11 +1296,8 @@ class ScriptLoaderRunnable final : public nsIRunnable, public nsINamed { // referrer logic depends on the WorkerPrivate principal having a URL // that matches the worker script URL. If bug 1340694 is ever fixed // this can be removed. - // XXX: force the storagePrincipal to be equal to the response one. This - // is OK for now because we don't want to expose storagePrincipal - // functionality in ServiceWorkers yet. - rv = mWorkerPrivate->SetPrincipalsOnMainThread( - responsePrincipal, responsePrincipal, loadGroup); + rv = mWorkerPrivate->SetPrincipalOnMainThread(responsePrincipal, + loadGroup); MOZ_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv)); rv = mWorkerPrivate->SetCSPFromHeaderValues(aCSPHeaderValue, @@ -1844,7 +1841,7 @@ class ChannelGetterRunnable final : public WorkerMainThreadRunnable { getter_AddRefs(channel)); NS_ENSURE_SUCCESS(mResult, true); - mResult = mLoadInfo.SetPrincipalsFromChannel(channel); + mResult = mLoadInfo.SetPrincipalFromChannel(channel); NS_ENSURE_SUCCESS(mResult, true); mLoadInfo.mChannel = channel.forget(); diff --git a/dom/workers/WorkerLoadInfo.cpp b/dom/workers/WorkerLoadInfo.cpp index 8aa12cf09f81..ea6a57ced5a0 100644 --- a/dom/workers/WorkerLoadInfo.cpp +++ b/dom/workers/WorkerLoadInfo.cpp @@ -87,19 +87,17 @@ WorkerLoadInfoData::WorkerLoadInfoData() mReportCSPViolations(false), mXHRParamsAllowed(false), mPrincipalIsSystem(false), - mStorageAccess(nsContentUtils::StorageAccess::eDeny), + mStorageAllowed(false), mFirstPartyStorageAccessGranted(false), mServiceWorkersTestingInWindow(false), mSecureContext(eNotSet) {} -nsresult WorkerLoadInfo::SetPrincipalsOnMainThread( - nsIPrincipal* aPrincipal, nsIPrincipal* aStoragePrincipal, - nsILoadGroup* aLoadGroup) { +nsresult WorkerLoadInfo::SetPrincipalOnMainThread(nsIPrincipal* aPrincipal, + nsILoadGroup* aLoadGroup) { AssertIsOnMainThread(); MOZ_ASSERT(NS_LoadGroupMatchesPrincipal(aLoadGroup, aPrincipal)); mPrincipal = aPrincipal; - mStoragePrincipal = aStoragePrincipal; mPrincipalIsSystem = nsContentUtils::IsSystemPrincipal(aPrincipal); nsresult rv = aPrincipal->GetCsp(getter_AddRefs(mCSP)); @@ -115,33 +113,23 @@ nsresult WorkerLoadInfo::SetPrincipalsOnMainThread( mLoadGroup = aLoadGroup; mPrincipalInfo = new PrincipalInfo(); - mStoragePrincipalInfo = new PrincipalInfo(); mOriginAttributes = nsContentUtils::GetOriginAttributes(aLoadGroup); rv = PrincipalToPrincipalInfo(aPrincipal, mPrincipalInfo); NS_ENSURE_SUCCESS(rv, rv); - if (aPrincipal->Equals(aStoragePrincipal)) { - *mStoragePrincipalInfo = *mPrincipalInfo; - } else { - mStoragePrincipalInfo = new PrincipalInfo(); - rv = PrincipalToPrincipalInfo(aStoragePrincipal, mStoragePrincipalInfo); - NS_ENSURE_SUCCESS(rv, rv); - } - rv = nsContentUtils::GetUTFOrigin(aPrincipal, mOrigin); NS_ENSURE_SUCCESS(rv, rv); return NS_OK; } -nsresult WorkerLoadInfo::GetPrincipalsAndLoadGroupFromChannel( +nsresult WorkerLoadInfo::GetPrincipalAndLoadGroupFromChannel( nsIChannel* aChannel, nsIPrincipal** aPrincipalOut, - nsIPrincipal** aStoragePrincipalOut, nsILoadGroup** aLoadGroupOut) { + nsILoadGroup** aLoadGroupOut) { AssertIsOnMainThread(); MOZ_DIAGNOSTIC_ASSERT(aChannel); MOZ_DIAGNOSTIC_ASSERT(aPrincipalOut); - MOZ_DIAGNOSTIC_ASSERT(aStoragePrincipalOut); MOZ_DIAGNOSTIC_ASSERT(aLoadGroupOut); // Initial triggering principal should be set @@ -151,10 +139,8 @@ nsresult WorkerLoadInfo::GetPrincipalsAndLoadGroupFromChannel( MOZ_DIAGNOSTIC_ASSERT(ssm); nsCOMPtr channelPrincipal; - nsCOMPtr channelStoragePrincipal; - nsresult rv = ssm->GetChannelResultPrincipals( - aChannel, getter_AddRefs(channelPrincipal), - getter_AddRefs(channelStoragePrincipal)); + nsresult rv = ssm->GetChannelResultPrincipal( + aChannel, getter_AddRefs(channelPrincipal)); NS_ENSURE_SUCCESS(rv, rv); // Every time we call GetChannelResultPrincipal() it will return a different @@ -168,7 +154,6 @@ nsresult WorkerLoadInfo::GetPrincipalsAndLoadGroupFromChannel( if (mPrincipal && mPrincipal->GetIsNullPrincipal() && channelPrincipal->GetIsNullPrincipal()) { channelPrincipal = mPrincipal; - channelStoragePrincipal = mPrincipal; } nsCOMPtr channelLoadGroup; @@ -201,7 +186,6 @@ nsresult WorkerLoadInfo::GetPrincipalsAndLoadGroupFromChannel( // Assign the system principal to the resource:// worker only if it // was loaded from code using the system principal. channelPrincipal = mLoadingPrincipal; - channelStoragePrincipal = mLoadingPrincipal; } else { return NS_ERROR_DOM_BAD_URI; } @@ -213,35 +197,30 @@ nsresult WorkerLoadInfo::GetPrincipalsAndLoadGroupFromChannel( MOZ_ASSERT(NS_LoadGroupMatchesPrincipal(channelLoadGroup, channelPrincipal)); channelPrincipal.forget(aPrincipalOut); - channelStoragePrincipal.forget(aStoragePrincipalOut); channelLoadGroup.forget(aLoadGroupOut); return NS_OK; } -nsresult WorkerLoadInfo::SetPrincipalsFromChannel(nsIChannel* aChannel) { +nsresult WorkerLoadInfo::SetPrincipalFromChannel(nsIChannel* aChannel) { AssertIsOnMainThread(); nsCOMPtr principal; - nsCOMPtr storagePrincipal; nsCOMPtr loadGroup; - nsresult rv = GetPrincipalsAndLoadGroupFromChannel( - aChannel, getter_AddRefs(principal), getter_AddRefs(storagePrincipal), - getter_AddRefs(loadGroup)); + nsresult rv = GetPrincipalAndLoadGroupFromChannel( + aChannel, getter_AddRefs(principal), getter_AddRefs(loadGroup)); NS_ENSURE_SUCCESS(rv, rv); - return SetPrincipalsOnMainThread(principal, storagePrincipal, loadGroup); + return SetPrincipalOnMainThread(principal, loadGroup); } bool WorkerLoadInfo::FinalChannelPrincipalIsValid(nsIChannel* aChannel) { AssertIsOnMainThread(); nsCOMPtr principal; - nsCOMPtr storagePrincipal; nsCOMPtr loadGroup; - nsresult rv = GetPrincipalsAndLoadGroupFromChannel( - aChannel, getter_AddRefs(principal), getter_AddRefs(storagePrincipal), - getter_AddRefs(loadGroup)); + nsresult rv = GetPrincipalAndLoadGroupFromChannel( + aChannel, getter_AddRefs(principal), getter_AddRefs(loadGroup)); NS_ENSURE_SUCCESS(rv, false); // Verify that the channel is still a null principal. We don't care @@ -264,10 +243,7 @@ bool WorkerLoadInfo::FinalChannelPrincipalIsValid(nsIChannel* aChannel) { bool WorkerLoadInfo::PrincipalIsValid() const { return mPrincipal && mPrincipalInfo && mPrincipalInfo->type() != PrincipalInfo::T__None && - mPrincipalInfo->type() <= PrincipalInfo::T__Last && - mStoragePrincipal && mStoragePrincipalInfo && - mStoragePrincipalInfo->type() != PrincipalInfo::T__None && - mStoragePrincipalInfo->type() <= PrincipalInfo::T__Last; + mPrincipalInfo->type() <= PrincipalInfo::T__Last; } bool WorkerLoadInfo::PrincipalURIMatchesScriptURL() { @@ -336,7 +312,7 @@ bool WorkerLoadInfo::ProxyReleaseMainThreadObjects( bool WorkerLoadInfo::ProxyReleaseMainThreadObjects( WorkerPrivate* aWorkerPrivate, nsCOMPtr& aLoadGroupToCancel) { - static const uint32_t kDoomedCount = 11; + static const uint32_t kDoomedCount = 10; nsTArray> doomed(kDoomedCount); SwapToISupportsArray(mWindow, doomed); @@ -344,7 +320,6 @@ bool WorkerLoadInfo::ProxyReleaseMainThreadObjects( SwapToISupportsArray(mBaseURI, doomed); SwapToISupportsArray(mResolvedScriptURI, doomed); SwapToISupportsArray(mPrincipal, doomed); - SwapToISupportsArray(mStoragePrincipal, doomed); SwapToISupportsArray(mLoadingPrincipal, doomed); SwapToISupportsArray(mChannel, doomed); SwapToISupportsArray(mCSP, doomed); diff --git a/dom/workers/WorkerLoadInfo.h b/dom/workers/WorkerLoadInfo.h index f62beda0660d..08083b9d306b 100644 --- a/dom/workers/WorkerLoadInfo.h +++ b/dom/workers/WorkerLoadInfo.h @@ -50,7 +50,6 @@ struct WorkerLoadInfoData { // If we load a data: URL, mPrincipal will be a null principal. nsCOMPtr mLoadingPrincipal; nsCOMPtr mPrincipal; - nsCOMPtr mStoragePrincipal; // Taken from the parent context. nsCOMPtr mCookieSettings; @@ -92,7 +91,6 @@ struct WorkerLoadInfoData { RefPtr mInterfaceRequestor; nsAutoPtr mPrincipalInfo; - nsAutoPtr mStoragePrincipalInfo; nsCString mDomain; nsString mOrigin; // Derived from mPrincipal; can be used on worker thread. @@ -114,7 +112,7 @@ struct WorkerLoadInfoData { bool mReportCSPViolations; bool mXHRParamsAllowed; bool mPrincipalIsSystem; - nsContentUtils::StorageAccess mStorageAccess; + bool mStorageAllowed; bool mFirstPartyStorageAccessGranted; bool mServiceWorkersTestingInWindow; OriginAttributes mOriginAttributes; @@ -138,15 +136,14 @@ struct WorkerLoadInfo : WorkerLoadInfoData { WorkerLoadInfo& operator=(WorkerLoadInfo&& aOther) = default; - nsresult SetPrincipalsOnMainThread(nsIPrincipal* aPrincipal, - nsIPrincipal* aStoragePrincipal, - nsILoadGroup* aLoadGroup); + nsresult SetPrincipalOnMainThread(nsIPrincipal* aPrincipal, + nsILoadGroup* aLoadGroup); - nsresult GetPrincipalsAndLoadGroupFromChannel( - nsIChannel* aChannel, nsIPrincipal** aPrincipalOut, - nsIPrincipal** aStoragePrincipalOut, nsILoadGroup** aLoadGroupOut); + nsresult GetPrincipalAndLoadGroupFromChannel(nsIChannel* aChannel, + nsIPrincipal** aPrincipalOut, + nsILoadGroup** aLoadGroupOut); - nsresult SetPrincipalsFromChannel(nsIChannel* aChannel); + nsresult SetPrincipalFromChannel(nsIChannel* aChannel); bool FinalChannelPrincipalIsValid(nsIChannel* aChannel); diff --git a/dom/workers/WorkerPrivate.cpp b/dom/workers/WorkerPrivate.cpp index fddb2559600c..00f70bca0c16 100644 --- a/dom/workers/WorkerPrivate.cpp +++ b/dom/workers/WorkerPrivate.cpp @@ -1932,15 +1932,13 @@ void WorkerPrivate::SetBaseURI(nsIURI* aBaseURI) { nsContentUtils::GetUTFOrigin(aBaseURI, mLocationInfo.mOrigin); } -nsresult WorkerPrivate::SetPrincipalsOnMainThread( - nsIPrincipal* aPrincipal, nsIPrincipal* aStoragePrincipal, - nsILoadGroup* aLoadGroup) { - return mLoadInfo.SetPrincipalsOnMainThread(aPrincipal, aStoragePrincipal, - aLoadGroup); +nsresult WorkerPrivate::SetPrincipalOnMainThread(nsIPrincipal* aPrincipal, + nsILoadGroup* aLoadGroup) { + return mLoadInfo.SetPrincipalOnMainThread(aPrincipal, aLoadGroup); } -nsresult WorkerPrivate::SetPrincipalsFromChannel(nsIChannel* aChannel) { - return mLoadInfo.SetPrincipalsFromChannel(aChannel); +nsresult WorkerPrivate::SetPrincipalFromChannel(nsIChannel* aChannel) { + return mLoadInfo.SetPrincipalFromChannel(aChannel); } bool WorkerPrivate::FinalChannelPrincipalIsValid(nsIChannel* aChannel) { @@ -2357,7 +2355,7 @@ nsresult WorkerPrivate::GetLoadInfo(JSContext* aCx, nsPIDOMWindowInner* aWindow, loadInfo.mDomain = aParent->Domain(); loadInfo.mFromWindow = aParent->IsFromWindow(); loadInfo.mWindowID = aParent->WindowID(); - loadInfo.mStorageAccess = aParent->StorageAccess(); + loadInfo.mStorageAllowed = aParent->IsStorageAllowed(); loadInfo.mOriginAttributes = aParent->GetOriginAttributes(); loadInfo.mServiceWorkersTestingInWindow = aParent->ServiceWorkersTestingInWindow(); @@ -2484,8 +2482,9 @@ nsresult WorkerPrivate::GetLoadInfo(JSContext* aCx, nsPIDOMWindowInner* aWindow, loadInfo.mFromWindow = true; loadInfo.mWindowID = globalWindow->WindowID(); - loadInfo.mStorageAccess = + nsContentUtils::StorageAccess access = nsContentUtils::StorageAllowedForWindow(globalWindow); + loadInfo.mStorageAllowed = access > nsContentUtils::StorageAccess::eDeny; loadInfo.mCookieSettings = document->CookieSettings(); loadInfo.mOriginAttributes = nsContentUtils::GetOriginAttributes(document); @@ -2531,7 +2530,7 @@ nsresult WorkerPrivate::GetLoadInfo(JSContext* aCx, nsPIDOMWindowInner* aWindow, loadInfo.mXHRParamsAllowed = true; loadInfo.mFromWindow = false; loadInfo.mWindowID = UINT64_MAX; - loadInfo.mStorageAccess = nsContentUtils::StorageAccess::eAllow; + loadInfo.mStorageAllowed = true; loadInfo.mCookieSettings = mozilla::net::CookieSettings::Create(); MOZ_ASSERT(loadInfo.mCookieSettings); @@ -2564,7 +2563,7 @@ nsresult WorkerPrivate::GetLoadInfo(JSContext* aCx, nsPIDOMWindowInner* aWindow, getter_AddRefs(loadInfo.mResolvedScriptURI)); NS_ENSURE_SUCCESS(rv, rv); - rv = loadInfo.SetPrincipalsFromChannel(loadInfo.mChannel); + rv = loadInfo.SetPrincipalFromChannel(loadInfo.mChannel); NS_ENSURE_SUCCESS(rv, rv); } @@ -3360,11 +3359,6 @@ void WorkerPrivate::PropagateFirstPartyStorageAccessGrantedInternal() { mLoadInfo.mFirstPartyStorageAccessGranted = true; - WorkerGlobalScope* globalScope = GlobalScope(); - if (globalScope) { - globalScope->FirstPartyStorageAccessGranted(); - } - for (uint32_t index = 0; index < data->mChildWorkers.Length(); index++) { data->mChildWorkers[index]->PropagateFirstPartyStorageAccessGranted(); } diff --git a/dom/workers/WorkerPrivate.h b/dom/workers/WorkerPrivate.h index 323a32e27148..89a6a6811003 100644 --- a/dom/workers/WorkerPrivate.h +++ b/dom/workers/WorkerPrivate.h @@ -12,7 +12,6 @@ #include "mozilla/CondVar.h" #include "mozilla/DOMEventTargetHelper.h" #include "mozilla/RelativeTimeline.h" -#include "nsContentUtils.h" #include "nsIContentSecurityPolicy.h" #include "nsIEventTarget.h" #include "nsTObserverArray.h" @@ -662,11 +661,6 @@ class WorkerPrivate : public RelativeTimeline { return mLoadInfo.mPrincipal; } - nsIPrincipal* GetEffectiveStoragePrincipal() const { - AssertIsOnMainThread(); - return mLoadInfo.mStoragePrincipal; - } - nsIPrincipal* GetLoadingPrincipal() const { AssertIsOnMainThread(); return mLoadInfo.mLoadingPrincipal; @@ -685,10 +679,6 @@ class WorkerPrivate : public RelativeTimeline { return *mLoadInfo.mPrincipalInfo; } - const mozilla::ipc::PrincipalInfo& GetEffectiveStoragePrincipalInfo() const { - return *mLoadInfo.mStoragePrincipalInfo; - } - already_AddRefed ForgetWorkerChannel() { AssertIsOnMainThread(); return mLoadInfo.mChannel.forget(); @@ -738,13 +728,10 @@ class WorkerPrivate : public RelativeTimeline { mLoadInfo.mXHRParamsAllowed = aAllowed; } - nsContentUtils::StorageAccess StorageAccess() const { + bool IsStorageAllowed() const { AssertIsOnWorkerThread(); - if (mLoadInfo.mFirstPartyStorageAccessGranted) { - return nsContentUtils::StorageAccess::eAllow; - } - - return mLoadInfo.mStorageAccess; + return mLoadInfo.mStorageAllowed || + mLoadInfo.mFirstPartyStorageAccessGranted; } nsICookieSettings* CookieSettings() const { @@ -797,11 +784,10 @@ class WorkerPrivate : public RelativeTimeline { void CycleCollect(bool aDummy); - nsresult SetPrincipalsOnMainThread(nsIPrincipal* aPrincipal, - nsIPrincipal* aStoragePrincipal, - nsILoadGroup* aLoadGroup); + nsresult SetPrincipalOnMainThread(nsIPrincipal* aPrincipal, + nsILoadGroup* aLoadGroup); - nsresult SetPrincipalsFromChannel(nsIChannel* aChannel); + nsresult SetPrincipalFromChannel(nsIChannel* aChannel); bool FinalChannelPrincipalIsValid(nsIChannel* aChannel); diff --git a/dom/workers/WorkerScope.cpp b/dom/workers/WorkerScope.cpp index 6ce325b8f81a..4a52b710055e 100644 --- a/dom/workers/WorkerScope.cpp +++ b/dom/workers/WorkerScope.cpp @@ -393,23 +393,13 @@ already_AddRefed WorkerGlobalScope::GetIndexedDB( RefPtr indexedDB = mIndexedDB; if (!indexedDB) { - nsContentUtils::StorageAccess access = mWorkerPrivate->StorageAccess(); - - if (access == nsContentUtils::StorageAccess::eDeny) { + if (!mWorkerPrivate->IsStorageAllowed()) { NS_WARNING("IndexedDB is not allowed in this worker!"); aErrorResult = NS_ERROR_DOM_SECURITY_ERR; return nullptr; } - if (access == nsContentUtils::StorageAccess::ePartitionedOrDeny && - !StaticPrefs::privacy_storagePrincipal_enabledForTrackers()) { - NS_WARNING("IndexedDB is not allowed in this worker!"); - aErrorResult = NS_ERROR_DOM_SECURITY_ERR; - return nullptr; - } - - const PrincipalInfo& principalInfo = - mWorkerPrivate->GetEffectiveStoragePrincipalInfo(); + const PrincipalInfo& principalInfo = mWorkerPrivate->GetPrincipalInfo(); nsresult rv = IDBFactory::CreateForWorker(this, principalInfo, mWorkerPrivate->WindowID(), @@ -497,10 +487,6 @@ WorkerGlobalScope::GetOrCreateServiceWorkerRegistration( return ref.forget(); } -void WorkerGlobalScope::FirstPartyStorageAccessGranted() { - mIndexedDB = nullptr; -} - DedicatedWorkerGlobalScope::DedicatedWorkerGlobalScope( WorkerPrivate* aWorkerPrivate, const nsString& aName) : WorkerGlobalScope(aWorkerPrivate), mName(aName) {} diff --git a/dom/workers/WorkerScope.h b/dom/workers/WorkerScope.h index 638190d3e049..ec13f7fdb3fc 100644 --- a/dom/workers/WorkerScope.h +++ b/dom/workers/WorkerScope.h @@ -190,8 +190,6 @@ class WorkerGlobalScope : public DOMEventTargetHelper, RefPtr GetOrCreateServiceWorkerRegistration( const ServiceWorkerRegistrationDescriptor& aDescriptor) override; - - void FirstPartyStorageAccessGranted(); }; class DedicatedWorkerGlobalScope final : public WorkerGlobalScope { diff --git a/dom/workers/remoteworkers/RemoteWorkerChild.cpp b/dom/workers/remoteworkers/RemoteWorkerChild.cpp index fe2e3815c24c..569fb8035a39 100644 --- a/dom/workers/remoteworkers/RemoteWorkerChild.cpp +++ b/dom/workers/remoteworkers/RemoteWorkerChild.cpp @@ -262,31 +262,16 @@ nsresult RemoteWorkerChild::ExecWorkerOnMainThread( return rv; } - nsCOMPtr storagePrincipal = - PrincipalInfoToPrincipal(aData.storagePrincipalInfo(), &rv); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - - rv = PopulatePrincipalContentSecurityPolicy( - storagePrincipal, aData.storagePrincipalCsp(), - aData.storagePrincipalPreloadCsp()); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - WorkerLoadInfo info; info.mBaseURI = DeserializeURI(aData.baseScriptURL()); info.mResolvedScriptURI = DeserializeURI(aData.resolvedScriptURL()); info.mPrincipalInfo = new PrincipalInfo(aData.principalInfo()); - info.mStoragePrincipalInfo = new PrincipalInfo(aData.storagePrincipalInfo()); info.mDomain = aData.domain(); info.mPrincipal = principal; - info.mStoragePrincipal = storagePrincipal; info.mLoadingPrincipal = loadingPrincipal; - info.mStorageAccess = aData.storageAccess(); + info.mStorageAllowed = aData.isStorageAccessAllowed(); info.mOriginAttributes = BasePrincipal::Cast(principal)->OriginAttributesRef(); info.mCookieSettings = net::CookieSettings::Create(); @@ -305,8 +290,7 @@ nsresult RemoteWorkerChild::ExecWorkerOnMainThread( new SharedWorkerInterfaceRequestor(); info.mInterfaceRequestor->SetOuterRequestor(requestor); - rv = info.SetPrincipalsOnMainThread(info.mPrincipal, info.mStoragePrincipal, - info.mLoadGroup); + rv = info.SetPrincipalOnMainThread(info.mPrincipal, info.mLoadGroup); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } diff --git a/dom/workers/remoteworkers/RemoteWorkerTypes.ipdlh b/dom/workers/remoteworkers/RemoteWorkerTypes.ipdlh index 75c76e1ed9f9..3d4e7725cfbf 100644 --- a/dom/workers/remoteworkers/RemoteWorkerTypes.ipdlh +++ b/dom/workers/remoteworkers/RemoteWorkerTypes.ipdlh @@ -7,7 +7,6 @@ include PBackgroundSharedTypes; include URIParams; using struct mozilla::void_t from "ipc/IPCMessageUtils.h"; -using nsContentUtils::StorageAccess from "mozilla/dom/ClientIPCUtils.h"; namespace mozilla { namespace dom { @@ -38,17 +37,13 @@ struct RemoteWorkerData ContentSecurityPolicy[] principalCsp; ContentSecurityPolicy[] principalPreloadCsp; - PrincipalInfo storagePrincipalInfo; - ContentSecurityPolicy[] storagePrincipalCsp; - ContentSecurityPolicy[] storagePrincipalPreloadCsp; - nsCString domain; bool isSecureContext; IPCClientInfo? clientInfo; - StorageAccess storageAccess; + bool isStorageAccessAllowed; bool isSharedWorker; }; diff --git a/dom/workers/sharedworkers/SharedWorker.cpp b/dom/workers/sharedworkers/SharedWorker.cpp index a675bec46bd0..1c50be1da3f0 100644 --- a/dom/workers/sharedworkers/SharedWorker.cpp +++ b/dom/workers/sharedworkers/SharedWorker.cpp @@ -102,14 +102,14 @@ already_AddRefed SharedWorker::Constructor( do_QueryInterface(aGlobal.GetAsSupports()); MOZ_ASSERT(window); + // If the window is blocked from accessing storage, do not allow it + // to connect to a SharedWorker. This would potentially allow it + // to communicate with other windows that do have storage access. + // Allow private browsing, however, as we handle that isolation + // via the principal. auto storageAllowed = nsContentUtils::StorageAllowedForWindow(window); - if (storageAllowed == nsContentUtils::StorageAccess::eDeny) { - aRv.Throw(NS_ERROR_DOM_SECURITY_ERR); - return nullptr; - } - - if (storageAllowed == nsContentUtils::StorageAccess::ePartitionedOrDeny && - !StaticPrefs::privacy_storagePrincipal_enabledForTrackers()) { + if (storageAllowed != nsContentUtils::StorageAccess::eAllow && + storageAllowed != nsContentUtils::StorageAccess::ePrivateBrowsing) { aRv.Throw(NS_ERROR_DOM_SECURITY_ERR); return nullptr; } @@ -176,57 +176,6 @@ already_AddRefed SharedWorker::Constructor( return nullptr; } - // Here, the StoragePrincipal is always equal to the SharedWorker's principal - // because the channel is not opened yet, and, because of this, it's not - // classified. We need to force the correct originAttributes. - if (storageAllowed == nsContentUtils::StorageAccess::ePartitionedOrDeny) { - nsCOMPtr sop = do_QueryInterface(window); - if (!sop) { - aRv.Throw(NS_ERROR_FAILURE); - return nullptr; - } - - nsIPrincipal* windowPrincipal = sop->GetPrincipal(); - if (!windowPrincipal) { - aRv.Throw(NS_ERROR_UNEXPECTED); - return nullptr; - } - - nsIPrincipal* windowStoragePrincipal = sop->GetEffectiveStoragePrincipal(); - if (!windowStoragePrincipal) { - aRv.Throw(NS_ERROR_UNEXPECTED); - return nullptr; - } - - if (!windowPrincipal->Equals(windowStoragePrincipal)) { - loadInfo.mStoragePrincipal = - BasePrincipal::Cast(loadInfo.mPrincipal) - ->CloneForcingOriginAttributes( - BasePrincipal::Cast(windowStoragePrincipal) - ->OriginAttributesRef()); - } - } - - PrincipalInfo storagePrincipalInfo; - if (loadInfo.mPrincipal->Equals(loadInfo.mStoragePrincipal)) { - storagePrincipalInfo = principalInfo; - } else { - aRv = PrincipalToPrincipalInfo(loadInfo.mStoragePrincipal, - &storagePrincipalInfo); - if (NS_WARN_IF(aRv.Failed())) { - return nullptr; - } - } - - nsTArray storagePrincipalCSP; - nsTArray storagePrincipalPreloadCSP; - aRv = PopulateContentSecurityPolicyArray(loadInfo.mStoragePrincipal, - storagePrincipalCSP, - storagePrincipalPreloadCSP); - if (NS_WARN_IF(aRv.Failed())) { - return nullptr; - } - // We don't actually care about this MessageChannel, but we use it to 'steal' // its 2 connected ports. nsCOMPtr global = do_QueryInterface(window); @@ -255,12 +204,15 @@ already_AddRefed SharedWorker::Constructor( ipcClientInfo.emplace(clientInfo.value().ToIPC()); } + bool storageAccessAllowed = + storageAllowed > nsContentUtils::StorageAccess::eDeny; + RemoteWorkerData remoteWorkerData( nsString(aScriptURL), baseURL, resolvedScriptURL, name, loadingPrincipalInfo, loadingPrincipalCSP, loadingPrincipalPreloadCSP, - principalInfo, principalCSP, principalPreloadCSP, storagePrincipalInfo, - storagePrincipalCSP, storagePrincipalPreloadCSP, loadInfo.mDomain, - isSecureContext, ipcClientInfo, storageAllowed, true /* sharedWorker */); + principalInfo, principalCSP, principalPreloadCSP, loadInfo.mDomain, + isSecureContext, ipcClientInfo, storageAccessAllowed, + true /* sharedWorker */); PSharedWorkerChild* pActor = actorChild->SendPSharedWorkerConstructor( remoteWorkerData, loadInfo.mWindowID, portIdentifier); diff --git a/dom/workers/sharedworkers/SharedWorkerManager.cpp b/dom/workers/sharedworkers/SharedWorkerManager.cpp index c05cb3e07cea..d0b6284af5a6 100644 --- a/dom/workers/sharedworkers/SharedWorkerManager.cpp +++ b/dom/workers/sharedworkers/SharedWorkerManager.cpp @@ -22,13 +22,11 @@ namespace dom { // static already_AddRefed SharedWorkerManager::Create( SharedWorkerService* aService, nsIEventTarget* aPBackgroundEventTarget, - const RemoteWorkerData& aData, nsIPrincipal* aLoadingPrincipal, - const OriginAttributes& aStoragePrincipalAttrs) { + const RemoteWorkerData& aData, nsIPrincipal* aLoadingPrincipal) { MOZ_ASSERT(NS_IsMainThread()); - RefPtr manager = - new SharedWorkerManager(aPBackgroundEventTarget, aData, aLoadingPrincipal, - aStoragePrincipalAttrs); + RefPtr manager = new SharedWorkerManager( + aPBackgroundEventTarget, aData, aLoadingPrincipal); RefPtr holder = new SharedWorkerManagerHolder(manager, aService); @@ -37,12 +35,10 @@ already_AddRefed SharedWorkerManager::Create( SharedWorkerManager::SharedWorkerManager( nsIEventTarget* aPBackgroundEventTarget, const RemoteWorkerData& aData, - nsIPrincipal* aLoadingPrincipal, - const OriginAttributes& aStoragePrincipalAttrs) + nsIPrincipal* aLoadingPrincipal) : mPBackgroundEventTarget(aPBackgroundEventTarget), mLoadingPrincipal(aLoadingPrincipal), mDomain(aData.domain()), - mStoragePrincipalAttrs(aStoragePrincipalAttrs), mResolvedScriptURL(DeserializeURI(aData.resolvedScriptURL())), mName(aData.name()), mIsSecureContext(aData.isSecureContext()), @@ -84,10 +80,11 @@ bool SharedWorkerManager::MaybeCreateRemoteWorker( } already_AddRefed -SharedWorkerManager::MatchOnMainThread( - SharedWorkerService* aService, const nsACString& aDomain, - nsIURI* aScriptURL, const nsAString& aName, nsIPrincipal* aLoadingPrincipal, - const OriginAttributes& aStoragePrincipalAttrs) { +SharedWorkerManager::MatchOnMainThread(SharedWorkerService* aService, + const nsACString& aDomain, + nsIURI* aScriptURL, + const nsAString& aName, + nsIPrincipal* aLoadingPrincipal) { MOZ_ASSERT(NS_IsMainThread()); bool urlEquals; @@ -99,8 +96,7 @@ SharedWorkerManager::MatchOnMainThread( // We want to be sure that the window's principal subsumes the // SharedWorker's loading principal and vice versa. mLoadingPrincipal->Subsumes(aLoadingPrincipal) && - aLoadingPrincipal->Subsumes(mLoadingPrincipal) && - mStoragePrincipalAttrs == aStoragePrincipalAttrs; + aLoadingPrincipal->Subsumes(mLoadingPrincipal); if (!match) { return nullptr; } diff --git a/dom/workers/sharedworkers/SharedWorkerManager.h b/dom/workers/sharedworkers/SharedWorkerManager.h index 5b62062c077a..50ffc10f626c 100644 --- a/dom/workers/sharedworkers/SharedWorkerManager.h +++ b/dom/workers/sharedworkers/SharedWorkerManager.h @@ -67,16 +67,14 @@ class SharedWorkerManager final : public RemoteWorkerObserver { static already_AddRefed Create( SharedWorkerService* aService, nsIEventTarget* aPBackgroundEventTarget, - const RemoteWorkerData& aData, nsIPrincipal* aLoadingPrincipal, - const OriginAttributes& aStoragePrincipalAttrs); + const RemoteWorkerData& aData, nsIPrincipal* aLoadingPrincipal); // Returns a holder if this manager matches. The holder blocks the shutdown of // the manager. already_AddRefed MatchOnMainThread( SharedWorkerService* aService, const nsACString& aDomain, nsIURI* aScriptURL, const nsAString& aName, - nsIPrincipal* aLoadingPrincipal, - const OriginAttributes& aStoragePrincipalAttrs); + nsIPrincipal* aLoadingPrincipal); // RemoteWorkerObserver @@ -116,8 +114,7 @@ class SharedWorkerManager final : public RemoteWorkerObserver { private: SharedWorkerManager(nsIEventTarget* aPBackgroundEventTarget, const RemoteWorkerData& aData, - nsIPrincipal* aLoadingPrincipal, - const OriginAttributes& aStoragePrincipalAttrs); + nsIPrincipal* aLoadingPrincipal); ~SharedWorkerManager(); @@ -125,7 +122,6 @@ class SharedWorkerManager final : public RemoteWorkerObserver { nsCOMPtr mLoadingPrincipal; nsCString mDomain; - OriginAttributes mStoragePrincipalAttrs; nsCOMPtr mResolvedScriptURL; nsString mName; bool mIsSecureContext; diff --git a/dom/workers/sharedworkers/SharedWorkerService.cpp b/dom/workers/sharedworkers/SharedWorkerService.cpp index 4fc898f2c0ac..66d483924248 100644 --- a/dom/workers/sharedworkers/SharedWorkerService.cpp +++ b/dom/workers/sharedworkers/SharedWorkerService.cpp @@ -219,9 +219,16 @@ void SharedWorkerService::GetOrCreateWorkerManagerOnMainThread( MOZ_ASSERT(aActor); nsresult rv = NS_OK; - nsCOMPtr storagePrincipal = - PrincipalInfoToPrincipal(aData.storagePrincipalInfo(), &rv); - if (NS_WARN_IF(!storagePrincipal)) { + nsCOMPtr principal = + PrincipalInfoToPrincipal(aData.principalInfo(), &rv); + if (NS_WARN_IF(!principal)) { + ErrorPropagationOnMainThread(aBackgroundEventTarget, aActor, rv); + return; + } + + rv = PopulatePrincipalContentSecurityPolicy(principal, aData.principalCsp(), + aData.principalPreloadCsp()); + if (NS_WARN_IF(NS_FAILED(rv))) { ErrorPropagationOnMainThread(aBackgroundEventTarget, aActor, rv); return; } @@ -248,8 +255,8 @@ void SharedWorkerService::GetOrCreateWorkerManagerOnMainThread( DeserializeURI(aData.resolvedScriptURL()); for (SharedWorkerManager* workerManager : mWorkerManagers) { managerHolder = workerManager->MatchOnMainThread( - this, aData.domain(), resolvedScriptURL, aData.name(), loadingPrincipal, - BasePrincipal::Cast(storagePrincipal)->OriginAttributesRef()); + this, aData.domain(), resolvedScriptURL, aData.name(), + loadingPrincipal); if (managerHolder) { break; } @@ -257,9 +264,8 @@ void SharedWorkerService::GetOrCreateWorkerManagerOnMainThread( // Let's create a new one. if (!managerHolder) { - managerHolder = SharedWorkerManager::Create( - this, aBackgroundEventTarget, aData, loadingPrincipal, - BasePrincipal::Cast(storagePrincipal)->OriginAttributesRef()); + managerHolder = SharedWorkerManager::Create(this, aBackgroundEventTarget, + aData, loadingPrincipal); mWorkerManagers.AppendElement(managerHolder->Manager()); } else { diff --git a/dom/xml/XMLDocument.cpp b/dom/xml/XMLDocument.cpp index 0b97d08aa899..3c16cb7c00de 100644 --- a/dom/xml/XMLDocument.cpp +++ b/dom/xml/XMLDocument.cpp @@ -129,7 +129,7 @@ nsresult NS_NewDOMDocument(Document** aInstancePtrResult, d->SetLoadedAsData(aLoadedAsData); d->SetDocumentURI(aDocumentURI); // Must set the principal first, since SetBaseURI checks it. - d->SetPrincipals(aPrincipal, aPrincipal); + d->SetPrincipal(aPrincipal); d->SetBaseURI(aBaseURI); // We need to set the script handling object after we set the principal such @@ -252,15 +252,14 @@ void XMLDocument::Reset(nsIChannel* aChannel, nsILoadGroup* aLoadGroup) { } void XMLDocument::ResetToURI(nsIURI* aURI, nsILoadGroup* aLoadGroup, - nsIPrincipal* aPrincipal, - nsIPrincipal* aStoragePrincipal) { + nsIPrincipal* aPrincipal) { if (mChannelIsPending) { StopDocumentLoad(); mChannel->Cancel(NS_BINDING_ABORTED); mChannelIsPending = false; } - Document::ResetToURI(aURI, aLoadGroup, aPrincipal, aStoragePrincipal); + Document::ResetToURI(aURI, aLoadGroup, aPrincipal); } bool XMLDocument::Load(const nsAString& aUrl, CallerType aCallerType, @@ -275,7 +274,6 @@ bool XMLDocument::Load(const nsAString& aUrl, CallerType aCallerType, nsCOMPtr callingDoc = GetEntryDocument(); nsCOMPtr principal = NodePrincipal(); - nsCOMPtr storagePrincipal = EffectiveStoragePrincipal(); // The callingDoc's Principal and doc's Principal should be the same if (callingDoc && (callingDoc->NodePrincipal() != principal)) { @@ -372,7 +370,7 @@ bool XMLDocument::Load(const nsAString& aUrl, CallerType aCallerType, loadGroup = callingDoc->GetDocumentLoadGroup(); } - ResetToURI(uri, loadGroup, principal, storagePrincipal); + ResetToURI(uri, loadGroup, principal); mListenerManager = elm; diff --git a/dom/xml/XMLDocument.h b/dom/xml/XMLDocument.h index e436cff32dca..06206388ef97 100644 --- a/dom/xml/XMLDocument.h +++ b/dom/xml/XMLDocument.h @@ -26,8 +26,7 @@ class XMLDocument : public Document { virtual void Reset(nsIChannel* aChannel, nsILoadGroup* aLoadGroup) override; virtual void ResetToURI(nsIURI* aURI, nsILoadGroup* aLoadGroup, - nsIPrincipal* aPrincipal, - nsIPrincipal* aStoragePrincipal) override; + nsIPrincipal* aPrincipal) override; virtual void SetSuppressParserErrorElement(bool aSuppress) override; virtual bool SuppressParserErrorElement() override; diff --git a/dom/xslt/base/txURIUtils.cpp b/dom/xslt/base/txURIUtils.cpp index fbb350bf61d7..0e5650473e93 100644 --- a/dom/xslt/base/txURIUtils.cpp +++ b/dom/xslt/base/txURIUtils.cpp @@ -46,7 +46,6 @@ void URIUtils::resolveHref(const nsAString& href, const nsAString& base, void URIUtils::ResetWithSource(Document* aNewDoc, nsINode* aSourceNode) { nsCOMPtr sourceDoc = aSourceNode->OwnerDoc(); nsIPrincipal* sourcePrincipal = sourceDoc->NodePrincipal(); - nsIPrincipal* sourceStoragePrincipal = sourceDoc->EffectiveStoragePrincipal(); // Copy the channel and loadgroup from the source document. nsCOMPtr loadGroup = sourceDoc->GetDocumentLoadGroup(); @@ -67,7 +66,7 @@ void URIUtils::ResetWithSource(Document* aNewDoc, nsINode* aSourceNode) { } aNewDoc->Reset(channel, loadGroup); - aNewDoc->SetPrincipals(sourcePrincipal, sourceStoragePrincipal); + aNewDoc->SetPrincipal(sourcePrincipal); aNewDoc->SetBaseURI(sourceDoc->GetDocBaseURI()); // Copy charset diff --git a/dom/xul/XULDocument.cpp b/dom/xul/XULDocument.cpp index f79ecd3e1e52..3352241a8857 100644 --- a/dom/xul/XULDocument.cpp +++ b/dom/xul/XULDocument.cpp @@ -193,8 +193,7 @@ void XULDocument::Reset(nsIChannel* aChannel, nsILoadGroup* aLoadGroup) { } void XULDocument::ResetToURI(nsIURI* aURI, nsILoadGroup* aLoadGroup, - nsIPrincipal* aPrincipal, - nsIPrincipal* aStoragePrincipal) { + nsIPrincipal* aPrincipal) { MOZ_ASSERT_UNREACHABLE("ResetToURI"); } @@ -243,21 +242,10 @@ nsresult XULDocument::StartDocumentLoad(const char* aCommand, // Get the document's principal nsCOMPtr principal; - nsCOMPtr storagePrincipal; - rv = nsContentUtils::GetSecurityManager()->GetChannelResultPrincipals( - mChannel, getter_AddRefs(principal), getter_AddRefs(storagePrincipal)); - NS_ENSURE_SUCCESS(rv, rv); - - bool equal = principal->Equals(storagePrincipal); - + nsContentUtils::GetSecurityManager()->GetChannelResultPrincipal( + mChannel, getter_AddRefs(principal)); principal = MaybeDowngradePrincipal(principal); - if (equal) { - storagePrincipal = principal; - } else { - storagePrincipal = MaybeDowngradePrincipal(storagePrincipal); - } - - SetPrincipals(principal, storagePrincipal); + SetPrincipal(principal); ResetStylesheetsToURI(mDocumentURI); diff --git a/dom/xul/XULDocument.h b/dom/xul/XULDocument.h index add682e8f752..53d3b0e71f74 100644 --- a/dom/xul/XULDocument.h +++ b/dom/xul/XULDocument.h @@ -59,8 +59,7 @@ class XULDocument final : public XMLDocument { // Document interface virtual void Reset(nsIChannel* aChannel, nsILoadGroup* aLoadGroup) override; virtual void ResetToURI(nsIURI* aURI, nsILoadGroup* aLoadGroup, - nsIPrincipal* aPrincipal, - nsIPrincipal* aStoragePrincipal) override; + nsIPrincipal* aPrincipal) override; virtual nsresult StartDocumentLoad(const char* aCommand, nsIChannel* channel, nsILoadGroup* aLoadGroup, diff --git a/js/xpconnect/src/BackstagePass.h b/js/xpconnect/src/BackstagePass.h index da171522cf65..cb3c9bb9b77d 100644 --- a/js/xpconnect/src/BackstagePass.h +++ b/js/xpconnect/src/BackstagePass.h @@ -29,10 +29,6 @@ class BackstagePass : public nsIGlobalObject, virtual nsIPrincipal* GetPrincipal() override { return mPrincipal; } - virtual nsIPrincipal* GetEffectiveStoragePrincipal() override { - return nullptr; - } - virtual JSObject* GetGlobalJSObject() override; void ForgetGlobalObject() { mWrapper = nullptr; } diff --git a/js/xpconnect/src/SandboxPrivate.h b/js/xpconnect/src/SandboxPrivate.h index e41f3f3bdc6c..bac428da169c 100644 --- a/js/xpconnect/src/SandboxPrivate.h +++ b/js/xpconnect/src/SandboxPrivate.h @@ -45,8 +45,6 @@ class SandboxPrivate : public nsIGlobalObject, nsIPrincipal* GetPrincipal() override { return mPrincipal; } - nsIPrincipal* GetEffectiveStoragePrincipal() override { return nullptr; } - JSObject* GetGlobalJSObject() override { return GetWrapper(); } void ForgetGlobalObject(JSObject* obj) { ClearWrapper(obj); } diff --git a/layout/build/nsContentDLF.cpp b/layout/build/nsContentDLF.cpp index 059fb5345b73..a4ffc0ffad14 100644 --- a/layout/build/nsContentDLF.cpp +++ b/layout/build/nsContentDLF.cpp @@ -277,7 +277,7 @@ already_AddRefed nsContentDLF::CreateBlankDocument( if (!uri) { return nullptr; } - blankDoc->ResetToURI(uri, aLoadGroup, aPrincipal, aPrincipal); + blankDoc->ResetToURI(uri, aLoadGroup, aPrincipal); blankDoc->SetContainer(aContainer); // add some simple content structure diff --git a/modules/libpref/init/StaticPrefList.h b/modules/libpref/init/StaticPrefList.h index 1c4631127f7b..93de7d2a539d 100644 --- a/modules/libpref/init/StaticPrefList.h +++ b/modules/libpref/init/StaticPrefList.h @@ -2233,12 +2233,6 @@ VARCACHE_PREF( RelaxedAtomicBool, false ) -VARCACHE_PREF( - "privacy.storagePrincipal.enabledForTrackers", - privacy_storagePrincipal_enabledForTrackers, - RelaxedAtomicBool, false -) - // Password protection VARCACHE_PREF( "browser.safebrowsing.passwords.enabled", diff --git a/netwerk/base/LoadInfo.cpp b/netwerk/base/LoadInfo.cpp index b263ad3ba813..54c8899e5edf 100644 --- a/netwerk/base/LoadInfo.cpp +++ b/netwerk/base/LoadInfo.cpp @@ -189,12 +189,6 @@ LoadInfo::LoadInfo( !nsContentUtils::IsInPrivateBrowsing(doc))) { mTopLevelStorageAreaPrincipal = innerWindow->GetPrincipal(); } - - // If this is the first level iframe, innerWindow is our top-level - // principal. - if (!mTopLevelPrincipal) { - mTopLevelPrincipal = innerWindow->GetPrincipal(); - } } mDocumentHasLoaded = innerWindow->IsDocumentLoaded(); diff --git a/netwerk/base/nsNetUtil.cpp b/netwerk/base/nsNetUtil.cpp index 7d3671c078bc..c0d53fed3319 100644 --- a/netwerk/base/nsNetUtil.cpp +++ b/netwerk/base/nsNetUtil.cpp @@ -16,7 +16,6 @@ #include "mozilla/LoadInfo.h" #include "mozilla/BasePrincipal.h" #include "mozilla/Monitor.h" -#include "mozilla/StoragePrincipalHelper.h" #include "mozilla/TaskQueue.h" #include "mozilla/Telemetry.h" #include "nsCategoryCache.h" @@ -1852,14 +1851,13 @@ nsresult NS_LoadPersistentPropertiesFromURISpec( bool NS_UsePrivateBrowsing(nsIChannel *channel) { OriginAttributes attrs; - bool result = NS_GetOriginAttributes(channel, attrs, false); + bool result = NS_GetOriginAttributes(channel, attrs); NS_ENSURE_TRUE(result, result); return attrs.mPrivateBrowsingId > 0; } bool NS_GetOriginAttributes(nsIChannel *aChannel, - mozilla::OriginAttributes &aAttributes, - bool aUsingStoragePrincipal) { + mozilla::OriginAttributes &aAttributes) { nsCOMPtr loadInfo = aChannel->LoadInfo(); loadInfo->GetOriginAttributes(&aAttributes); @@ -1875,10 +1873,6 @@ bool NS_GetOriginAttributes(nsIChannel *aChannel, isPrivate = loadContext && loadContext->UsePrivateBrowsing(); } aAttributes.SyncAttributesWithPrivateBrowsing(isPrivate); - - if (aUsingStoragePrincipal) { - StoragePrincipalHelper::PrepareOriginAttributes(aChannel, aAttributes); - } return true; } diff --git a/netwerk/base/nsNetUtil.h b/netwerk/base/nsNetUtil.h index 88581e7fa9e5..a88499906429 100644 --- a/netwerk/base/nsNetUtil.h +++ b/netwerk/base/nsNetUtil.h @@ -610,12 +610,9 @@ bool NS_UsePrivateBrowsing(nsIChannel *channel); /** * Extract the OriginAttributes from the channel's triggering principal. - * If aUsingStoragePrincipal is set to true, the originAttributes could have - * first-party isolation domain set to the top-level URI. */ bool NS_GetOriginAttributes(nsIChannel *aChannel, - mozilla::OriginAttributes &aAttributes, - bool aUsingStoragePrincipal = false); + mozilla::OriginAttributes &aAttributes); /** * Returns true if the channel has visited any cross-origin URLs on any diff --git a/netwerk/cookie/CookieServiceChild.cpp b/netwerk/cookie/CookieServiceChild.cpp index 39d48f630829..20c5a798959a 100644 --- a/netwerk/cookie/CookieServiceChild.cpp +++ b/netwerk/cookie/CookieServiceChild.cpp @@ -13,7 +13,6 @@ #include "mozilla/ipc/URIUtils.h" #include "mozilla/net/NeckoChild.h" #include "mozilla/SystemGroup.h" -#include "mozilla/StoragePrincipalHelper.h" #include "nsCookie.h" #include "nsCookieService.h" #include "nsContentUtils.h" @@ -176,7 +175,6 @@ void CookieServiceChild::TrackCookieLoad(nsIChannel *aChannel) { } } mozilla::OriginAttributes attrs = loadInfo->GetOriginAttributes(); - StoragePrincipalHelper::PrepareOriginAttributes(aChannel, attrs); URIParams uriParams; SerializeURI(uri, uriParams); bool isSafeTopLevelNav = NS_IsSafeTopLevelNav(aChannel); @@ -296,7 +294,6 @@ void CookieServiceChild::GetCookieStringFromCookieHashTable( if (aChannel) { loadInfo = aChannel->LoadInfo(); attrs = loadInfo->GetOriginAttributes(); - StoragePrincipalHelper::PrepareOriginAttributes(aChannel, attrs); } nsCookieService::GetBaseDomain(TLDService, aHostURI, baseDomain, @@ -565,7 +562,6 @@ nsresult CookieServiceChild::SetCookieStringInternal(nsIURI *aHostURI, MOZ_ASSERT(loadInfo); attrs = loadInfo->GetOriginAttributes(); - StoragePrincipalHelper::PrepareOriginAttributes(aChannel, attrs); } else { SerializeURI(nullptr, channelURIParams); } @@ -577,7 +573,7 @@ nsresult CookieServiceChild::SetCookieStringInternal(nsIURI *aHostURI, if (mIPCOpen) { SendSetCookieString(hostURIParams, channelURIParams, optionalLoadInfoArgs, isForeign, isTrackingResource, - firstPartyStorageAccessGranted, attrs, cookieString, + firstPartyStorageAccessGranted, cookieString, stringServerTime, aFromHttp); } diff --git a/netwerk/cookie/CookieServiceParent.cpp b/netwerk/cookie/CookieServiceParent.cpp index e78e148e7310..384622dd2cf5 100644 --- a/netwerk/cookie/CookieServiceParent.cpp +++ b/netwerk/cookie/CookieServiceParent.cpp @@ -9,7 +9,6 @@ #include "mozilla/BasePrincipal.h" #include "mozilla/ipc/URIUtils.h" -#include "mozilla/StoragePrincipalHelper.h" #include "nsArrayUtils.h" #include "nsCookieService.h" #include "nsIChannel.h" @@ -127,8 +126,6 @@ void CookieServiceParent::TrackCookieLoad(nsIChannel *aChannel) { bool isSafeTopLevelNav = NS_IsSafeTopLevelNav(aChannel); bool aIsSameSiteForeign = NS_IsSameSiteForeign(aChannel, uri); - StoragePrincipalHelper::PrepareOriginAttributes(aChannel, attrs); - // Send matching cookies to Child. nsCOMPtr thirdPartyUtil; thirdPartyUtil = do_GetService(THIRDPARTYUTIL_CONTRACTID); @@ -210,9 +207,8 @@ mozilla::ipc::IPCResult CookieServiceParent::RecvSetCookieString( const URIParams &aHost, const Maybe &aChannelURI, const Maybe &aLoadInfoArgs, const bool &aIsForeign, const bool &aIsTrackingResource, - const bool &aFirstPartyStorageAccessGranted, const OriginAttributes &aAttrs, - const nsCString &aCookieString, const nsCString &aServerTime, - const bool &aFromHttp) { + const bool &aFirstPartyStorageAccessGranted, const nsCString &aCookieString, + const nsCString &aServerTime, const bool &aFromHttp) { if (!mCookieService) return IPC_OK(); // Deserialize URI. Having a host URI is mandatory and should always be @@ -244,12 +240,17 @@ mozilla::ipc::IPCResult CookieServiceParent::RecvSetCookieString( // NB: dummyChannel could be null if something failed in CreateDummyChannel. nsDependentCString cookieString(aCookieString, 0); + OriginAttributes attrs; + if (loadInfo) { + attrs = loadInfo->GetOriginAttributes(); + } + // We set this to true while processing this cookie update, to make sure // we don't send it back to the same content process. mProcessingCookie = true; mCookieService->SetCookieStringInternal( hostURI, aIsForeign, aIsTrackingResource, aFirstPartyStorageAccessGranted, - cookieString, aServerTime, aFromHttp, aAttrs, dummyChannel); + cookieString, aServerTime, aFromHttp, attrs, dummyChannel); mProcessingCookie = false; return IPC_OK(); } diff --git a/netwerk/cookie/CookieServiceParent.h b/netwerk/cookie/CookieServiceParent.h index 8d67a2958ea3..3129bf96c5e6 100644 --- a/netwerk/cookie/CookieServiceParent.h +++ b/netwerk/cookie/CookieServiceParent.h @@ -49,8 +49,8 @@ class CookieServiceParent : public PCookieServiceParent { const Maybe &aLoadInfoArgs, const bool &aIsForeign, const bool &aIsTrackingResource, const bool &aFirstPartyStorageAccessGranted, - const OriginAttributes &aAttrs, const nsCString &aCookieString, - const nsCString &aServerTime, const bool &aFromHttp); + const nsCString &aCookieString, const nsCString &aServerTime, + const bool &aFromHttp); mozilla::ipc::IPCResult RecvPrepareCookieList( const URIParams &aHost, const bool &aIsForeign, diff --git a/netwerk/cookie/PCookieService.ipdl b/netwerk/cookie/PCookieService.ipdl index 0d02a097c839..4f8f3985f45a 100644 --- a/netwerk/cookie/PCookieService.ipdl +++ b/netwerk/cookie/PCookieService.ipdl @@ -75,7 +75,6 @@ parent: bool isForeign, bool isTrackingResource, bool firstPartyStorageAccessGranted, - OriginAttributes aStoragePrincipalAttrs, nsCString cookieString, nsCString serverTime, bool aFromHttp); diff --git a/netwerk/cookie/nsCookieService.cpp b/netwerk/cookie/nsCookieService.cpp index 0fb1e4d41511..be266997c579 100644 --- a/netwerk/cookie/nsCookieService.cpp +++ b/netwerk/cookie/nsCookieService.cpp @@ -1990,8 +1990,7 @@ nsresult nsCookieService::GetCookieStringCommon(nsIURI *aHostURI, OriginAttributes attrs; if (aChannel) { - NS_GetOriginAttributes(aChannel, attrs, - true /* considering storage principal */); + NS_GetOriginAttributes(aChannel, attrs); } bool isSafeTopLevelNav = NS_IsSafeTopLevelNav(aChannel); @@ -2110,8 +2109,7 @@ nsresult nsCookieService::SetCookieStringCommon(nsIURI *aHostURI, OriginAttributes attrs; if (aChannel) { - NS_GetOriginAttributes(aChannel, attrs, - true /* considering storage principal */); + NS_GetOriginAttributes(aChannel, attrs); } nsDependentCString cookieString(aCookieHeader); @@ -4042,12 +4040,6 @@ CookieStatus nsCookieService::CheckPrefs( if (aIsForeign && aIsTrackingResource && !aFirstPartyStorageAccessGranted && aCookieSettings->GetCookieBehavior() == nsICookieService::BEHAVIOR_REJECT_TRACKER) { - if (StaticPrefs::privacy_storagePrincipal_enabledForTrackers()) { - MOZ_ASSERT(!aOriginAttrs.mFirstPartyDomain.IsEmpty(), - "We must have a StoragePrincipal here!"); - return STATUS_ACCEPTED; - } - COOKIE_LOGFAILURE(aCookieHeader ? SET_COOKIE : GET_COOKIE, aHostURI, aCookieHeader, "cookies are disabled in trackers"); *aRejectedReason = nsIWebProgressListener::STATE_COOKIES_BLOCKED_TRACKER; diff --git a/parser/prototype/PrototypeDocumentParser.cpp b/parser/prototype/PrototypeDocumentParser.cpp index 88b2ffb6e24e..37170d38123d 100644 --- a/parser/prototype/PrototypeDocumentParser.cpp +++ b/parser/prototype/PrototypeDocumentParser.cpp @@ -84,8 +84,7 @@ PrototypeDocumentParser::Parse(nsIURI* aURL, nsIRequestObserver* aListener, mCurrentPrototype = proto; // Set up the right principal on the document. - mDocument->SetPrincipals(proto->DocumentPrincipal(), - proto->DocumentPrincipal()); + mDocument->SetPrincipal(proto->DocumentPrincipal()); } else { // It's just a vanilla document load. Create a parser to deal // with the stream n' stuff. @@ -186,7 +185,7 @@ nsresult PrototypeDocumentParser::PrepareToLoadPrototype( nsXULPrototypeCache::GetInstance()->PutPrototype(mCurrentPrototype); } - mDocument->SetPrincipals(aDocumentPrincipal, aDocumentPrincipal); + mDocument->SetPrincipal(aDocumentPrincipal); // Create a XUL content sink, a parser, and kick off a load for // the document. diff --git a/toolkit/components/antitracking/StoragePrincipalHelper.cpp b/toolkit/components/antitracking/StoragePrincipalHelper.cpp deleted file mode 100644 index 3faad336484f..000000000000 --- a/toolkit/components/antitracking/StoragePrincipalHelper.cpp +++ /dev/null @@ -1,100 +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 "StoragePrincipalHelper.h" - -#include "mozilla/ScopeExit.h" -#include "mozilla/StaticPrefs.h" -#include "nsContentUtils.h" -#include "nsIHttpChannel.h" - -namespace mozilla { - -namespace { - -already_AddRefed MaybeGetFirstPartyURI(nsIChannel* aChannel) { - MOZ_ASSERT(aChannel); - - if (!StaticPrefs::privacy_storagePrincipal_enabledForTrackers()) { - return nullptr; - } - - // Let's use the storage principal only if we need to partition the cookie - // jar. - nsContentUtils::StorageAccess access = - nsContentUtils::StorageAllowedForChannel(aChannel); - if (access != nsContentUtils::StorageAccess::ePartitionedOrDeny) { - return nullptr; - } - - nsCOMPtr httpChannel = do_QueryInterface(aChannel); - if (!httpChannel) { - return nullptr; - } - - MOZ_ASSERT(httpChannel->IsThirdPartyTrackingResource()); - - nsCOMPtr loadInfo = aChannel->LoadInfo(); - nsCOMPtr toplevelPrincipal = loadInfo->GetTopLevelPrincipal(); - if (!toplevelPrincipal) { - return nullptr; - } - - nsCOMPtr principalURI; - nsresult rv = toplevelPrincipal->GetURI(getter_AddRefs(principalURI)); - if (NS_WARN_IF(NS_FAILED(rv))) { - return nullptr; - } - - return principalURI.forget(); -} - -} // namespace - -// static -nsresult StoragePrincipalHelper::Create(nsIChannel* aChannel, - nsIPrincipal* aPrincipal, - nsIPrincipal** aStoragePrincipal) { - MOZ_ASSERT(aChannel); - MOZ_ASSERT(aPrincipal); - MOZ_ASSERT(aStoragePrincipal); - - auto scopeExit = MakeScopeExit([&] { - nsCOMPtr storagePrincipal = aPrincipal; - storagePrincipal.forget(aStoragePrincipal); - }); - - nsCOMPtr principalURI = MaybeGetFirstPartyURI(aChannel); - if (!principalURI) { - return NS_OK; - } - - scopeExit.release(); - - nsCOMPtr storagePrincipal = - BasePrincipal::Cast(aPrincipal) - ->CloneForcingFirstPartyDomain(principalURI); - - storagePrincipal.forget(aStoragePrincipal); - return NS_OK; -} - -// static -nsresult StoragePrincipalHelper::PrepareOriginAttributes( - nsIChannel* aChannel, OriginAttributes& aOriginAttributes) { - MOZ_ASSERT(aChannel); - - nsCOMPtr principalURI = MaybeGetFirstPartyURI(aChannel); - if (!principalURI) { - return NS_OK; - } - - aOriginAttributes.SetFirstPartyDomain(false, principalURI, - true /* aForced */); - return NS_OK; -} - -} // namespace mozilla diff --git a/toolkit/components/antitracking/StoragePrincipalHelper.h b/toolkit/components/antitracking/StoragePrincipalHelper.h deleted file mode 100644 index f50acb8b0ace..000000000000 --- a/toolkit/components/antitracking/StoragePrincipalHelper.h +++ /dev/null @@ -1,137 +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 mozilla_StoragePrincipalHelper_h -#define mozilla_StoragePrincipalHelper_h - -/** - * StoragePrincipal - * ~~~~~~~~~~~~~~~~ - * - * StoragePrincipal is the nsIPrincipal to be used to open the cookie jar of a - * resource's origin. Normally, the StoragePrincipal corresponds to the - * resource's origin, but, in some scenarios, it can be different: it can have - * some extra origin attributes. - * - * Each storage component, should always use the StoragePrincipal instead of the - * 'real' one in order to implement the partitioning correctly. - * - * On the web, each resource has its own origin (see - * https://html.spec.whatwg.org/multipage/origin.html#concept-origin) and each - * origin has its own cookie jar, containing cookies, storage data, cache and so - * on. - * - * In addition, gecko has a set of attributes to differentiate the same origin - * in different contexts (OriginAttributes). The main ones are: - * - privateBrowsingId, for private browsing navigation. - * - userContextId, for containers - * - firstPartyIsolation, for TOR. - * - * In gecko-world, the origin and its attributes are stored and managed by the - * nsIPrincipal interface. Both resource's Principal and resource's - * StoragePrincipal are nsIPrincipal interfaces and, normally, they are the same - * object. - * - * Here is the way you can obtain the two Principals: - * From a Document: - * - Document's principal: nsINode::NodePrincipal - * - Document's StoragePrincipal: Document::EffectiveStoragePrincipal - * From a Global object: - * - nsIScriptObjectPrincipal::getPrincipal - * - nsIScriptObjectPrincipal::getEffectiveStoragePrincipal - * From a Worker: - * - WorkerPrivate::GetPrincipal(). - * - WorkerPrivate::GetEffectiveStoragePrincipal(); - * For a nsIChannel, the final principals must be calculated and they can be - * obtained by calling: - * - nsIScriptSecurityManager::getChannelResultPrincipal() or - * - nsIScriptSecurityManager::getChannelResultStoragePrincipal(). - * - * Principal VS StoragePrincipal - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * At the moment, we are experimenting the partitioning of cookie jars for 3rd - * party trackers: each 3rd party origin, detected as a tracker, will have a - * partitioned cookie jar, created by the tracker's origin, plus, the - * first-party domain. - * - * This means that, for those origins, StoragePrincipal will be equal to the - * main Principal but it will also have the 'first-party-domain' attribute set - * as the first-party URL's domain. Because of this, the tracker's cookie jar - * will be partitioned and it will be unique per first-party domain. - * - * The naminig is important. This is why Document has the StoragePrincipal - * stored in a member variable called mIntrinsicStoragePrincipal: this - * storagePrincipal is immutable even when Document::EffectiveStoragePrincipal - * returns the main principal. - * - * Storage access permission - * ~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * A resource's origin and its attributes are immutable. StoragePrincipal can - * change: when a tracker has the storage permission granted, its - * StoragePrincipal becomes equal to its document's principal. In this way, the - * tracker will have access to its first-party cookie jar, escaping from the - * its partitioning. - * - * To know more about when the storage access permission is granted, see the - * anti-tracking project's documentation. - * See: https://developer.mozilla.org/en-US/docs/Web/API/Storage_Access_API and - * https://developer.mozilla.org/en-US/docs/Mozilla/Firefox/Privacy/Storage_access_policy#Storage_access_grants - * - * - * When the storage access permission is granted, any of the StoragePrincipal - * getter methods will return the main principal instead of the storage one, and - * each storage component should consider the new Principal only. - * - * There are several ways to receive storage-permission notifications: - * - Add some code in nsGlobalWindowInner::StorageAccessGranted(). - * - WorkerScope::FirstPartyStorageAccessGranted for Workers. - * - observe the permission changes (not recommended) - * - * SharedWorkers and BroadcastChannels - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * SharedWorker and BroadcastChannel instances latch the effective storage - * principal at the moment of their creation. Existing bindings to the - * partitioned storage principal will continue to exist and operate even as it - * becomes possible to create bindings associated with the non-partitioned node - * principal. This makes it possible for such globals to bi-directionally - * bridge information between partitioned and non-partitioned principals. - * - * {Dedicated,Shared,Service}Workers - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * The storage access permission propagation happens with a ControlRunnable. - * This could impact the use of sync event-loops. Take a reference of the - * principal you want to use because it can change! - * - * ServiceWorkers are currently disabled for partitioned contexts. - * - * Client API uses the main principal always because there is not a direct - * connection between this API and the cookie jar. If we want to support - * ServiceWorkers in partitioned context, this part must be revisited. - */ - -class nsIChannel; -class nsIPrincipal; - -namespace mozilla { - -class OriginAttributes; - -class StoragePrincipalHelper final { - public: - static nsresult Create(nsIChannel* aChannel, nsIPrincipal* aPrincipal, - nsIPrincipal** aStoragePrincipal); - - static nsresult PrepareOriginAttributes(nsIChannel* aChannel, - OriginAttributes& aOriginAttributes); -}; - -} // namespace mozilla - -#endif // mozilla_StoragePrincipalHelper_h diff --git a/toolkit/components/antitracking/moz.build b/toolkit/components/antitracking/moz.build index de454c3df547..04e329f253d5 100644 --- a/toolkit/components/antitracking/moz.build +++ b/toolkit/components/antitracking/moz.build @@ -9,12 +9,10 @@ with Files('**'): EXPORTS.mozilla = [ 'AntiTrackingCommon.h', - 'StoragePrincipalHelper.h', ] UNIFIED_SOURCES += [ 'AntiTrackingCommon.cpp', - 'StoragePrincipalHelper.cpp', ] LOCAL_INCLUDES += [ diff --git a/toolkit/components/antitracking/test/browser/3rdPartyStorage.html b/toolkit/components/antitracking/test/browser/3rdPartyStorage.html deleted file mode 100644 index 749ead7c20d2..000000000000 --- a/toolkit/components/antitracking/test/browser/3rdPartyStorage.html +++ /dev/null @@ -1,44 +0,0 @@ - - - 3rd party content! - - - -

Here the 3rd party content!

- - - diff --git a/toolkit/components/antitracking/test/browser/3rdPartyStorageWO.html b/toolkit/components/antitracking/test/browser/3rdPartyStorageWO.html deleted file mode 100644 index b04916103ddf..000000000000 --- a/toolkit/components/antitracking/test/browser/3rdPartyStorageWO.html +++ /dev/null @@ -1,8 +0,0 @@ - - - 1st party content! - - -

Here the 1st party content!

- - diff --git a/toolkit/components/antitracking/test/browser/antitracking_head.js b/toolkit/components/antitracking/test/browser/antitracking_head.js deleted file mode 100644 index 76463b613440..000000000000 --- a/toolkit/components/antitracking/test/browser/antitracking_head.js +++ /dev/null @@ -1,707 +0,0 @@ -/* vim: set ts=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/. */ - -/* import-globals-from head.js */ - -"use strict"; - -var gFeatures = undefined; - -this.AntiTracking = { - runTest(name, callbackTracking, callbackNonTracking, cleanupFunction, extraPrefs, - windowOpenTest = true, userInteractionTest = true, - expectedBlockingNotifications = Ci.nsIWebProgressListener.STATE_COOKIES_BLOCKED_TRACKER, - runInPrivateWindow = false, iframeSandbox = null, accessRemoval = null, - callbackAfterRemoval = null) { - // Here we want to test that a 3rd party context is simply blocked. - this._createTask({ - name, - cookieBehavior: BEHAVIOR_REJECT_TRACKER, - blockingByContentBlockingRTUI: true, - allowList: false, - callback: callbackTracking, - extraPrefs, - expectedBlockingNotifications, - runInPrivateWindow, - iframeSandbox, - accessRemoval, - callbackAfterRemoval, - }); - this._createCleanupTask(cleanupFunction); - - this._createTask({ - name, - cookieBehavior: BEHAVIOR_REJECT_TRACKER, - blockingByContentBlockingRTUI: false, - allowList: true, - callback: callbackTracking, - extraPrefs, - expectedBlockingNotifications, - runInPrivateWindow, - iframeSandbox, - accessRemoval, - callbackAfterRemoval, - }); - this._createCleanupTask(cleanupFunction); - - if (callbackNonTracking) { - let runExtraTests = true; - let options = {}; - if (typeof callbackNonTracking == "object") { - options.callback = callbackNonTracking.callback; - runExtraTests = callbackNonTracking.runExtraTests; - if ("cookieBehavior" in callbackNonTracking) { - options.cookieBehavior = callbackNonTracking.cookieBehavior; - } else { - options.cookieBehavior = BEHAVIOR_ACCEPT; - } - if ("blockingByContentBlockingRTUI" in callbackNonTracking) { - options.blockingByContentBlockingRTUI = - callbackNonTracking.blockingByContentBlockingRTUI; - } else { - options.blockingByContentBlockingRTUI = false; - } - if ("blockingByAllowList" in callbackNonTracking) { - options.blockingByAllowList = - callbackNonTracking.blockingByAllowList; - } else { - options.blockingByAllowList = false; - } - callbackNonTracking = options.callback; - options.accessRemoval = null; - options.callbackAfterRemoval = null; - } - - // Phase 1: Here we want to test that a 3rd party context is not blocked if pref is off. - if (runExtraTests) { - // There are five ways in which the third-party context may not be blocked: - // * If the cookieBehavior pref causes it to not be blocked. - // * If the contentBlocking pref causes it to not be blocked. - // * If both of these prefs cause it to not be blocked. - // * If the top-level page is on the content blocking allow list. - // * If the contentBlocking third-party cookies UI pref is off, the allow list will be ignored. - // All of these cases are tested here. - this._createTask({ - name, - cookieBehavior: BEHAVIOR_ACCEPT, - blockingByContentBlockingRTUI: true, - allowList: false, - callback: callbackNonTracking, - extraPrefs, - expectedBlockingNotifications: 0, - runInPrivateWindow, - iframeSandbox, - accessRemoval: null, // only passed with non-blocking callback - callbackAfterRemoval: null, - }); - this._createCleanupTask(cleanupFunction); - - this._createTask({ - name, - cookieBehavior: BEHAVIOR_ACCEPT, - blockingByContentBlockingRTUI: false, - allowList: true, - callback: callbackNonTracking, - extraPrefs, - expectedBlockingNotifications: 0, - runInPrivateWindow, - iframeSandbox, - accessRemoval: null, // only passed with non-blocking callback - callbackAfterRemoval: null, - }); - this._createCleanupTask(cleanupFunction); - - this._createTask({ - name, - cookieBehavior: BEHAVIOR_ACCEPT, - blockingByContentBlockingRTUI: false, - allowList: false, - callback: callbackNonTracking, - extraPrefs, - expectedBlockingNotifications: 0, - runInPrivateWindow, - iframeSandbox, - accessRemoval: null, // only passed with non-blocking callback - callbackAfterRemoval: null, - }); - this._createCleanupTask(cleanupFunction); - - this._createTask({ - name, - cookieBehavior: BEHAVIOR_REJECT, - blockingByContentBlockingRTUI: true, - allowList: false, - callback: callbackTracking, - extraPrefs, - expectedBlockingNotifications: 0, - runInPrivateWindow, - iframeSandbox, - accessRemoval: null, // only passed with non-blocking callback - callbackAfterRemoval: null, - }); - this._createCleanupTask(cleanupFunction); - - this._createTask({ - name, - cookieBehavior: BEHAVIOR_LIMIT_FOREIGN, - blockingByContentBlockingRTUI: true, - allowList: true, - callback: callbackNonTracking, - extraPrefs, - expectedBlockingNotifications: 0, - runInPrivateWindow, - iframeSandbox, - accessRemoval: null, // only passed with non-blocking callback - callbackAfterRemoval: null, - }); - this._createCleanupTask(cleanupFunction); - - this._createTask({ - name, - cookieBehavior: BEHAVIOR_REJECT_FOREIGN, - blockingByContentBlockingRTUI: true, - allowList: true, - callback: callbackNonTracking, - extraPrefs, - expectedBlockingNotifications: 0, - runInPrivateWindow, - iframeSandbox, - accessRemoval: null, // only passed with non-blocking callback - callbackAfterRemoval: null, - }); - this._createCleanupTask(cleanupFunction); - - this._createTask({ - name, - cookieBehavior: BEHAVIOR_REJECT_TRACKER, - blockingByContentBlockingRTUI: true, - allowList: true, - callback: callbackNonTracking, - extraPrefs, - expectedBlockingNotifications: 0, - runInPrivateWindow, - iframeSandbox, - accessRemoval, - callbackAfterRemoval, - }); - this._createCleanupTask(cleanupFunction); - - this._createTask({ - name, - cookieBehavior: BEHAVIOR_REJECT_TRACKER, - blockingByContentBlockingRTUI: false, - allowList: false, - callback: callbackNonTracking, - extraPrefs, - expectedBlockingNotifications: false, - runInPrivateWindow, - iframeSandbox, - accessRemoval: null, // only passed with non-blocking callback - callbackAfterRemoval: null, - thirdPartyPage: TEST_ANOTHER_3RD_PARTY_PAGE, - }); - this._createCleanupTask(cleanupFunction); - } - - // Phase 2: Here we want to test that a third-party context doesn't - // get blocked with when the same origin is opened through window.open(). - if (windowOpenTest) { - this._createWindowOpenTask(name, callbackTracking, callbackNonTracking, - runInPrivateWindow, iframeSandbox, extraPrefs); - this._createCleanupTask(cleanupFunction); - } - - // Phase 3: Here we want to test that a third-party context doesn't - // get blocked with user interaction present - if (userInteractionTest) { - this._createUserInteractionTask(name, callbackTracking, callbackNonTracking, - runInPrivateWindow, iframeSandbox, extraPrefs); - this._createCleanupTask(cleanupFunction); - } - } - }, - - async interactWithTracker() { - let windowClosed = new Promise(resolve => { - Services.ww.registerNotification(function notification(aSubject, aTopic, aData) { - if (aTopic == "domwindowclosed") { - Services.ww.unregisterNotification(notification); - resolve(); - } - }); - }); - - info("Let's interact with the tracker"); - window.open(TEST_3RD_PARTY_DOMAIN + TEST_PATH + "3rdPartyOpenUI.html"); - await windowClosed; - }, - - async _setupTest(win, cookieBehavior, blockingByContentBlockingRTUI, - extraPrefs) { - await SpecialPowers.flushPrefEnv(); - await SpecialPowers.pushPrefEnv({"set": [ - ["dom.storage_access.enabled", true], - ["browser.contentblocking.allowlist.annotations.enabled", blockingByContentBlockingRTUI], - ["browser.contentblocking.allowlist.storage.enabled", blockingByContentBlockingRTUI], - ["network.cookie.cookieBehavior", cookieBehavior], - ["privacy.trackingprotection.enabled", false], - ["privacy.trackingprotection.pbmode.enabled", false], - ["privacy.trackingprotection.annotate_channels", cookieBehavior != BEHAVIOR_ACCEPT], - [win.ContentBlocking.prefIntroCount, win.ContentBlocking.MAX_INTROS], - ["privacy.restrict3rdpartystorage.userInteractionRequiredForHosts", "tracking.example.com,tracking.example.org"], - ]}); - - if (extraPrefs && Array.isArray(extraPrefs) && extraPrefs.length) { - await SpecialPowers.pushPrefEnv({"set": extraPrefs }); - - for (let item of extraPrefs) { - // When setting up skip URLs, we need to wait to ensure our prefs - // actually take effect. In order to do this, we set up a skip list - // observer and wait until it calls us back. - if (item[0] == "urlclassifier.trackingAnnotationSkipURLs") { - info("Waiting for the skip list service to initialize..."); - let classifier = Cc["@mozilla.org/url-classifier/dbservice;1"] - .getService(Ci.nsIURIClassifier); - let feature = classifier.getFeatureByName("tracking-annotation"); - await TestUtils.waitForCondition(() => feature.skipHostList == item[1].toLowerCase(), - "Skip list service initialized"); - break; - } - } - } - - await UrlClassifierTestUtils.addTestTrackers(); - }, - - _createTask(options) { - add_task(async function() { - info("Starting " + (options.cookieBehavior != BEHAVIOR_ACCEPT ? "blocking" : "non-blocking") + " cookieBehavior (" + options.cookieBehavior + ") and " + - (options.blockingByContentBlockingRTUI ? "" : "no") + " contentBlocking third-party cookies UI with" + - (options.allowList ? "" : "out") + " allow list test " + options.name + - " running in a " + (options.runInPrivateWindow ? "private" : "normal") + " window " + - " with iframe sandbox set to " + options.iframeSandbox + - " and access removal set to " + options.accessRemoval + - (typeof options.thirdPartyPage == "string" ? ( - " and third party page set to " + options.thirdPartyPage) : "")); - - is(!!options.callbackAfterRemoval, !!options.accessRemoval, - "callbackAfterRemoval must be passed when accessRemoval is non-null"); - - let win = window; - if (options.runInPrivateWindow) { - win = OpenBrowserWindow({private: true}); - await TestUtils.topicObserved("browser-delayed-startup-finished"); - } - - await AntiTracking._setupTest(win, options.cookieBehavior, - options.blockingByContentBlockingRTUI, - options.extraPrefs); - - let cookieBlocked = 0; - let listener = { - onContentBlockingEvent(webProgress, request, event) { - if ((event & options.expectedBlockingNotifications)) { - ++cookieBlocked; - } - }, - }; - win.gBrowser.addProgressListener(listener); - - info("Creating a new tab"); - let tab = BrowserTestUtils.addTab(win.gBrowser, TEST_TOP_PAGE); - win.gBrowser.selectedTab = tab; - - let browser = win.gBrowser.getBrowserForTab(tab); - await BrowserTestUtils.browserLoaded(browser); - - if (options.allowList) { - info("Disabling content blocking for this page"); - win.ContentBlocking.disableForCurrentPage(); - - // The previous function reloads the browser, so wait for it to load again! - await BrowserTestUtils.browserLoaded(browser); - } - - info("Creating a 3rd party content"); - let doAccessRemovalChecks = typeof options.accessRemoval == "string" && - options.cookieBehavior == BEHAVIOR_REJECT_TRACKER && - options.blockingByContentBlockingRTUI && - !options.allowList; - let thirdPartyPage; - if (typeof options.thirdPartyPage == "string") { - thirdPartyPage = options.thirdPartyPage; - } else { - thirdPartyPage = TEST_3RD_PARTY_PAGE; - } - await ContentTask.spawn(browser, - { page: thirdPartyPage, - nextPage: TEST_4TH_PARTY_PAGE, - callback: options.callback.toString(), - callbackAfterRemoval: options.callbackAfterRemoval ? - options.callbackAfterRemoval.toString() : null, - accessRemoval: options.accessRemoval, - iframeSandbox: options.iframeSandbox, - allowList: options.allowList, - doAccessRemovalChecks }, - async function(obj) { - let id = "id" + Math.random(); - await new content.Promise(resolve => { - let ifr = content.document.createElement("iframe"); - ifr.id = id; - ifr.onload = function() { - info("Sending code to the 3rd party content"); - let callback = obj.allowList + "!!!" + obj.callback; - ifr.contentWindow.postMessage(callback, "*"); - }; - if (typeof obj.iframeSandbox == "string") { - ifr.setAttribute("sandbox", obj.iframeSandbox); - } - - content.addEventListener("message", function msg(event) { - if (event.data.type == "finish") { - content.removeEventListener("message", msg); - resolve(); - return; - } - - if (event.data.type == "ok") { - ok(event.data.what, event.data.msg); - return; - } - - if (event.data.type == "info") { - info(event.data.msg); - return; - } - - ok(false, "Unknown message"); - }); - - content.document.body.appendChild(ifr); - ifr.src = obj.page; - }); - - if (obj.doAccessRemovalChecks) { - info(`Running after removal checks (${obj.accessRemoval})`); - switch (obj.accessRemoval) { - case "navigate-subframe": - await new content.Promise(resolve => { - let ifr = content.document.getElementById(id); - let oldWindow = ifr.contentWindow; - ifr.onload = function() { - info("Sending code to the old 3rd party content"); - oldWindow.postMessage(obj.callbackAfterRemoval, "*"); - }; - if (typeof obj.iframeSandbox == "string") { - ifr.setAttribute("sandbox", obj.iframeSandbox); - } - - content.addEventListener("message", function msg(event) { - if (event.data.type == "finish") { - content.removeEventListener("message", msg); - resolve(); - return; - } - - if (event.data.type == "ok") { - ok(event.data.what, event.data.msg); - return; - } - - if (event.data.type == "info") { - info(event.data.msg); - return; - } - - ok(false, "Unknown message"); - }); - - ifr.src = obj.nextPage; - }); - break; - default: - ok(false, "Unexpected accessRemoval code passed: " + obj.accessRemoval); - break; - } - } - }); - - if (options.allowList) { - info("Enabling content blocking for this page"); - win.ContentBlocking.enableForCurrentPage(); - - // The previous function reloads the browser, so wait for it to load again! - await BrowserTestUtils.browserLoaded(browser); - } - - win.gBrowser.removeProgressListener(listener); - - is(!!cookieBlocked, !!options.expectedBlockingNotifications, "Checking cookie blocking notifications"); - - info("Removing the tab"); - BrowserTestUtils.removeTab(tab); - - if (options.runInPrivateWindow) { - win.close(); - } - }); - }, - - _createCleanupTask(cleanupFunction) { - add_task(async function() { - info("Cleaning up."); - if (cleanupFunction) { - await cleanupFunction(); - } - }); - }, - - _createWindowOpenTask(name, blockingCallback, nonBlockingCallback, runInPrivateWindow, - iframeSandbox, extraPrefs) { - add_task(async function() { - info("Starting window-open test " + name); - - let win = window; - if (runInPrivateWindow) { - win = OpenBrowserWindow({private: true}); - await TestUtils.topicObserved("browser-delayed-startup-finished"); - } - - await AntiTracking._setupTest(win, BEHAVIOR_REJECT_TRACKER, true, extraPrefs); - - info("Creating a new tab"); - let tab = BrowserTestUtils.addTab(win.gBrowser, TEST_TOP_PAGE); - win.gBrowser.selectedTab = tab; - - let browser = win.gBrowser.getBrowserForTab(tab); - await BrowserTestUtils.browserLoaded(browser); - - let pageURL = TEST_3RD_PARTY_PAGE_WO; - if (gFeatures == "noopener") { - pageURL += "?noopener"; - } - - info("Creating a 3rd party content"); - await ContentTask.spawn(browser, - { page: pageURL, - blockingCallback: blockingCallback.toString(), - nonBlockingCallback: nonBlockingCallback.toString(), - iframeSandbox, - }, - async function(obj) { - await new content.Promise(resolve => { - let ifr = content.document.createElement("iframe"); - ifr.onload = function() { - info("Sending code to the 3rd party content"); - ifr.contentWindow.postMessage(obj, "*"); - }; - if (typeof obj.iframeSandbox == "string") { - ifr.setAttribute("sandbox", obj.iframeSandbox); - } - - content.addEventListener("message", function msg(event) { - if (event.data.type == "finish") { - content.removeEventListener("message", msg); - resolve(); - return; - } - - if (event.data.type == "ok") { - ok(event.data.what, event.data.msg); - return; - } - - if (event.data.type == "info") { - info(event.data.msg); - return; - } - - ok(false, "Unknown message"); - }); - - content.document.body.appendChild(ifr); - ifr.src = obj.page; - }); - }); - - info("Removing the tab"); - BrowserTestUtils.removeTab(tab); - - if (runInPrivateWindow) { - win.close(); - } - }); - }, - - _createUserInteractionTask(name, blockingCallback, nonBlockingCallback, - runInPrivateWindow, iframeSandbox, extraPrefs) { - add_task(async function() { - info("Starting user-interaction test " + name); - - let win = window; - if (runInPrivateWindow) { - win = OpenBrowserWindow({private: true}); - await TestUtils.topicObserved("browser-delayed-startup-finished"); - } - - await AntiTracking._setupTest(win, BEHAVIOR_REJECT_TRACKER, true, extraPrefs); - - info("Creating a new tab"); - let tab = BrowserTestUtils.addTab(win.gBrowser, TEST_TOP_PAGE); - win.gBrowser.selectedTab = tab; - - let browser = win.gBrowser.getBrowserForTab(tab); - await BrowserTestUtils.browserLoaded(browser); - - info("Creating a 3rd party content"); - await ContentTask.spawn(browser, - { page: TEST_3RD_PARTY_PAGE_UI, - popup: TEST_POPUP_PAGE, - blockingCallback: blockingCallback.toString(), - iframeSandbox, - }, - async function(obj) { - let ifr = content.document.createElement("iframe"); - let loading = new content.Promise(resolve => { ifr.onload = resolve; }); - if (typeof obj.iframeSandbox == "string") { - ifr.setAttribute("sandbox", obj.iframeSandbox); - } - content.document.body.appendChild(ifr); - ifr.src = obj.page; - await loading; - - info("The 3rd party content should not have access to first party storage."); - await new content.Promise(resolve => { - content.addEventListener("message", function msg(event) { - if (event.data.type == "finish") { - content.removeEventListener("message", msg); - resolve(); - return; - } - - if (event.data.type == "ok") { - ok(event.data.what, event.data.msg); - return; - } - - if (event.data.type == "info") { - info(event.data.msg); - return; - } - - ok(false, "Unknown message"); - }); - ifr.contentWindow.postMessage({ callback: obj.blockingCallback }, "*"); - }); - - let windowClosed = new content.Promise(resolve => { - Services.ww.registerNotification(function notification(aSubject, aTopic, aData) { - if (aTopic == "domwindowclosed") { - Services.ww.unregisterNotification(notification); - resolve(); - } - }); - }); - - info("Opening a window from the iframe."); - ifr.contentWindow.open(obj.popup); - - info("Let's wait for the window to be closed"); - await windowClosed; - - info("First time, the 3rd party content should not have access to first party storage " + - "because the tracker did not have user interaction"); - await new content.Promise(resolve => { - content.addEventListener("message", function msg(event) { - if (event.data.type == "finish") { - content.removeEventListener("message", msg); - resolve(); - return; - } - - if (event.data.type == "ok") { - ok(event.data.what, event.data.msg); - return; - } - - if (event.data.type == "info") { - info(event.data.msg); - return; - } - - ok(false, "Unknown message"); - }); - ifr.contentWindow.postMessage({ callback: obj.blockingCallback }, "*"); - }); - }); - - await AntiTracking.interactWithTracker(); - - await ContentTask.spawn(browser, - { page: TEST_3RD_PARTY_PAGE_UI, - popup: TEST_POPUP_PAGE, - nonBlockingCallback: nonBlockingCallback.toString(), - iframeSandbox, - }, - async function(obj) { - let ifr = content.document.createElement("iframe"); - let loading = new content.Promise(resolve => { ifr.onload = resolve; }); - if (typeof obj.iframeSandbox == "string") { - ifr.setAttribute("sandbox", obj.iframeSandbox); - } - content.document.body.appendChild(ifr); - ifr.src = obj.page; - await loading; - - let windowClosed = new content.Promise(resolve => { - Services.ww.registerNotification(function notification(aSubject, aTopic, aData) { - if (aTopic == "domwindowclosed") { - Services.ww.unregisterNotification(notification); - resolve(); - } - }); - }); - - info("Opening a window from the iframe."); - ifr.contentWindow.open(obj.popup); - - info("Let's wait for the window to be closed"); - await windowClosed; - - info("The 3rd party content should now have access to first party storage."); - await new content.Promise(resolve => { - content.addEventListener("message", function msg(event) { - if (event.data.type == "finish") { - content.removeEventListener("message", msg); - resolve(); - return; - } - - if (event.data.type == "ok") { - ok(event.data.what, event.data.msg); - return; - } - - if (event.data.type == "info") { - info(event.data.msg); - return; - } - - ok(false, "Unknown message"); - }); - ifr.contentWindow.postMessage({ callback: obj.nonBlockingCallback }, "*"); - }); - }); - - info("Removing the tab"); - BrowserTestUtils.removeTab(tab); - - if (runInPrivateWindow) { - win.close(); - } - }); - }, -}; - diff --git a/toolkit/components/antitracking/test/browser/browser.ini b/toolkit/components/antitracking/test/browser/browser.ini index 9442ccac946e..220e36b6d399 100644 --- a/toolkit/components/antitracking/test/browser/browser.ini +++ b/toolkit/components/antitracking/test/browser/browser.ini @@ -9,8 +9,6 @@ support-files = container.html embedder.html head.js - antitracking_head.js - storageprincipal_head.js image.sjs imageCacheWorker.js page.html @@ -25,8 +23,6 @@ support-files = popup.html server.sjs storageAccessAPIHelpers.js - 3rdPartyStorage.html - 3rdPartyStorageWO.html !/browser/modules/test/browser/head.js [browser_allowListNotifications.js] @@ -92,12 +88,3 @@ support-files = localStorageEvents.html [browser_workerPropagation.js] support-files = workerIframe.html [browser_cookieBetweenTabs.js] -[browser_partitionedMessaging.js] -[browser_partitionedIndexedDB.js] -[browser_partitionedCookies.js] -support-files = cookies.sjs -[browser_partitionedDOMCache.js] -[browser_partitionedServiceWorkers.js] -support-files = matchAll.js -[browser_partitionedSharedWorkers.js] -support-files = sharedWorker.js diff --git a/toolkit/components/antitracking/test/browser/browser_allowListSeparationInPrivateAndNormalWindows.js b/toolkit/components/antitracking/test/browser/browser_allowListSeparationInPrivateAndNormalWindows.js index a6228fe58050..ccc2beb09c13 100644 --- a/toolkit/components/antitracking/test/browser/browser_allowListSeparationInPrivateAndNormalWindows.js +++ b/toolkit/components/antitracking/test/browser/browser_allowListSeparationInPrivateAndNormalWindows.js @@ -10,9 +10,6 @@ // private windows wouldn't send any blocking notifications as they don't have // storage access in the first place. -/* import-globals-from antitracking_head.js */ - -"use strict"; add_task(async _ => { let uri = Services.io.newURI("https://example.net"); Services.perms.add(uri, "trackingprotection-pb", diff --git a/toolkit/components/antitracking/test/browser/browser_allowPermissionForTracker.js b/toolkit/components/antitracking/test/browser/browser_allowPermissionForTracker.js index 3bab531991f5..ac89bdadde0b 100644 --- a/toolkit/components/antitracking/test/browser/browser_allowPermissionForTracker.js +++ b/toolkit/components/antitracking/test/browser/browser_allowPermissionForTracker.js @@ -1,8 +1,6 @@ // This test works by setting up an exception for the tracker domain, which // disables all the anti-tracking tests. -/* import-globals-from antitracking_head.js */ - add_task(async _ => { Services.perms.add(Services.io.newURI("https://tracking.example.org"), "cookie", Services.perms.ALLOW_ACTION); diff --git a/toolkit/components/antitracking/test/browser/browser_blockingCookies.js b/toolkit/components/antitracking/test/browser/browser_blockingCookies.js index 4c7419eecaa1..4448510b8e00 100644 --- a/toolkit/components/antitracking/test/browser/browser_blockingCookies.js +++ b/toolkit/components/antitracking/test/browser/browser_blockingCookies.js @@ -1,5 +1,3 @@ -/* import-globals-from antitracking_head.js */ - AntiTracking.runTest("Set/Get Cookies", // Blocking callback async _ => { diff --git a/toolkit/components/antitracking/test/browser/browser_blockingDOMCache.js b/toolkit/components/antitracking/test/browser/browser_blockingDOMCache.js index 72472826e0ad..028b1f95c317 100644 --- a/toolkit/components/antitracking/test/browser/browser_blockingDOMCache.js +++ b/toolkit/components/antitracking/test/browser/browser_blockingDOMCache.js @@ -1,5 +1,3 @@ -/* import-globals-from antitracking_head.js */ - requestLongerTimeout(2); AntiTracking.runTest("DOM Cache", diff --git a/toolkit/components/antitracking/test/browser/browser_blockingIndexedDb.js b/toolkit/components/antitracking/test/browser/browser_blockingIndexedDb.js index 14a02f05591b..35dd4f75084a 100644 --- a/toolkit/components/antitracking/test/browser/browser_blockingIndexedDb.js +++ b/toolkit/components/antitracking/test/browser/browser_blockingIndexedDb.js @@ -1,5 +1,3 @@ -/* import-globals-from antitracking_head.js */ - AntiTracking.runTest("IndexedDB", // blocking callback async _ => { diff --git a/toolkit/components/antitracking/test/browser/browser_blockingIndexedDbInWorkers.js b/toolkit/components/antitracking/test/browser/browser_blockingIndexedDbInWorkers.js index 3e020f02ef21..077de91b4e5b 100644 --- a/toolkit/components/antitracking/test/browser/browser_blockingIndexedDbInWorkers.js +++ b/toolkit/components/antitracking/test/browser/browser_blockingIndexedDbInWorkers.js @@ -1,5 +1,3 @@ -/* import-globals-from antitracking_head.js */ - AntiTracking.runTest("IndexedDB in workers", async _ => { function blockCode() { diff --git a/toolkit/components/antitracking/test/browser/browser_blockingLocalStorage.js b/toolkit/components/antitracking/test/browser/browser_blockingLocalStorage.js index 42fcb29285c0..ad39aec3c033 100644 --- a/toolkit/components/antitracking/test/browser/browser_blockingLocalStorage.js +++ b/toolkit/components/antitracking/test/browser/browser_blockingLocalStorage.js @@ -1,5 +1,3 @@ -/* import-globals-from antitracking_head.js */ - AntiTracking.runTest("localStorage", async _ => { is(window.localStorage, null, "LocalStorage is null"); diff --git a/toolkit/components/antitracking/test/browser/browser_blockingMessaging.js b/toolkit/components/antitracking/test/browser/browser_blockingMessaging.js index 5069e44186bc..439b508b3086 100644 --- a/toolkit/components/antitracking/test/browser/browser_blockingMessaging.js +++ b/toolkit/components/antitracking/test/browser/browser_blockingMessaging.js @@ -1,5 +1,3 @@ -/* import-globals-from antitracking_head.js */ - AntiTracking.runTest("BroadcastChannel", async _ => { try { diff --git a/toolkit/components/antitracking/test/browser/browser_blockingNoOpener.js b/toolkit/components/antitracking/test/browser/browser_blockingNoOpener.js index 1f96fd32f862..2f5e23570fcf 100644 --- a/toolkit/components/antitracking/test/browser/browser_blockingNoOpener.js +++ b/toolkit/components/antitracking/test/browser/browser_blockingNoOpener.js @@ -1,5 +1,3 @@ -/* import-globals-from antitracking_head.js */ - gFeatures = "noopener"; AntiTracking.runTest("Blocking in the case of noopener windows", diff --git a/toolkit/components/antitracking/test/browser/browser_blockingServiceWorkers.js b/toolkit/components/antitracking/test/browser/browser_blockingServiceWorkers.js index fad1501667e0..90a6362b7ed7 100644 --- a/toolkit/components/antitracking/test/browser/browser_blockingServiceWorkers.js +++ b/toolkit/components/antitracking/test/browser/browser_blockingServiceWorkers.js @@ -1,5 +1,3 @@ -/* import-globals-from antitracking_head.js */ - AntiTracking.runTest("ServiceWorkers", async _ => { await navigator.serviceWorker.register("empty.js").then( diff --git a/toolkit/components/antitracking/test/browser/browser_blockingServiceWorkersStorageAccessAPI.js b/toolkit/components/antitracking/test/browser/browser_blockingServiceWorkersStorageAccessAPI.js index 385e885e792f..3e91ecbfa588 100644 --- a/toolkit/components/antitracking/test/browser/browser_blockingServiceWorkersStorageAccessAPI.js +++ b/toolkit/components/antitracking/test/browser/browser_blockingServiceWorkersStorageAccessAPI.js @@ -1,5 +1,3 @@ -/* import-globals-from antitracking_head.js */ - requestLongerTimeout(2); AntiTracking.runTest("ServiceWorkers and Storage Access API", diff --git a/toolkit/components/antitracking/test/browser/browser_blockingSessionStorage.js b/toolkit/components/antitracking/test/browser/browser_blockingSessionStorage.js index 5e3baac06f58..d7e4ae9d17b6 100644 --- a/toolkit/components/antitracking/test/browser/browser_blockingSessionStorage.js +++ b/toolkit/components/antitracking/test/browser/browser_blockingSessionStorage.js @@ -1,5 +1,3 @@ -/* import-globals-from antitracking_head.js */ - AntiTracking.runTest("sessionStorage", async _ => { let shouldThrow = SpecialPowers.Services.prefs.getIntPref("network.cookie.cookieBehavior") == SpecialPowers.Ci.nsICookieService.BEHAVIOR_REJECT; diff --git a/toolkit/components/antitracking/test/browser/browser_blockingSharedWorkers.js b/toolkit/components/antitracking/test/browser/browser_blockingSharedWorkers.js index ed28a9aad555..44e73d2632ec 100644 --- a/toolkit/components/antitracking/test/browser/browser_blockingSharedWorkers.js +++ b/toolkit/components/antitracking/test/browser/browser_blockingSharedWorkers.js @@ -1,5 +1,3 @@ -/* import-globals-from antitracking_head.js */ - requestLongerTimeout(2); AntiTracking.runTest("SharedWorkers", diff --git a/toolkit/components/antitracking/test/browser/browser_denyPermissionForTracker.js b/toolkit/components/antitracking/test/browser/browser_denyPermissionForTracker.js index ec7892fd1b1c..9c76c8359a41 100644 --- a/toolkit/components/antitracking/test/browser/browser_denyPermissionForTracker.js +++ b/toolkit/components/antitracking/test/browser/browser_denyPermissionForTracker.js @@ -1,8 +1,6 @@ // This test works by setting up an exception for the tracker domain, which // disables all the anti-tracking tests. -/* import-globals-from antitracking_head.js */ - add_task(async _ => { Services.perms.add(Services.io.newURI("https://tracking.example.org"), "cookie", Services.perms.DENY_ACTION); diff --git a/toolkit/components/antitracking/test/browser/browser_partitionedCookies.js b/toolkit/components/antitracking/test/browser/browser_partitionedCookies.js deleted file mode 100644 index 0eaf3e1a85ae..000000000000 --- a/toolkit/components/antitracking/test/browser/browser_partitionedCookies.js +++ /dev/null @@ -1,49 +0,0 @@ -/* import-globals-from storageprincipal_head.js */ - -StoragePrincipalHelper.runTest("HTTP Cookies", - async (win3rdParty, win1stParty, allowed) => { - await win3rdParty.fetch("cookies.sjs?3rd").then(r => r.text()); - await win3rdParty.fetch("cookies.sjs").then(r => r.text()).then(text => { - is(text, "cookie:foopy=3rd", "3rd party cookie set"); - }); - - await win1stParty.fetch("cookies.sjs?first").then(r => r.text()); - await win1stParty.fetch("cookies.sjs").then(r => r.text()).then(text => { - is(text, "cookie:foopy=first", "First party cookie set"); - }); - - await win3rdParty.fetch("cookies.sjs").then(r => r.text()).then(text => { - if (allowed) { - is(text, "cookie:foopy=first", "3rd party has the first party cookie set"); - } else { - is(text, "cookie:foopy=3rd", "3rd party has not the first party cookie set"); - } - }); - }, - - async _ => { - await new Promise(resolve => { - Services.clearData.deleteData(Ci.nsIClearDataService.CLEAR_ALL, value => resolve()); - }); - }); - -StoragePrincipalHelper.runTest("DOM Cookies", - async (win3rdParty, win1stParty, allowed) => { - win3rdParty.document.cookie = "foo=3rd"; - is(win3rdParty.document.cookie, "foo=3rd", "3rd party cookie set"); - - win1stParty.document.cookie = "foo=first"; - is(win1stParty.document.cookie, "foo=first", "First party cookie set"); - - if (allowed) { - is(win3rdParty.document.cookie, "foo=first", "3rd party has the first party cookie set"); - } else { - is(win3rdParty.document.cookie, "foo=3rd", "3rd party has not the first party cookie set"); - } - }, - - async _ => { - await new Promise(resolve => { - Services.clearData.deleteData(Ci.nsIClearDataService.CLEAR_ALL, value => resolve()); - }); - }); diff --git a/toolkit/components/antitracking/test/browser/browser_partitionedDOMCache.js b/toolkit/components/antitracking/test/browser/browser_partitionedDOMCache.js deleted file mode 100644 index e4bf7cfc1279..000000000000 --- a/toolkit/components/antitracking/test/browser/browser_partitionedDOMCache.js +++ /dev/null @@ -1,21 +0,0 @@ -/* import-globals-from storageprincipal_head.js */ - -StoragePrincipalHelper.runTest("DOMCache", - async (win3rdParty, win1stParty, allowed) => { - // DOM Cache is not supported. Always blocked. - await win3rdParty.caches.open("wow").then( - _ => { ok(allowed, "DOM Cache cannot be used!"); }, - _ => { ok(!allowed, "DOM Cache cannot be used!"); } - ); - - await win1stParty.caches.open("wow").then( - _ => { ok(true, "DOM Cache shoulw be available"); }, - _ => { ok(false, "DOM Cache shoulw be available"); }, - ); - }, - - async _ => { - await new Promise(resolve => { - Services.clearData.deleteData(Ci.nsIClearDataService.CLEAR_ALL, value => resolve()); - }); - }); diff --git a/toolkit/components/antitracking/test/browser/browser_partitionedIndexedDB.js b/toolkit/components/antitracking/test/browser/browser_partitionedIndexedDB.js deleted file mode 100644 index 014b84b0117c..000000000000 --- a/toolkit/components/antitracking/test/browser/browser_partitionedIndexedDB.js +++ /dev/null @@ -1,46 +0,0 @@ -/* import-globals-from storageprincipal_head.js */ - -StoragePrincipalHelper.runTest("IndexedDB", - async (win3rdParty, win1stParty, allowed) => { - await new Promise(resolve => { - let a = win1stParty.indexedDB.open("test", 1); - ok(!!a, "IDB should not be blocked in 1st party contexts"); - - a.onsuccess = e => { - let db = e.target.result; - is(db.objectStoreNames.length, 1, "We have 1 objectStore"); - is(db.objectStoreNames[0], "foobar", "We have 'foobar' objectStore"); - resolve(); - }; - - a.onupgradeneeded = e => { - let db = e.target.result; - is(db.objectStoreNames.length, 0, "We have 0 objectStores"); - db.createObjectStore("foobar", { keyPath: "test" }); - }; - }); - - await new Promise(resolve => { - let a = win3rdParty.indexedDB.open("test", 1); - ok(!!a, "IDB should not be blocked in 3rd party contexts"); - - a.onsuccess = e => { - let db = e.target.result; - - if (allowed) { - is(db.objectStoreNames.length, 1, "We have 1 objectStore"); - is(db.objectStoreNames[0], "foobar", "We have 'foobar' objectStore"); - } else { - is(db.objectStoreNames.length, 0, "We have 0 objectStore"); - } - resolve(); - }; - }); - }, - - async _ => { - await new Promise(resolve => { - Services.clearData.deleteData(Ci.nsIClearDataService.CLEAR_ALL, value => resolve()); - }); - }); - diff --git a/toolkit/components/antitracking/test/browser/browser_partitionedLocalStorage.js b/toolkit/components/antitracking/test/browser/browser_partitionedLocalStorage.js index 62b9ef39e8c0..86e1e71a4618 100644 --- a/toolkit/components/antitracking/test/browser/browser_partitionedLocalStorage.js +++ b/toolkit/components/antitracking/test/browser/browser_partitionedLocalStorage.js @@ -1,5 +1,3 @@ -/* import-globals-from antitracking_head.js */ - AntiTracking.runTest("localStorage and Storage Access API", async _ => { /* import-globals-from storageAccessAPIHelpers.js */ diff --git a/toolkit/components/antitracking/test/browser/browser_partitionedMessaging.js b/toolkit/components/antitracking/test/browser/browser_partitionedMessaging.js deleted file mode 100644 index 09c12b8867d2..000000000000 --- a/toolkit/components/antitracking/test/browser/browser_partitionedMessaging.js +++ /dev/null @@ -1,18 +0,0 @@ -/* import-globals-from storageprincipal_head.js */ - -StoragePrincipalHelper.runTest("BroadcastChannel", - async (win3rdParty, win1stParty, allowed) => { - let a = new win3rdParty.BroadcastChannel("hello"); - ok(!!a, "BroadcastChannel should be created by 3rd party iframe"); - - let b = new win1stParty.BroadcastChannel("hello"); - ok(!!b, "BroadcastChannel should be created by 1st party iframe"); - - // BroadcastChannel uses the incument global, this means that its CTOR will - // always use the 3rd party iframe's window as global. - }, - async _ => { - await new Promise(resolve => { - Services.clearData.deleteData(Ci.nsIClearDataService.CLEAR_ALL, value => resolve()); - }); - }); diff --git a/toolkit/components/antitracking/test/browser/browser_partitionedServiceWorkers.js b/toolkit/components/antitracking/test/browser/browser_partitionedServiceWorkers.js deleted file mode 100644 index 29a867c8e295..000000000000 --- a/toolkit/components/antitracking/test/browser/browser_partitionedServiceWorkers.js +++ /dev/null @@ -1,65 +0,0 @@ -/* import-globals-from storageprincipal_head.js */ - -StoragePrincipalHelper.runTest("ServiceWorkers", - async (win3rdParty, win1stParty, allowed) => { - // ServiceWorkers are not supported. Always blocked. - await win3rdParty.navigator.serviceWorker.register("empty.js").then( - _ => { ok(allowed, "Success: ServiceWorker cannot be used!"); }, - _ => { ok(!allowed, "Failed: ServiceWorker cannot be used!"); }); - - await win1stParty.navigator.serviceWorker.register("empty.js").then( - _ => { ok(true, "Success: ServiceWorker should be available!"); }, - _ => { ok(false, "Failed: ServiceWorker should be available!"); }); - }, - - async _ => { - await new Promise(resolve => { - Services.clearData.deleteData(Ci.nsIClearDataService.CLEAR_ALL, value => resolve()); - }); - }, - - [["dom.serviceWorkers.exemptFromPerDomainMax", true], - ["dom.ipc.processCount", 1], - ["dom.serviceWorkers.enabled", true], - ["dom.serviceWorkers.testing.enabled", true]]); - -StoragePrincipalHelper.runTest("ServiceWorkers - MatchAll", - async (win3rdParty, win1stParty, allowed) => { - if (!win1stParty.sw) { - let reg = await win1stParty.navigator.serviceWorker.register("matchAll.js"); - if (reg.installing.state !== "activated") { - await new Promise(resolve => { - let w = reg.installing; - w.addEventListener("statechange", function onStateChange() { - if (w.state === "activated") { - w.removeEventListener("statechange", onStateChange); - win1stParty.sw = reg.active; - resolve(); - } - }); - }); - } - } - - let msgPromise = new Promise(resolve => { - win1stParty.navigator.serviceWorker.addEventListener("message", msg => { - resolve(msg.data); - }); - }); - - win1stParty.sw.postMessage(win3rdParty.location.href); - let msg = await msgPromise; - - is(allowed, msg, "We want to have the 3rd party window controlled."); - }, - - async _ => { - await new Promise(resolve => { - Services.clearData.deleteData(Ci.nsIClearDataService.CLEAR_ALL, value => resolve()); - }); - }, - - [["dom.serviceWorkers.exemptFromPerDomainMax", true], - ["dom.ipc.processCount", 1], - ["dom.serviceWorkers.enabled", true], - ["dom.serviceWorkers.testing.enabled", true]]); diff --git a/toolkit/components/antitracking/test/browser/browser_partitionedSharedWorkers.js b/toolkit/components/antitracking/test/browser/browser_partitionedSharedWorkers.js deleted file mode 100644 index c8ac37831338..000000000000 --- a/toolkit/components/antitracking/test/browser/browser_partitionedSharedWorkers.js +++ /dev/null @@ -1,36 +0,0 @@ -/* import-globals-from storageprincipal_head.js */ - -StoragePrincipalHelper.runTest("SharedWorkers", - async (win3rdParty, win1stParty, allowed) => { - let sh1 = new win1stParty.SharedWorker("sharedWorker.js"); - await new Promise(resolve => { - sh1.port.onmessage = e => { - is(e.data, 1, "We expected 1 connection"); - resolve(); - }; - sh1.port.postMessage("count"); - }); - - let sh3 = new win3rdParty.SharedWorker("sharedWorker.js"); - await new Promise(resolve => { - sh3.port.onmessage = e => { - ok(!allowed, "We should be here only if the SharedWorker is partitioned"); - is(e.data, 1, "We expected 1 connection for 3rd party SharedWorker"); - resolve(); - }; - sh3.onerror = _ => { - ok(allowed, "We should be here only if the SharedWorker is not partitioned"); - resolve(); - }; - sh3.port.postMessage("count"); - }); - - sh1.port.postMessage("close"); - sh3.port.postMessage("close"); - }, - - async _ => { - await new Promise(resolve => { - Services.clearData.deleteData(Ci.nsIClearDataService.CLEAR_ALL, value => resolve()); - }); - }); diff --git a/toolkit/components/antitracking/test/browser/browser_permissionInNormalWindows.js b/toolkit/components/antitracking/test/browser/browser_permissionInNormalWindows.js index 00194776c091..fd984094b818 100644 --- a/toolkit/components/antitracking/test/browser/browser_permissionInNormalWindows.js +++ b/toolkit/components/antitracking/test/browser/browser_permissionInNormalWindows.js @@ -1,5 +1,3 @@ -/* import-globals-from antitracking_head.js */ - AntiTracking.runTest("Test whether we receive any persistent permissions in normal windows", // Blocking callback async _ => { diff --git a/toolkit/components/antitracking/test/browser/browser_permissionInPrivateWindows.js b/toolkit/components/antitracking/test/browser/browser_permissionInPrivateWindows.js index 1837065bd072..952d8f5643a4 100644 --- a/toolkit/components/antitracking/test/browser/browser_permissionInPrivateWindows.js +++ b/toolkit/components/antitracking/test/browser/browser_permissionInPrivateWindows.js @@ -1,5 +1,3 @@ -/* import-globals-from antitracking_head.js */ - AntiTracking.runTest("Test whether we receive any persistent permissions in private windows", // Blocking callback async _ => { diff --git a/toolkit/components/antitracking/test/browser/browser_script.js b/toolkit/components/antitracking/test/browser/browser_script.js index b967de519cd7..50ee765c4727 100644 --- a/toolkit/components/antitracking/test/browser/browser_script.js +++ b/toolkit/components/antitracking/test/browser/browser_script.js @@ -1,5 +1,3 @@ -/* import-globals-from antitracking_head.js */ - add_task(async function() { info("Starting subResources test"); diff --git a/toolkit/components/antitracking/test/browser/browser_siteSpecificWorkArounds.js b/toolkit/components/antitracking/test/browser/browser_siteSpecificWorkArounds.js index b38656d963da..e4e676d3c350 100644 --- a/toolkit/components/antitracking/test/browser/browser_siteSpecificWorkArounds.js +++ b/toolkit/components/antitracking/test/browser/browser_siteSpecificWorkArounds.js @@ -1,5 +1,3 @@ -/* import-globals-from antitracking_head.js */ - AntiTracking.runTest("localStorage with a tracker that is whitelisted via a pref", async _ => { let shouldThrow = SpecialPowers.Services.prefs.getIntPref("network.cookie.cookieBehavior") == SpecialPowers.Ci.nsICookieService.BEHAVIOR_REJECT; diff --git a/toolkit/components/antitracking/test/browser/browser_storageAccessPrivateWindow.js b/toolkit/components/antitracking/test/browser/browser_storageAccessPrivateWindow.js index f5cd7a3451a1..8a752ebff5e1 100644 --- a/toolkit/components/antitracking/test/browser/browser_storageAccessPrivateWindow.js +++ b/toolkit/components/antitracking/test/browser/browser_storageAccessPrivateWindow.js @@ -1,5 +1,3 @@ -/* import-globals-from antitracking_head.js */ - AntiTracking.runTest("Storage Access API called in a private window", // blocking callback async _ => { diff --git a/toolkit/components/antitracking/test/browser/browser_storageAccessPromiseRejectHandlerUserInteraction.js b/toolkit/components/antitracking/test/browser/browser_storageAccessPromiseRejectHandlerUserInteraction.js index e70f6dee9ff7..5c046a27abe8 100644 --- a/toolkit/components/antitracking/test/browser/browser_storageAccessPromiseRejectHandlerUserInteraction.js +++ b/toolkit/components/antitracking/test/browser/browser_storageAccessPromiseRejectHandlerUserInteraction.js @@ -1,5 +1,3 @@ -/* import-globals-from antitracking_head.js */ - AntiTracking.runTest("Storage Access API returns promises that maintain user activation for calling its reject handler", // blocking callback async _ => { diff --git a/toolkit/components/antitracking/test/browser/browser_storageAccessPromiseResolveHandlerUserInteraction.js b/toolkit/components/antitracking/test/browser/browser_storageAccessPromiseResolveHandlerUserInteraction.js index 3c3d3819999b..7f691e3eed79 100644 --- a/toolkit/components/antitracking/test/browser/browser_storageAccessPromiseResolveHandlerUserInteraction.js +++ b/toolkit/components/antitracking/test/browser/browser_storageAccessPromiseResolveHandlerUserInteraction.js @@ -1,5 +1,3 @@ -/* import-globals-from antitracking_head.js */ - AntiTracking.runTest("Storage Access API returns promises that maintain user activation", // blocking callback async _ => { diff --git a/toolkit/components/antitracking/test/browser/browser_storageAccessRemovalNavigateSubframe.js b/toolkit/components/antitracking/test/browser/browser_storageAccessRemovalNavigateSubframe.js index 171e5d97f5fc..173fa1815d28 100644 --- a/toolkit/components/antitracking/test/browser/browser_storageAccessRemovalNavigateSubframe.js +++ b/toolkit/components/antitracking/test/browser/browser_storageAccessRemovalNavigateSubframe.js @@ -1,5 +1,3 @@ -/* import-globals-from antitracking_head.js */ - AntiTracking.runTest("Storage Access is removed when subframe navigates", // blocking callback async _ => { diff --git a/toolkit/components/antitracking/test/browser/browser_storageAccessSandboxed.js b/toolkit/components/antitracking/test/browser/browser_storageAccessSandboxed.js index f19735279c8f..87c018b49bb8 100644 --- a/toolkit/components/antitracking/test/browser/browser_storageAccessSandboxed.js +++ b/toolkit/components/antitracking/test/browser/browser_storageAccessSandboxed.js @@ -1,5 +1,3 @@ -/* import-globals-from antitracking_head.js */ - let counter = 0; AntiTracking.runTest("Storage Access API called in a sandboxed iframe", diff --git a/toolkit/components/antitracking/test/browser/browser_storageAccessWithHeuristics.js b/toolkit/components/antitracking/test/browser/browser_storageAccessWithHeuristics.js index 320d27175a7e..8317d7c4a0c0 100644 --- a/toolkit/components/antitracking/test/browser/browser_storageAccessWithHeuristics.js +++ b/toolkit/components/antitracking/test/browser/browser_storageAccessWithHeuristics.js @@ -1,5 +1,3 @@ -/* import-globals-from antitracking_head.js */ - add_task(async function() { info("Starting subResources test"); diff --git a/toolkit/components/antitracking/test/browser/cookies.sjs b/toolkit/components/antitracking/test/browser/cookies.sjs deleted file mode 100644 index 1267a69d8c4e..000000000000 --- a/toolkit/components/antitracking/test/browser/cookies.sjs +++ /dev/null @@ -1,12 +0,0 @@ -function handleRequest(aRequest, aResponse) { - aResponse.setStatusLine(aRequest.httpVersion, 200); - let cookie = ""; - if (aRequest.hasHeader("Cookie")) { - cookie = aRequest.getHeader("Cookie"); - } - aResponse.write("cookie:" + cookie); - - if (aRequest.queryString) { - aResponse.setHeader("Set-Cookie", "foopy=" + aRequest.queryString); - } -} diff --git a/toolkit/components/antitracking/test/browser/head.js b/toolkit/components/antitracking/test/browser/head.js index 72ca78dea411..ccacccba0031 100644 --- a/toolkit/components/antitracking/test/browser/head.js +++ b/toolkit/components/antitracking/test/browser/head.js @@ -1,10 +1,3 @@ -/* vim: set ts=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/. */ - -"use strict"; - const TEST_DOMAIN = "http://example.net/"; const TEST_DOMAIN_2 = "http://xn--exmple-cua.test/"; const TEST_DOMAIN_3 = "https://xn--hxajbheg2az3al.xn--jxalpdlp/"; @@ -32,7 +25,6 @@ const TEST_3RD_PARTY_PAGE_UI = TEST_3RD_PARTY_DOMAIN + TEST_PATH + "3rdPartyUI.h const TEST_3RD_PARTY_PAGE_WITH_SVG = TEST_3RD_PARTY_DOMAIN + TEST_PATH + "3rdPartySVG.html"; const TEST_4TH_PARTY_PAGE = TEST_4TH_PARTY_DOMAIN + TEST_PATH + "3rdParty.html"; const TEST_ANOTHER_3RD_PARTY_PAGE = TEST_ANOTHER_3RD_PARTY_DOMAIN + TEST_PATH + "3rdParty.html"; -const TEST_3RD_PARTY_STORAGE_PAGE = TEST_3RD_PARTY_DOMAIN + TEST_PATH + "3rdPartyStorage.html"; const BEHAVIOR_ACCEPT = Ci.nsICookieService.BEHAVIOR_ACCEPT; const BEHAVIOR_REJECT = Ci.nsICookieService.BEHAVIOR_REJECT; @@ -40,14 +32,704 @@ const BEHAVIOR_LIMIT_FOREIGN = Ci.nsICookieService.BEHAVIOR_LIMIT_FOREIGN; const BEHAVIOR_REJECT_FOREIGN = Ci.nsICookieService.BEHAVIOR_REJECT_FOREIGN; const BEHAVIOR_REJECT_TRACKER = Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER; +var gFeatures = undefined; + +let {UrlClassifierTestUtils} = ChromeUtils.import("resource://testing-common/UrlClassifierTestUtils.jsm"); + requestLongerTimeout(3); -const {UrlClassifierTestUtils} = ChromeUtils.import("resource://testing-common/UrlClassifierTestUtils.jsm"); +this.AntiTracking = { + runTest(name, callbackTracking, callbackNonTracking, cleanupFunction, extraPrefs, + windowOpenTest = true, userInteractionTest = true, + expectedBlockingNotifications = Ci.nsIWebProgressListener.STATE_COOKIES_BLOCKED_TRACKER, + runInPrivateWindow = false, iframeSandbox = null, accessRemoval = null, + callbackAfterRemoval = null) { + // Here we want to test that a 3rd party context is simply blocked. + this._createTask({ + name, + cookieBehavior: BEHAVIOR_REJECT_TRACKER, + blockingByContentBlockingRTUI: true, + allowList: false, + callback: callbackTracking, + extraPrefs, + expectedBlockingNotifications, + runInPrivateWindow, + iframeSandbox, + accessRemoval, + callbackAfterRemoval, + }); + this._createCleanupTask(cleanupFunction); -Services.scriptloader.loadSubScript( - "chrome://mochitests/content/browser/toolkit/components/antitracking/test/browser/antitracking_head.js", - this); + this._createTask({ + name, + cookieBehavior: BEHAVIOR_REJECT_TRACKER, + blockingByContentBlockingRTUI: false, + allowList: true, + callback: callbackTracking, + extraPrefs, + expectedBlockingNotifications, + runInPrivateWindow, + iframeSandbox, + accessRemoval, + callbackAfterRemoval, + }); + this._createCleanupTask(cleanupFunction); -Services.scriptloader.loadSubScript( - "chrome://mochitests/content/browser/toolkit/components/antitracking/test/browser/storageprincipal_head.js", - this); + if (callbackNonTracking) { + let runExtraTests = true; + let options = {}; + if (typeof callbackNonTracking == "object") { + options.callback = callbackNonTracking.callback; + runExtraTests = callbackNonTracking.runExtraTests; + if ("cookieBehavior" in callbackNonTracking) { + options.cookieBehavior = callbackNonTracking.cookieBehavior; + } else { + options.cookieBehavior = BEHAVIOR_ACCEPT; + } + if ("blockingByContentBlockingRTUI" in callbackNonTracking) { + options.blockingByContentBlockingRTUI = + callbackNonTracking.blockingByContentBlockingRTUI; + } else { + options.blockingByContentBlockingRTUI = false; + } + if ("blockingByAllowList" in callbackNonTracking) { + options.blockingByAllowList = + callbackNonTracking.blockingByAllowList; + } else { + options.blockingByAllowList = false; + } + callbackNonTracking = options.callback; + options.accessRemoval = null; + options.callbackAfterRemoval = null; + } + + // Phase 1: Here we want to test that a 3rd party context is not blocked if pref is off. + if (runExtraTests) { + // There are five ways in which the third-party context may not be blocked: + // * If the cookieBehavior pref causes it to not be blocked. + // * If the contentBlocking pref causes it to not be blocked. + // * If both of these prefs cause it to not be blocked. + // * If the top-level page is on the content blocking allow list. + // * If the contentBlocking third-party cookies UI pref is off, the allow list will be ignored. + // All of these cases are tested here. + this._createTask({ + name, + cookieBehavior: BEHAVIOR_ACCEPT, + blockingByContentBlockingRTUI: true, + allowList: false, + callback: callbackNonTracking, + extraPrefs, + expectedBlockingNotifications: 0, + runInPrivateWindow, + iframeSandbox, + accessRemoval: null, // only passed with non-blocking callback + callbackAfterRemoval: null, + }); + this._createCleanupTask(cleanupFunction); + + this._createTask({ + name, + cookieBehavior: BEHAVIOR_ACCEPT, + blockingByContentBlockingRTUI: false, + allowList: true, + callback: callbackNonTracking, + extraPrefs, + expectedBlockingNotifications: 0, + runInPrivateWindow, + iframeSandbox, + accessRemoval: null, // only passed with non-blocking callback + callbackAfterRemoval: null, + }); + this._createCleanupTask(cleanupFunction); + + this._createTask({ + name, + cookieBehavior: BEHAVIOR_ACCEPT, + blockingByContentBlockingRTUI: false, + allowList: false, + callback: callbackNonTracking, + extraPrefs, + expectedBlockingNotifications: 0, + runInPrivateWindow, + iframeSandbox, + accessRemoval: null, // only passed with non-blocking callback + callbackAfterRemoval: null, + }); + this._createCleanupTask(cleanupFunction); + + this._createTask({ + name, + cookieBehavior: BEHAVIOR_REJECT, + blockingByContentBlockingRTUI: true, + allowList: false, + callback: callbackTracking, + extraPrefs, + expectedBlockingNotifications: 0, + runInPrivateWindow, + iframeSandbox, + accessRemoval: null, // only passed with non-blocking callback + callbackAfterRemoval: null, + }); + this._createCleanupTask(cleanupFunction); + + this._createTask({ + name, + cookieBehavior: BEHAVIOR_LIMIT_FOREIGN, + blockingByContentBlockingRTUI: true, + allowList: true, + callback: callbackNonTracking, + extraPrefs, + expectedBlockingNotifications: 0, + runInPrivateWindow, + iframeSandbox, + accessRemoval: null, // only passed with non-blocking callback + callbackAfterRemoval: null, + }); + this._createCleanupTask(cleanupFunction); + + this._createTask({ + name, + cookieBehavior: BEHAVIOR_REJECT_FOREIGN, + blockingByContentBlockingRTUI: true, + allowList: true, + callback: callbackNonTracking, + extraPrefs, + expectedBlockingNotifications: 0, + runInPrivateWindow, + iframeSandbox, + accessRemoval: null, // only passed with non-blocking callback + callbackAfterRemoval: null, + }); + this._createCleanupTask(cleanupFunction); + + this._createTask({ + name, + cookieBehavior: BEHAVIOR_REJECT_TRACKER, + blockingByContentBlockingRTUI: true, + allowList: true, + callback: callbackNonTracking, + extraPrefs, + expectedBlockingNotifications: 0, + runInPrivateWindow, + iframeSandbox, + accessRemoval, + callbackAfterRemoval, + }); + this._createCleanupTask(cleanupFunction); + + this._createTask({ + name, + cookieBehavior: BEHAVIOR_REJECT_TRACKER, + blockingByContentBlockingRTUI: false, + allowList: false, + callback: callbackNonTracking, + extraPrefs, + expectedBlockingNotifications: false, + runInPrivateWindow, + iframeSandbox, + accessRemoval: null, // only passed with non-blocking callback + callbackAfterRemoval: null, + thirdPartyPage: TEST_ANOTHER_3RD_PARTY_PAGE, + }); + this._createCleanupTask(cleanupFunction); + } + + // Phase 2: Here we want to test that a third-party context doesn't + // get blocked with when the same origin is opened through window.open(). + if (windowOpenTest) { + this._createWindowOpenTask(name, callbackTracking, callbackNonTracking, + runInPrivateWindow, iframeSandbox, extraPrefs); + this._createCleanupTask(cleanupFunction); + } + + // Phase 3: Here we want to test that a third-party context doesn't + // get blocked with user interaction present + if (userInteractionTest) { + this._createUserInteractionTask(name, callbackTracking, callbackNonTracking, + runInPrivateWindow, iframeSandbox, extraPrefs); + this._createCleanupTask(cleanupFunction); + } + } + }, + + async interactWithTracker() { + let windowClosed = new Promise(resolve => { + Services.ww.registerNotification(function notification(aSubject, aTopic, aData) { + if (aTopic == "domwindowclosed") { + Services.ww.unregisterNotification(notification); + resolve(); + } + }); + }); + + info("Let's interact with the tracker"); + window.open(TEST_3RD_PARTY_DOMAIN + TEST_PATH + "3rdPartyOpenUI.html"); + await windowClosed; + }, + + async _setupTest(win, cookieBehavior, blockingByContentBlockingRTUI, + extraPrefs) { + await SpecialPowers.flushPrefEnv(); + await SpecialPowers.pushPrefEnv({"set": [ + ["dom.storage_access.enabled", true], + ["browser.contentblocking.allowlist.annotations.enabled", blockingByContentBlockingRTUI], + ["browser.contentblocking.allowlist.storage.enabled", blockingByContentBlockingRTUI], + ["network.cookie.cookieBehavior", cookieBehavior], + ["privacy.trackingprotection.enabled", false], + ["privacy.trackingprotection.pbmode.enabled", false], + ["privacy.trackingprotection.annotate_channels", cookieBehavior != BEHAVIOR_ACCEPT], + [win.ContentBlocking.prefIntroCount, win.ContentBlocking.MAX_INTROS], + ["privacy.restrict3rdpartystorage.userInteractionRequiredForHosts", "tracking.example.com,tracking.example.org"], + ]}); + + if (extraPrefs && Array.isArray(extraPrefs) && extraPrefs.length) { + await SpecialPowers.pushPrefEnv({"set": extraPrefs }); + + for (let item of extraPrefs) { + // When setting up skip URLs, we need to wait to ensure our prefs + // actually take effect. In order to do this, we set up a skip list + // observer and wait until it calls us back. + if (item[0] == "urlclassifier.trackingAnnotationSkipURLs") { + info("Waiting for the skip list service to initialize..."); + let classifier = Cc["@mozilla.org/url-classifier/dbservice;1"] + .getService(Ci.nsIURIClassifier); + let feature = classifier.getFeatureByName("tracking-annotation"); + await TestUtils.waitForCondition(() => feature.skipHostList == item[1].toLowerCase(), + "Skip list service initialized"); + break; + } + } + } + + await UrlClassifierTestUtils.addTestTrackers(); + }, + + _createTask(options) { + add_task(async function() { + info("Starting " + (options.cookieBehavior != BEHAVIOR_ACCEPT ? "blocking" : "non-blocking") + " cookieBehavior (" + options.cookieBehavior + ") and " + + (options.blockingByContentBlockingRTUI ? "" : "no") + " contentBlocking third-party cookies UI with" + + (options.allowList ? "" : "out") + " allow list test " + options.name + + " running in a " + (options.runInPrivateWindow ? "private" : "normal") + " window " + + " with iframe sandbox set to " + options.iframeSandbox + + " and access removal set to " + options.accessRemoval + + (typeof options.thirdPartyPage == "string" ? ( + " and third party page set to " + options.thirdPartyPage) : "")); + + is(!!options.callbackAfterRemoval, !!options.accessRemoval, + "callbackAfterRemoval must be passed when accessRemoval is non-null"); + + let win = window; + if (options.runInPrivateWindow) { + win = OpenBrowserWindow({private: true}); + await TestUtils.topicObserved("browser-delayed-startup-finished"); + } + + await AntiTracking._setupTest(win, options.cookieBehavior, + options.blockingByContentBlockingRTUI, + options.extraPrefs); + + let cookieBlocked = 0; + let listener = { + onContentBlockingEvent(webProgress, request, event) { + if ((event & options.expectedBlockingNotifications)) { + ++cookieBlocked; + } + }, + }; + win.gBrowser.addProgressListener(listener); + + info("Creating a new tab"); + let tab = BrowserTestUtils.addTab(win.gBrowser, TEST_TOP_PAGE); + win.gBrowser.selectedTab = tab; + + let browser = win.gBrowser.getBrowserForTab(tab); + await BrowserTestUtils.browserLoaded(browser); + + if (options.allowList) { + info("Disabling content blocking for this page"); + win.ContentBlocking.disableForCurrentPage(); + + // The previous function reloads the browser, so wait for it to load again! + await BrowserTestUtils.browserLoaded(browser); + } + + info("Creating a 3rd party content"); + let doAccessRemovalChecks = typeof options.accessRemoval == "string" && + options.cookieBehavior == BEHAVIOR_REJECT_TRACKER && + options.blockingByContentBlockingRTUI && + !options.allowList; + let thirdPartyPage; + if (typeof options.thirdPartyPage == "string") { + thirdPartyPage = options.thirdPartyPage; + } else { + thirdPartyPage = TEST_3RD_PARTY_PAGE; + } + await ContentTask.spawn(browser, + { page: thirdPartyPage, + nextPage: TEST_4TH_PARTY_PAGE, + callback: options.callback.toString(), + callbackAfterRemoval: options.callbackAfterRemoval ? + options.callbackAfterRemoval.toString() : null, + accessRemoval: options.accessRemoval, + iframeSandbox: options.iframeSandbox, + allowList: options.allowList, + doAccessRemovalChecks }, + async function(obj) { + let id = "id" + Math.random(); + await new content.Promise(resolve => { + let ifr = content.document.createElement("iframe"); + ifr.id = id; + ifr.onload = function() { + info("Sending code to the 3rd party content"); + let callback = obj.allowList + "!!!" + obj.callback; + ifr.contentWindow.postMessage(callback, "*"); + }; + if (typeof obj.iframeSandbox == "string") { + ifr.setAttribute("sandbox", obj.iframeSandbox); + } + + content.addEventListener("message", function msg(event) { + if (event.data.type == "finish") { + content.removeEventListener("message", msg); + resolve(); + return; + } + + if (event.data.type == "ok") { + ok(event.data.what, event.data.msg); + return; + } + + if (event.data.type == "info") { + info(event.data.msg); + return; + } + + ok(false, "Unknown message"); + }); + + content.document.body.appendChild(ifr); + ifr.src = obj.page; + }); + + if (obj.doAccessRemovalChecks) { + info(`Running after removal checks (${obj.accessRemoval})`); + switch (obj.accessRemoval) { + case "navigate-subframe": + await new content.Promise(resolve => { + let ifr = content.document.getElementById(id); + let oldWindow = ifr.contentWindow; + ifr.onload = function() { + info("Sending code to the old 3rd party content"); + oldWindow.postMessage(obj.callbackAfterRemoval, "*"); + }; + if (typeof obj.iframeSandbox == "string") { + ifr.setAttribute("sandbox", obj.iframeSandbox); + } + + content.addEventListener("message", function msg(event) { + if (event.data.type == "finish") { + content.removeEventListener("message", msg); + resolve(); + return; + } + + if (event.data.type == "ok") { + ok(event.data.what, event.data.msg); + return; + } + + if (event.data.type == "info") { + info(event.data.msg); + return; + } + + ok(false, "Unknown message"); + }); + + ifr.src = obj.nextPage; + }); + break; + default: + ok(false, "Unexpected accessRemoval code passed: " + obj.accessRemoval); + break; + } + } + }); + + if (options.allowList) { + info("Enabling content blocking for this page"); + win.ContentBlocking.enableForCurrentPage(); + + // The previous function reloads the browser, so wait for it to load again! + await BrowserTestUtils.browserLoaded(browser); + } + + win.gBrowser.removeProgressListener(listener); + + is(!!cookieBlocked, !!options.expectedBlockingNotifications, "Checking cookie blocking notifications"); + + info("Removing the tab"); + BrowserTestUtils.removeTab(tab); + + if (options.runInPrivateWindow) { + win.close(); + } + }); + }, + + _createCleanupTask(cleanupFunction) { + add_task(async function() { + info("Cleaning up."); + if (cleanupFunction) { + await cleanupFunction(); + } + }); + }, + + _createWindowOpenTask(name, blockingCallback, nonBlockingCallback, runInPrivateWindow, + iframeSandbox, extraPrefs) { + add_task(async function() { + info("Starting window-open test " + name); + + let win = window; + if (runInPrivateWindow) { + win = OpenBrowserWindow({private: true}); + await TestUtils.topicObserved("browser-delayed-startup-finished"); + } + + await AntiTracking._setupTest(win, BEHAVIOR_REJECT_TRACKER, true, extraPrefs); + + info("Creating a new tab"); + let tab = BrowserTestUtils.addTab(win.gBrowser, TEST_TOP_PAGE); + win.gBrowser.selectedTab = tab; + + let browser = win.gBrowser.getBrowserForTab(tab); + await BrowserTestUtils.browserLoaded(browser); + + let pageURL = TEST_3RD_PARTY_PAGE_WO; + if (gFeatures == "noopener") { + pageURL += "?noopener"; + } + + info("Creating a 3rd party content"); + await ContentTask.spawn(browser, + { page: pageURL, + blockingCallback: blockingCallback.toString(), + nonBlockingCallback: nonBlockingCallback.toString(), + iframeSandbox, + }, + async function(obj) { + await new content.Promise(resolve => { + let ifr = content.document.createElement("iframe"); + ifr.onload = function() { + info("Sending code to the 3rd party content"); + ifr.contentWindow.postMessage(obj, "*"); + }; + if (typeof obj.iframeSandbox == "string") { + ifr.setAttribute("sandbox", obj.iframeSandbox); + } + + content.addEventListener("message", function msg(event) { + if (event.data.type == "finish") { + content.removeEventListener("message", msg); + resolve(); + return; + } + + if (event.data.type == "ok") { + ok(event.data.what, event.data.msg); + return; + } + + if (event.data.type == "info") { + info(event.data.msg); + return; + } + + ok(false, "Unknown message"); + }); + + content.document.body.appendChild(ifr); + ifr.src = obj.page; + }); + }); + + info("Removing the tab"); + BrowserTestUtils.removeTab(tab); + + if (runInPrivateWindow) { + win.close(); + } + }); + }, + + _createUserInteractionTask(name, blockingCallback, nonBlockingCallback, + runInPrivateWindow, iframeSandbox, extraPrefs) { + add_task(async function() { + info("Starting user-interaction test " + name); + + let win = window; + if (runInPrivateWindow) { + win = OpenBrowserWindow({private: true}); + await TestUtils.topicObserved("browser-delayed-startup-finished"); + } + + await AntiTracking._setupTest(win, BEHAVIOR_REJECT_TRACKER, true, extraPrefs); + + info("Creating a new tab"); + let tab = BrowserTestUtils.addTab(win.gBrowser, TEST_TOP_PAGE); + win.gBrowser.selectedTab = tab; + + let browser = win.gBrowser.getBrowserForTab(tab); + await BrowserTestUtils.browserLoaded(browser); + + info("Creating a 3rd party content"); + await ContentTask.spawn(browser, + { page: TEST_3RD_PARTY_PAGE_UI, + popup: TEST_POPUP_PAGE, + blockingCallback: blockingCallback.toString(), + iframeSandbox, + }, + async function(obj) { + let ifr = content.document.createElement("iframe"); + let loading = new content.Promise(resolve => { ifr.onload = resolve; }); + if (typeof obj.iframeSandbox == "string") { + ifr.setAttribute("sandbox", obj.iframeSandbox); + } + content.document.body.appendChild(ifr); + ifr.src = obj.page; + await loading; + + info("The 3rd party content should not have access to first party storage."); + await new content.Promise(resolve => { + content.addEventListener("message", function msg(event) { + if (event.data.type == "finish") { + content.removeEventListener("message", msg); + resolve(); + return; + } + + if (event.data.type == "ok") { + ok(event.data.what, event.data.msg); + return; + } + + if (event.data.type == "info") { + info(event.data.msg); + return; + } + + ok(false, "Unknown message"); + }); + ifr.contentWindow.postMessage({ callback: obj.blockingCallback }, "*"); + }); + + let windowClosed = new content.Promise(resolve => { + Services.ww.registerNotification(function notification(aSubject, aTopic, aData) { + if (aTopic == "domwindowclosed") { + Services.ww.unregisterNotification(notification); + resolve(); + } + }); + }); + + info("Opening a window from the iframe."); + ifr.contentWindow.open(obj.popup); + + info("Let's wait for the window to be closed"); + await windowClosed; + + info("First time, the 3rd party content should not have access to first party storage " + + "because the tracker did not have user interaction"); + await new content.Promise(resolve => { + content.addEventListener("message", function msg(event) { + if (event.data.type == "finish") { + content.removeEventListener("message", msg); + resolve(); + return; + } + + if (event.data.type == "ok") { + ok(event.data.what, event.data.msg); + return; + } + + if (event.data.type == "info") { + info(event.data.msg); + return; + } + + ok(false, "Unknown message"); + }); + ifr.contentWindow.postMessage({ callback: obj.blockingCallback }, "*"); + }); + }); + + await AntiTracking.interactWithTracker(); + + await ContentTask.spawn(browser, + { page: TEST_3RD_PARTY_PAGE_UI, + popup: TEST_POPUP_PAGE, + nonBlockingCallback: nonBlockingCallback.toString(), + iframeSandbox, + }, + async function(obj) { + let ifr = content.document.createElement("iframe"); + let loading = new content.Promise(resolve => { ifr.onload = resolve; }); + if (typeof obj.iframeSandbox == "string") { + ifr.setAttribute("sandbox", obj.iframeSandbox); + } + content.document.body.appendChild(ifr); + ifr.src = obj.page; + await loading; + + let windowClosed = new content.Promise(resolve => { + Services.ww.registerNotification(function notification(aSubject, aTopic, aData) { + if (aTopic == "domwindowclosed") { + Services.ww.unregisterNotification(notification); + resolve(); + } + }); + }); + + info("Opening a window from the iframe."); + ifr.contentWindow.open(obj.popup); + + info("Let's wait for the window to be closed"); + await windowClosed; + + info("The 3rd party content should now have access to first party storage."); + await new content.Promise(resolve => { + content.addEventListener("message", function msg(event) { + if (event.data.type == "finish") { + content.removeEventListener("message", msg); + resolve(); + return; + } + + if (event.data.type == "ok") { + ok(event.data.what, event.data.msg); + return; + } + + if (event.data.type == "info") { + info(event.data.msg); + return; + } + + ok(false, "Unknown message"); + }); + ifr.contentWindow.postMessage({ callback: obj.nonBlockingCallback }, "*"); + }); + }); + + info("Removing the tab"); + BrowserTestUtils.removeTab(tab); + + if (runInPrivateWindow) { + win.close(); + } + }); + }, +}; diff --git a/toolkit/components/antitracking/test/browser/imageCacheWorker.js b/toolkit/components/antitracking/test/browser/imageCacheWorker.js index 869bafa8483e..f65c365d1c93 100644 --- a/toolkit/components/antitracking/test/browser/imageCacheWorker.js +++ b/toolkit/components/antitracking/test/browser/imageCacheWorker.js @@ -1,7 +1,5 @@ /* import-globals-from head.js */ -/* import-globals-from antitracking_head.js */ /* import-globals-from browser_imageCache4.js */ - AntiTracking.runTest("Image cache - should load the image three times.", // blocking callback async _ => { diff --git a/toolkit/components/antitracking/test/browser/matchAll.js b/toolkit/components/antitracking/test/browser/matchAll.js deleted file mode 100644 index 4eecac38ac4b..000000000000 --- a/toolkit/components/antitracking/test/browser/matchAll.js +++ /dev/null @@ -1,13 +0,0 @@ -self.addEventListener("message", async e => { - let clients = await self.clients.matchAll({type: "window", includeUncontrolled: true}); - - let hasWindow = false; - for (let client of clients) { - if (e.data == client.url) { - hasWindow = true; - break; - } - } - - e.source.postMessage(hasWindow); -}); diff --git a/toolkit/components/antitracking/test/browser/sharedWorker.js b/toolkit/components/antitracking/test/browser/sharedWorker.js deleted file mode 100644 index 01188ed10a2c..000000000000 --- a/toolkit/components/antitracking/test/browser/sharedWorker.js +++ /dev/null @@ -1,18 +0,0 @@ -let ports = 0; -self.onconnect = e => { - ++ports; - e.ports[0].onmessage = event => { - if (event.data === "count") { - e.ports[0].postMessage(ports); - return; - } - - if (event.data === "close") { - self.close(); - return; - } - - // Error. - e.ports[0].postMessage(-1); - }; -}; diff --git a/toolkit/components/antitracking/test/browser/storageprincipal_head.js b/toolkit/components/antitracking/test/browser/storageprincipal_head.js deleted file mode 100644 index 28b8b8fc934d..000000000000 --- a/toolkit/components/antitracking/test/browser/storageprincipal_head.js +++ /dev/null @@ -1,89 +0,0 @@ -/* vim: set ts=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/. */ - -/* import-globals-from head.js */ - -"use strict"; - -this.StoragePrincipalHelper = { - runTest(name, callback, cleanupFunction, extraPrefs) { - add_task(async _ => { - info("Starting test `" + name + "'..."); - - await SpecialPowers.flushPrefEnv(); - await SpecialPowers.pushPrefEnv({"set": [ - ["dom.storage_access.enabled", true], - ["network.cookie.cookieBehavior", Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER], - ["privacy.trackingprotection.enabled", false], - ["privacy.trackingprotection.pbmode.enabled", false], - ["privacy.trackingprotection.annotate_channels", true], - ["privacy.storagePrincipal.enabledForTrackers", true], - ]}); - - if (extraPrefs && Array.isArray(extraPrefs) && extraPrefs.length) { - await SpecialPowers.pushPrefEnv({"set": extraPrefs }); - } - - await UrlClassifierTestUtils.addTestTrackers(); - - info("Creating a new tab"); - let tab = BrowserTestUtils.addTab(gBrowser, TEST_TOP_PAGE); - gBrowser.selectedTab = tab; - - let browser = gBrowser.getBrowserForTab(tab); - await BrowserTestUtils.browserLoaded(browser); - - info("Creating a 3rd party content"); - await ContentTask.spawn(browser, { - page: TEST_3RD_PARTY_STORAGE_PAGE, - callback: callback.toString(), - }, - async obj => { - await new content.Promise(resolve => { - let ifr = content.document.createElement("iframe"); - ifr.onload = __ => { - is(ifr.contentWindow.document.nodePrincipal.originAttributes.firstPartyDomain, "", "We don't have first-party set on nodePrincipal"); - is(ifr.contentWindow.document.effectiveStoragePrincipal.originAttributes.firstPartyDomain, "example.net", "We have first-party set on storagePrincipal"); - info("Sending code to the 3rd party content"); - ifr.contentWindow.postMessage(obj.callback, "*"); - }; - - content.addEventListener("message", function msg(event) { - if (event.data.type == "finish") { - content.removeEventListener("message", msg); - resolve(); - return; - } - - if (event.data.type == "ok") { - ok(event.data.what, event.data.msg); - return; - } - - if (event.data.type == "info") { - info(event.data.msg); - return; - } - - ok(false, "Unknown message"); - }); - - content.document.body.appendChild(ifr); - ifr.src = obj.page; - }); - }); - - info("Removing the tab"); - BrowserTestUtils.removeTab(tab); - }); - - add_task(async _ => { - info("Cleaning up."); - if (cleanupFunction) { - await cleanupFunction(); - } - }); - }, -};