From 8d2894e70d76db375845842a3f93bf5274e25942 Mon Sep 17 00:00:00 2001 From: Ciure Andrei Date: Thu, 28 Feb 2019 00:55:39 +0200 Subject: [PATCH] Backed out 12 changesets (bug 1525245) for failing worker-interception.https.html CLOSED TREE Backed out changeset 009e7457b990 (bug 1525245) Backed out changeset efb2e8fca464 (bug 1525245) Backed out changeset 6a8401de3237 (bug 1525245) Backed out changeset 38e802661b14 (bug 1525245) Backed out changeset d02e3f436390 (bug 1525245) Backed out changeset 10afd61b7582 (bug 1525245) Backed out changeset 6b92fb3666d1 (bug 1525245) Backed out changeset 476af2d7efe5 (bug 1525245) Backed out changeset 43ad14e323a1 (bug 1525245) Backed out changeset 94295e3fb027 (bug 1525245) Backed out changeset d01ead2270e9 (bug 1525245) Backed out changeset 6bdda622a04a (bug 1525245) --- dom/base/Document.cpp | 32 +-- dom/base/Document.h | 8 +- dom/base/nsContentUtils.cpp | 56 ++-- dom/base/nsContentUtils.h | 9 +- dom/base/nsGlobalWindowInner.cpp | 42 --- dom/base/nsGlobalWindowOuter.cpp | 43 ++- dom/broadcastchannel/BroadcastChannel.cpp | 32 ++- dom/indexedDB/test/mochitest.ini | 6 +- dom/indexedDB/test/test_third_party.html | 35 +-- dom/indexedDB/test/third_party_window.html | 33 --- dom/serviceworkers/test/mochitest.ini | 2 - .../test/test_third_party_iframes.html | 60 ++-- .../test/window_party_iframes.html | 18 -- dom/storage/LocalStorageCache.cpp | 26 +- dom/storage/LocalStorageCache.h | 6 + dom/storage/SessionStorage.cpp | 6 + dom/storage/SessionStorage.h | 2 + dom/storage/SessionStorageCache.cpp | 18 +- dom/storage/SessionStorageCache.h | 1 + dom/storage/Storage.cpp | 32 ++- dom/storage/Storage.h | 13 + dom/tests/mochitest/bugs/mochitest.ini | 1 - dom/tests/mochitest/bugs/test_bug1171215.html | 80 ++++-- .../mochitest/bugs/window_bug1171215.html | 86 ------ dom/tests/mochitest/general/mochitest.ini | 1 - .../general/storagePermissionsUtils.js | 29 -- .../test_storagePermissionsAccept.html | 36 ++- .../test_storagePermissionsLimitForeign.html | 38 ++- .../test_storagePermissionsReject.html | 36 ++- .../test_storagePermissionsRejectForeign.html | 36 ++- .../general/window_storagePermissions.html | 38 --- .../frameLocalStorageCookieSettings.html | 4 + .../mochitest/localstorage/mochitest.ini | 3 +- .../localstorage/test_cookieBlock.html | 37 ++- .../localstorage/test_cookieSession.html | 139 ++++++++++ .../test_localStorageCookieSettings.html | 67 ++--- .../test_localStorageSessionPrefOverride.html | 56 ++++ .../mochitest/localstorage/windowProxy.html | 3 - .../mochitest/sessionstorage/mochitest.ini | 1 + .../sessionstorage/test_cookieSession.html | 124 +++++++++ dom/workers/RuntimeService.cpp | 12 +- dom/workers/test/mochitest.ini | 4 +- .../test/sharedWorker_thirdparty_window.html | 26 -- .../test/test_sharedWorker_thirdparty.html | 13 +- .../test/unit/test_cookies_thirdparty.js | 120 +++----- ipc/glue/BackgroundUtils.cpp | 48 +--- modules/libpref/init/StaticPrefList.h | 8 - netwerk/base/LoadInfo.cpp | 43 +-- netwerk/base/LoadInfo.h | 5 +- netwerk/base/nsILoadInfo.idl | 7 - netwerk/cookie/CookieSettings.cpp | 206 -------------- netwerk/cookie/CookieSettings.h | 63 ----- netwerk/cookie/moz.build | 4 - netwerk/cookie/nsICookieSettings.idl | 30 -- netwerk/cookie/test/browser/browser.ini | 8 - .../test/browser/browser_broadcastChannel.js | 77 ------ .../cookie/test/browser/browser_domCache.js | 13 - .../cookie/test/browser/browser_indexedDB.js | 82 ------ .../test/browser/browser_serviceWorker.js | 24 -- .../test/browser/browser_sharedWorker.js | 16 -- .../cookie/test/browser/browser_storage.js | 41 --- netwerk/cookie/test/browser/file_empty.js | 1 - netwerk/cookie/test/browser/head.js | 173 ------------ netwerk/ipc/NeckoChannelParams.ipdlh | 28 -- .../antitracking/AntiTrackingCommon.cpp | 257 ++++++++---------- .../browser_storageAccessWithHeuristics.js | 37 +++ 66 files changed, 920 insertions(+), 1721 deletions(-) delete mode 100644 dom/indexedDB/test/third_party_window.html delete mode 100644 dom/serviceworkers/test/window_party_iframes.html delete mode 100644 dom/tests/mochitest/bugs/window_bug1171215.html delete mode 100644 dom/tests/mochitest/general/window_storagePermissions.html create mode 100644 dom/tests/mochitest/localstorage/test_cookieSession.html create mode 100644 dom/tests/mochitest/localstorage/test_localStorageSessionPrefOverride.html delete mode 100644 dom/tests/mochitest/localstorage/windowProxy.html create mode 100644 dom/tests/mochitest/sessionstorage/test_cookieSession.html delete mode 100644 dom/workers/test/sharedWorker_thirdparty_window.html delete mode 100644 netwerk/cookie/CookieSettings.cpp delete mode 100644 netwerk/cookie/CookieSettings.h delete mode 100644 netwerk/cookie/nsICookieSettings.idl delete mode 100644 netwerk/cookie/test/browser/browser_broadcastChannel.js delete mode 100644 netwerk/cookie/test/browser/browser_domCache.js delete mode 100644 netwerk/cookie/test/browser/browser_indexedDB.js delete mode 100644 netwerk/cookie/test/browser/browser_serviceWorker.js delete mode 100644 netwerk/cookie/test/browser/browser_sharedWorker.js delete mode 100644 netwerk/cookie/test/browser/browser_storage.js delete mode 100644 netwerk/cookie/test/browser/file_empty.js delete mode 100644 netwerk/cookie/test/browser/head.js diff --git a/dom/base/Document.cpp b/dom/base/Document.cpp index dbefbc060de6..f65aaedc73bf 100644 --- a/dom/base/Document.cpp +++ b/dom/base/Document.cpp @@ -78,7 +78,6 @@ #include "mozilla/dom/ShadowIncludingTreeIterator.h" #include "mozilla/dom/StyleSheetList.h" #include "mozilla/dom/SVGUseElement.h" -#include "mozilla/net/CookieSettings.h" #include "nsGenericHTMLElement.h" #include "mozilla/dom/CDATASection.h" #include "mozilla/dom/ProcessingInstruction.h" @@ -129,7 +128,6 @@ #include "nsIDOMWindow.h" #include "nsPIDOMWindow.h" #include "nsFocusManager.h" -#include "nsICookiePermission.h" #include "nsICookieService.h" #include "nsBidiUtils.h" @@ -2572,18 +2570,6 @@ nsresult Document::StartDocumentLoad(const char* aCommand, nsIChannel* aChannel, aChannel->Cancel(NS_ERROR_CSP_FRAME_ANCESTOR_VIOLATION); } - // Let's take the CookieSettings from the loadInfo or from the parent - // document. - if (loadInfo) { - rv = loadInfo->GetCookieSettings(getter_AddRefs(mCookieSettings)); - NS_ENSURE_SUCCESS(rv, rv); - } else { - nsCOMPtr parentDocument = GetParentDocument(); - if (parentDocument) { - mCookieSettings = parentDocument->CookieSettings(); - } - } - return NS_OK; } @@ -11813,7 +11799,7 @@ DocumentAutoplayPolicy Document::AutoplayPolicy() const { } void Document::MaybeAllowStorageForOpenerAfterUserInteraction() { - if (mCookieSettings->GetCookieBehavior() != + if (StaticPrefs::network_cookie_cookieBehavior() != nsICookieService::BEHAVIOR_REJECT_TRACKER) { return; } @@ -12329,8 +12315,8 @@ already_AddRefed Document::RequestStorageAccess( } // Only enforce third-party checks when there is a reason to enforce them. - if (mCookieSettings->GetCookieBehavior() != - nsICookieService::BEHAVIOR_REJECT_TRACKER) { + if (StaticPrefs::network_cookie_cookieBehavior() != + nsICookieService::BEHAVIOR_ACCEPT) { // Step 3. If the document's frame is the main frame, resolve. if (IsTopLevelContentDocument()) { promise->MaybeResolveWithUndefined(); @@ -12382,7 +12368,7 @@ already_AddRefed Document::RequestStorageAccess( return promise.forget(); } - if (mCookieSettings->GetCookieBehavior() == + if (StaticPrefs::network_cookie_cookieBehavior() == nsICookieService::BEHAVIOR_REJECT_TRACKER && inner) { // Only do something special for third-party tracking content. @@ -12640,15 +12626,5 @@ void Document::RecomputeLanguageFromCharset() { mLanguageFromCharset = language.forget(); } -nsICookieSettings* Document::CookieSettings() { - // If we are here, this is probably a javascript: URL document. In any case, - // we must have a nsCookieSettings. Let's create it. - if (!mCookieSettings) { - mCookieSettings = net::CookieSettings::Create(); - } - - return mCookieSettings; -} - } // namespace dom } // namespace mozilla diff --git a/dom/base/Document.h b/dom/base/Document.h index e479909847e2..6d0eca61943f 100644 --- a/dom/base/Document.h +++ b/dom/base/Document.h @@ -12,8 +12,7 @@ #include "nsCOMArray.h" // for member #include "nsCompatibility.h" // for member #include "nsCOMPtr.h" // for member -#include "nsICookieSettings.h" -#include "nsGkAtoms.h" // for static class members +#include "nsGkAtoms.h" // for static class members #include "nsIApplicationCache.h" #include "nsIApplicationCacheContainer.h" #include "nsIContentViewer.h" @@ -1506,9 +1505,6 @@ class Document : public nsINode, // Sets the cache sizes for the current generation. void SetCachedSizes(nsTabSizes* aSizes); - // Returns the cookie settings for this and sub contexts. - nsICookieSettings* CookieSettings(); - protected: friend class nsUnblockOnloadEvent; @@ -4667,8 +4663,6 @@ class Document : public nsINode, int32_t mCachedTabSizeGeneration; nsTabSizes mCachedTabSizes; - nsCOMPtr mCookieSettings; - 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 b389cad3c38b..e9f718b8706d 100644 --- a/dom/base/nsContentUtils.cpp +++ b/dom/base/nsContentUtils.cpp @@ -8229,30 +8229,31 @@ nsContentUtils::StorageAccess nsContentUtils::StorageAllowedForServiceWorker( } // static, private -void nsContentUtils::GetCookieLifetimePolicyFromCookieSettings( - nsICookieSettings* aCookieSettings, nsIPrincipal* aPrincipal, - uint32_t* aLifetimePolicy) { +void nsContentUtils::GetCookieLifetimePolicyForPrincipal( + nsIPrincipal* aPrincipal, uint32_t* aLifetimePolicy) { *aLifetimePolicy = sCookiesLifetimePolicy; - if (aCookieSettings) { - uint32_t cookiePermission = 0; - nsresult rv = - aCookieSettings->CookiePermission(aPrincipal, &cookiePermission); - if (NS_WARN_IF(NS_FAILED(rv))) { - return; - } + // Any permissions set for the given principal will override our default + // settings from preferences. + nsCOMPtr permissionManager = + services::GetPermissionManager(); + if (!permissionManager) { + return; + } - switch (cookiePermission) { - case nsICookiePermission::ACCESS_ALLOW: - *aLifetimePolicy = nsICookieService::ACCEPT_NORMALLY; - break; - case nsICookiePermission::ACCESS_DENY: - *aLifetimePolicy = nsICookieService::ACCEPT_NORMALLY; - break; - case nsICookiePermission::ACCESS_SESSION: - *aLifetimePolicy = nsICookieService::ACCEPT_SESSION; - break; - } + uint32_t perm; + permissionManager->TestPermissionFromPrincipal( + aPrincipal, NS_LITERAL_CSTRING("cookie"), &perm); + switch (perm) { + case nsICookiePermission::ACCESS_ALLOW: + *aLifetimePolicy = nsICookieService::ACCEPT_NORMALLY; + break; + case nsICookiePermission::ACCESS_DENY: + *aLifetimePolicy = nsICookieService::ACCEPT_NORMALLY; + break; + case nsICookiePermission::ACCESS_SESSION: + *aLifetimePolicy = nsICookieService::ACCEPT_SESSION; + break; } } @@ -8423,7 +8424,6 @@ nsContentUtils::StorageAccess nsContentUtils::InternalStorageAllowedCheck( aRejectedReason = 0; StorageAccess access = StorageAccess::eAllow; - nsCOMPtr cookieSettings; // We don't allow storage on the null principal, in general. Even if the // calling context is chrome. @@ -8442,15 +8442,6 @@ nsContentUtils::StorageAccess nsContentUtils::InternalStorageAllowedCheck( if (IsInPrivateBrowsing(document)) { access = StorageAccess::ePrivateBrowsing; } - - if (document) { - cookieSettings = document->CookieSettings(); - } - } - - if (aChannel) { - nsCOMPtr loadInfo = aChannel->LoadInfo(); - loadInfo->GetCookieSettings(getter_AddRefs(cookieSettings)); } uint32_t lifetimePolicy; @@ -8462,8 +8453,7 @@ nsContentUtils::StorageAccess nsContentUtils::InternalStorageAllowedCheck( if (policy) { lifetimePolicy = nsICookieService::ACCEPT_NORMALLY; } else { - GetCookieLifetimePolicyFromCookieSettings(cookieSettings, aPrincipal, - &lifetimePolicy); + GetCookieLifetimePolicyForPrincipal(aPrincipal, &lifetimePolicy); } // Check if we should only allow storage for the session, and record that fact diff --git a/dom/base/nsContentUtils.h b/dom/base/nsContentUtils.h index e95378542e26..43d56c2bbfed 100644 --- a/dom/base/nsContentUtils.h +++ b/dom/base/nsContentUtils.h @@ -3385,14 +3385,13 @@ class nsContentUtils { CallOnRemoteChildFunction aCallback, void* aArg); /** - * Gets the cookie lifetime policy for a given cookieSettings and a given - * principal by checking the permission value. + * Gets the current cookie lifetime policy for a given principal by checking + * with preferences and the permission manager. * * Used in the implementation of InternalStorageAllowedCheck. */ - static void GetCookieLifetimePolicyFromCookieSettings( - nsICookieSettings* aCookieSettings, nsIPrincipal* aPrincipal, - uint32_t* aLifetimePolicy); + static void GetCookieLifetimePolicyForPrincipal(nsIPrincipal* aPrincipal, + uint32_t* aLifetimePolicy); /* * Checks if storage for a given principal is permitted by the user's diff --git a/dom/base/nsGlobalWindowInner.cpp b/dom/base/nsGlobalWindowInner.cpp index 6976cef5f0fd..e2eded505dc6 100644 --- a/dom/base/nsGlobalWindowInner.cpp +++ b/dom/base/nsGlobalWindowInner.cpp @@ -4349,48 +4349,6 @@ Storage* nsGlobalWindowInner::GetSessionStorage(ErrorResult& aError) { return nullptr; } - uint32_t rejectedReason = 0; - nsContentUtils::StorageAccess access = - nsContentUtils::StorageAllowedForWindow(this, &rejectedReason); - - // SessionStorage is an ephemeral per-tab per-origin storage that only lives - // as long as the tab is open, although it may survive browser restarts - // thanks to the session store. So we interpret storage access differently - // than we would for persistent per-origin storage like LocalStorage and so - // it may be okay to provide SessionStorage even when we receive a value of - // eDeny. - // - // AntiTrackingCommon::IsFirstPartyStorageAccessGranted will return false - // for 3 main reasons. - // - // 1. Cookies are entirely blocked due to a per-origin permission - // (nsICookiePermission::ACCESS_DENY for the top-level principal or this - // window's principal) or the very broad BEHAVIOR_REJECT. This will return - // eDeny with a reason of STATE_COOKIES_BLOCKED_BY_PERMISSION or - // STATE_COOKIES_BLOCKED_ALL. - // - // 2. Third-party cookies are limited via BEHAVIOR_REJECT_FOREIGN and - // BEHAVIOR_LIMIT_FOREIGN and this is a third-party window. This will return - // eDeny with a reason of STATE_COOKIES_BLOCKED_FOREIGN. - // - // 3. Tracking protection (BEHAVIOR_REJECT_TRACKER) is in effect and - // IsThirdPartyTrackingResourceWindow() returned true and there wasn't a - // permission that allows it. This will return ePartitionedOrDeny with a - // reason of STATE_COOKIES_BLOCKED_TRACKER. - // - // In the 1st case, the user has explicitly indicated that they don't want - // to allow any storage to the origin or all origins and so we throw an - // error and deny access to SessionStorage. In the 2nd case, a legacy - // decision reasoned that there's no harm in providing SessionStorage - // because the information is not durable and cannot escape the current tab. - // The rationale is similar for the 3rd case. - if (access == nsContentUtils::StorageAccess::eDeny && - rejectedReason != - nsIWebProgressListener::STATE_COOKIES_BLOCKED_FOREIGN) { - aError.Throw(NS_ERROR_DOM_SECURITY_ERR); - return nullptr; - } - nsresult rv; nsCOMPtr storageManager = diff --git a/dom/base/nsGlobalWindowOuter.cpp b/dom/base/nsGlobalWindowOuter.cpp index 24ee26498201..2360608f5e23 100644 --- a/dom/base/nsGlobalWindowOuter.cpp +++ b/dom/base/nsGlobalWindowOuter.cpp @@ -1264,6 +1264,10 @@ nsGlobalWindowOuter::~nsGlobalWindowOuter() { if (obs) { obs->RemoveObserver(this, PERM_CHANGE_NOTIFICATION); } + nsCOMPtr prefBranch = do_GetService(NS_PREFSERVICE_CONTRACTID); + if (prefBranch) { + prefBranch->RemoveObserver("network.cookie.cookieBehavior", this); + } nsLayoutStatics::Release(); } @@ -2320,18 +2324,20 @@ nsresult nsGlobalWindowOuter::SetNewDocument(Document* aDocument, mHasStorageAccess = false; nsIURI* uri = aDocument->GetDocumentURI(); - if (newInnerWindow && - aDocument->CookieSettings()->GetCookieBehavior() == - nsICookieService::BEHAVIOR_REJECT_TRACKER && - nsContentUtils::IsThirdPartyWindowOrChannel(newInnerWindow, nullptr, - uri) && - nsContentUtils::IsTrackingResourceWindow(newInnerWindow)) { - // Grant storage access by default if the first-party storage access - // permission has been granted already. - // Don't notify in this case, since we would be notifying the user - // needlessly. - mHasStorageAccess = AntiTrackingCommon::IsFirstPartyStorageAccessGrantedFor( - newInnerWindow, uri, nullptr); + if (newInnerWindow) { + if (StaticPrefs::network_cookie_cookieBehavior() == + nsICookieService::BEHAVIOR_REJECT_TRACKER && + nsContentUtils::IsThirdPartyWindowOrChannel(newInnerWindow, nullptr, + uri) && + nsContentUtils::IsTrackingResourceWindow(newInnerWindow)) { + // Grant storage access by default if the first-party storage access + // permission has been granted already. + // Don't notify in this case, since we would be notifying the user + // needlessly. + mHasStorageAccess = + AntiTrackingCommon::IsFirstPartyStorageAccessGrantedFor( + newInnerWindow, uri, nullptr); + } } return NS_OK; @@ -6969,6 +6975,11 @@ NS_IMETHODIMP nsGlobalWindowOuter::Observe(nsISupports* aSupports, const char* aTopic, const char16_t* aData) { if (!nsCRT::strcmp(aTopic, PERM_CHANGE_NOTIFICATION)) { + if (!nsCRT::strcmp(aData, u"cleared") && !aSupports) { + // All permissions have been cleared. + mHasStorageAccess = false; + return NS_OK; + } nsCOMPtr permission = do_QueryInterface(aSupports); if (!permission) { return NS_OK; @@ -7000,6 +7011,10 @@ nsGlobalWindowOuter::Observe(nsISupports* aSupports, const char* aTopic, return NS_OK; } } + } else if (!nsCRT::strcmp(aTopic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID)) { + // Reset the storage access permission when our cookie policy changes. + mHasStorageAccess = false; + return NS_OK; } return NS_OK; } @@ -7796,6 +7811,10 @@ mozilla::dom::TabGroup* nsPIDOMWindowOuter::TabGroup() { obs->AddObserver(window, PERM_CHANGE_NOTIFICATION, true); })); } + nsCOMPtr prefBranch = do_GetService(NS_PREFSERVICE_CONTRACTID); + if (prefBranch) { + prefBranch->AddObserver("network.cookie.cookieBehavior", window, true); + } return window.forget(); } diff --git a/dom/broadcastchannel/BroadcastChannel.cpp b/dom/broadcastchannel/BroadcastChannel.cpp index 7f9bb16e9d57..0427fe7fdacc 100644 --- a/dom/broadcastchannel/BroadcastChannel.cpp +++ b/dom/broadcastchannel/BroadcastChannel.cpp @@ -67,13 +67,15 @@ nsIPrincipal* GetPrincipalFromThreadSafeWorkerRef( class InitializeRunnable final : public WorkerMainThreadRunnable { public: InitializeRunnable(ThreadSafeWorkerRef* aWorkerRef, nsACString& aOrigin, - PrincipalInfo& aPrincipalInfo, ErrorResult& aRv) + PrincipalInfo& aPrincipalInfo, bool* aThirdPartyWindow, + ErrorResult& aRv) : WorkerMainThreadRunnable( aWorkerRef->Private(), NS_LITERAL_CSTRING("BroadcastChannel :: Initialize")), mWorkerRef(aWorkerRef), mOrigin(aOrigin), mPrincipalInfo(aPrincipalInfo), + mThirdPartyWindow(aThirdPartyWindow), mRv(aRv) { MOZ_ASSERT(mWorkerRef); } @@ -109,6 +111,9 @@ class InitializeRunnable final : public WorkerMainThreadRunnable { return true; } + *mThirdPartyWindow = + nsContentUtils::IsThirdPartyWindowOrChannel(window, nullptr, nullptr); + return true; } @@ -116,6 +121,7 @@ class InitializeRunnable final : public WorkerMainThreadRunnable { RefPtr mWorkerRef; nsACString& mOrigin; PrincipalInfo& mPrincipalInfo; + bool* mThirdPartyWindow; ErrorResult& mRv; }; @@ -241,14 +247,6 @@ JSObject* BroadcastChannel::WrapObject(JSContext* aCx, return nullptr; } - // 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; @@ -258,6 +256,13 @@ JSObject* BroadcastChannel::WrapObject(JSContext* aCx, if (NS_WARN_IF(aRv.Failed())) { return nullptr; } + + if (nsContentUtils::IsThirdPartyWindowOrChannel(window, nullptr, nullptr) && + nsContentUtils::StorageAllowedForWindow(window) != + nsContentUtils::StorageAccess::eAllow) { + aRv.Throw(NS_ERROR_DOM_SECURITY_ERR); + return nullptr; + } } else { JSContext* cx = aGlobal.Context(); @@ -275,15 +280,16 @@ JSObject* BroadcastChannel::WrapObject(JSContext* aCx, RefPtr tsr = new ThreadSafeWorkerRef(workerRef); - RefPtr runnable = - new InitializeRunnable(tsr, origin, principalInfo, aRv); + bool thirdPartyWindow = false; + + RefPtr runnable = new InitializeRunnable( + tsr, origin, principalInfo, &thirdPartyWindow, aRv); runnable->Dispatch(Canceling, aRv); if (aRv.Failed()) { return nullptr; } - if (principalInfo.type() != PrincipalInfo::TNullPrincipalInfo && - !workerPrivate->IsStorageAllowed()) { + if (thirdPartyWindow && !workerPrivate->IsStorageAllowed()) { aRv.Throw(NS_ERROR_DOM_SECURITY_ERR); return nullptr; } diff --git a/dom/indexedDB/test/mochitest.ini b/dom/indexedDB/test/mochitest.ini index 6fcff713eba9..34b2cc095d8b 100644 --- a/dom/indexedDB/test/mochitest.ini +++ b/dom/indexedDB/test/mochitest.ini @@ -16,6 +16,8 @@ support-files = file.js helpers.js leaving_page_iframe.html + third_party_iframe1.html + third_party_iframe2.html unit/test_abort_deleted_index.js unit/test_abort_deleted_objectStore.js unit/test_add_put.js @@ -254,10 +256,6 @@ scheme=https [test_table_locks.html] [test_table_rollback.html] [test_third_party.html] -support-files = - third_party_window.html - third_party_iframe1.html - third_party_iframe2.html skip-if = (os == 'android' && debug) # Bug 1311590 [test_traffic_jam.html] [test_transaction_abort.html] diff --git a/dom/indexedDB/test/test_third_party.html b/dom/indexedDB/test/test_third_party.html index 9c609b909979..9347cb5ea5d4 100644 --- a/dom/indexedDB/test/test_third_party.html +++ b/dom/indexedDB/test/test_third_party.html @@ -46,25 +46,29 @@ "third_party_iframe2.html"); let testIndex = 0; - let openedWindow; + let testRunning = false; - // Cookie preference changes are only applied to top-level tabs/windows - // when they are loaded. We need a window-proxy to continue the test. - function openWindow() { + function iframeLoaded() { + let message = { source: "parent", href: iframe2URL }; + let iframe = document.getElementById("iframe1"); + iframe.contentWindow.postMessage(message.toSource(), "*"); + } + + function setiframe() { + let iframe = document.getElementById("iframe1"); + + if (!testRunning) { + testRunning = true; + iframe.addEventListener("load", iframeLoaded); + } SpecialPowers.pushPrefEnv({ "set": [ ["network.cookie.cookieBehavior", testData[testIndex].cookieBehavior], ], }, () => { - openedWindow = window.open("third_party_window.html"); - openedWindow.onload = _ => { - openedWindow.postMessage({ - source: "parent", - href: iframe2URL, - iframeUrl: testData[testIndex].host + iframe1Path, - }, "*"); - }; + iframe.src = testData[testIndex].host + iframe1Path; }); + // SpecialPowers.setIntPref("network.cookie.cookieBehavior", testData[testIndex].cookieBehavior); } function messageListener(event) { @@ -74,11 +78,9 @@ is(message.source, "iframe", "Good source"); is(message.result, testData[testIndex].expectedResult, "Good result"); - openedWindow.close(); - if (testIndex < testData.length - 1) { testIndex++; - openWindow(); + setiframe(); return; } @@ -91,13 +93,14 @@ SpecialPowers.addPermission("indexedDB", true, document); window.addEventListener("message", messageListener); - openWindow(); + setiframe(); } + diff --git a/dom/indexedDB/test/third_party_window.html b/dom/indexedDB/test/third_party_window.html deleted file mode 100644 index f2d7ba46ab75..000000000000 --- a/dom/indexedDB/test/third_party_window.html +++ /dev/null @@ -1,33 +0,0 @@ - - - - Indexed Database Test - - - - - - - - diff --git a/dom/serviceworkers/test/mochitest.ini b/dom/serviceworkers/test/mochitest.ini index dba7b9e7bc3e..0f833d54da13 100644 --- a/dom/serviceworkers/test/mochitest.ini +++ b/dom/serviceworkers/test/mochitest.ini @@ -308,8 +308,6 @@ skip-if = serviceworker_e10s [test_skip_waiting.html] [test_strict_mode_warning.html] [test_third_party_iframes.html] -support-files = - window_party_iframes.html [test_unregister.html] [test_unresolved_fetch_interception.html] skip-if = verify || serviceworker_e10s diff --git a/dom/serviceworkers/test/test_third_party_iframes.html b/dom/serviceworkers/test/test_third_party_iframes.html index 3d1ae92ed2af..e0ead59a48df 100644 --- a/dom/serviceworkers/test/test_third_party_iframes.html +++ b/dom/serviceworkers/test/test_third_party_iframes.html @@ -11,6 +11,11 @@ +

+ +

 
-
-
diff --git a/dom/storage/LocalStorageCache.cpp b/dom/storage/LocalStorageCache.cpp
index 47167501d32f..b9cac378e357 100644
--- a/dom/storage/LocalStorageCache.cpp
+++ b/dom/storage/LocalStorageCache.cpp
@@ -77,6 +77,7 @@ LocalStorageCache::LocalStorageCache(const nsACString* aOriginNoSuffix)
       mLoadResult(NS_OK),
       mInitialized(false),
       mPersistent(false),
+      mSessionOnlyDataSetActive(false),
       mPreloadTelemetryRecorded(false) {
   MOZ_COUNT_CTOR(LocalStorageCache);
 }
@@ -182,7 +183,29 @@ const nsCString LocalStorageCache::Origin() const {
 
 LocalStorageCache::Data& LocalStorageCache::DataSet(
     const LocalStorage* aStorage) {
-  return mData[GetDataSetIndex(aStorage)];
+  uint32_t index = GetDataSetIndex(aStorage);
+
+  if (index == kSessionSet && !mSessionOnlyDataSetActive) {
+    // Session only data set is demanded but not filled with
+    // current data set, copy to session only set now.
+
+    WaitForPreload(Telemetry::LOCALDOMSTORAGE_SESSIONONLY_PRELOAD_BLOCKING_MS);
+
+    Data& defaultSet = mData[kDefaultSet];
+    Data& sessionSet = mData[kSessionSet];
+
+    for (auto iter = defaultSet.mKeys.Iter(); !iter.Done(); iter.Next()) {
+      sessionSet.mKeys.Put(iter.Key(), iter.UserData());
+    }
+
+    mSessionOnlyDataSetActive = true;
+
+    // This updates sessionSet.mOriginQuotaUsage and also updates global usage
+    // for all session only data
+    ProcessUsageDelta(kSessionSet, defaultSet.mOriginQuotaUsage);
+  }
+
+  return mData[index];
 }
 
 bool LocalStorageCache::ProcessUsageDelta(const LocalStorage* aStorage,
@@ -518,6 +541,7 @@ void LocalStorageCache::UnloadItems(uint32_t aUnloadFlags) {
   if (aUnloadFlags & kUnloadSession) {
     mData[kSessionSet].mKeys.Clear();
     ProcessUsageDelta(kSessionSet, -mData[kSessionSet].mOriginQuotaUsage);
+    mSessionOnlyDataSetActive = false;
   }
 
 #ifdef DOM_STORAGE_TESTS
diff --git a/dom/storage/LocalStorageCache.h b/dom/storage/LocalStorageCache.h
index bbd1844599e6..ae4cd92eb2fe 100644
--- a/dom/storage/LocalStorageCache.h
+++ b/dom/storage/LocalStorageCache.h
@@ -267,6 +267,12 @@ class LocalStorageCache : public LocalStorageCacheBridge {
   // default data set.)
   bool mPersistent : 1;
 
+  // - False when the session-only data set was never used.
+  // - True after access to session-only data has been made for the first time.
+  // We also fill session-only data set with the default one at that moment.
+  // Drops back to false when session-only data are cleared from chrome.
+  bool mSessionOnlyDataSetActive : 1;
+
   // Whether we have already captured state of the cache preload on our first
   // access.
   bool mPreloadTelemetryRecorded : 1;
diff --git a/dom/storage/SessionStorage.cpp b/dom/storage/SessionStorage.cpp
index 0734c17d97ee..d1481ef3357d 100644
--- a/dom/storage/SessionStorage.cpp
+++ b/dom/storage/SessionStorage.cpp
@@ -164,5 +164,11 @@ bool SessionStorage::IsForkOf(const Storage* aOther) const {
   return mCache == static_cast(aOther)->mCache;
 }
 
+bool SessionStorage::ShouldThrowWhenStorageAccessDenied(
+    uint32_t aRejectedReason) {
+  return aRejectedReason !=
+         nsIWebProgressListener::STATE_COOKIES_BLOCKED_FOREIGN;
+}
+
 }  // namespace dom
 }  // namespace mozilla
diff --git a/dom/storage/SessionStorage.h b/dom/storage/SessionStorage.h
index 828278249ea7..2d80cd4d8525 100644
--- a/dom/storage/SessionStorage.h
+++ b/dom/storage/SessionStorage.h
@@ -65,6 +65,8 @@ class SessionStorage final : public Storage {
                                    const nsAString& aOldValue,
                                    const nsAString& aNewValue);
 
+  bool ShouldThrowWhenStorageAccessDenied(uint32_t aRejectedReason) override;
+
   RefPtr mCache;
   RefPtr mManager;
 
diff --git a/dom/storage/SessionStorageCache.cpp b/dom/storage/SessionStorageCache.cpp
index 379416f671df..eed7fd378437 100644
--- a/dom/storage/SessionStorageCache.cpp
+++ b/dom/storage/SessionStorageCache.cpp
@@ -9,7 +9,7 @@
 namespace mozilla {
 namespace dom {
 
-SessionStorageCache::SessionStorageCache() = default;
+SessionStorageCache::SessionStorageCache() : mSessionDataSetActive(false) {}
 
 SessionStorageCache::DataSet* SessionStorageCache::Set(
     DataSetType aDataSetType) {
@@ -19,6 +19,16 @@ SessionStorageCache::DataSet* SessionStorageCache::Set(
 
   MOZ_ASSERT(aDataSetType == eSessionSetType);
 
+  if (!mSessionDataSetActive) {
+    mSessionSet.mOriginQuotaUsage = mDefaultSet.mOriginQuotaUsage;
+
+    for (auto iter = mDefaultSet.mKeys.ConstIter(); !iter.Done(); iter.Next()) {
+      mSessionSet.mKeys.Put(iter.Key(), iter.Data());
+    }
+
+    mSessionDataSetActive = true;
+  }
+
   return &mSessionSet;
 }
 
@@ -111,11 +121,17 @@ void SessionStorageCache::Clear(DataSetType aDataSetType,
   DataSet* dataSet = Set(aDataSetType);
   dataSet->ProcessUsageDelta(-dataSet->mOriginQuotaUsage);
   dataSet->mKeys.Clear();
+
+  if (!aByUserInteraction && aDataSetType == eSessionSetType) {
+    mSessionDataSetActive = false;
+  }
 }
 
 already_AddRefed SessionStorageCache::Clone() const {
   RefPtr cache = new SessionStorageCache();
 
+  cache->mSessionDataSetActive = mSessionDataSetActive;
+
   cache->mDefaultSet.mOriginQuotaUsage = mDefaultSet.mOriginQuotaUsage;
   for (auto iter = mDefaultSet.mKeys.ConstIter(); !iter.Done(); iter.Next()) {
     cache->mDefaultSet.mKeys.Put(iter.Key(), iter.Data());
diff --git a/dom/storage/SessionStorageCache.h b/dom/storage/SessionStorageCache.h
index 5606d7830cf4..17eb069fb3d5 100644
--- a/dom/storage/SessionStorageCache.h
+++ b/dom/storage/SessionStorageCache.h
@@ -60,6 +60,7 @@ class SessionStorageCache final {
 
   DataSet mDefaultSet;
   DataSet mSessionSet;
+  bool mSessionDataSetActive;
 };
 
 }  // namespace dom
diff --git a/dom/storage/Storage.cpp b/dom/storage/Storage.cpp
index 8055f37a6d1a..0b69dbe1b5ff 100644
--- a/dom/storage/Storage.cpp
+++ b/dom/storage/Storage.cpp
@@ -29,20 +29,6 @@ NS_INTERFACE_MAP_END
 Storage::Storage(nsPIDOMWindowInner* aWindow, nsIPrincipal* aPrincipal)
     : mWindow(aWindow), mPrincipal(aPrincipal), mIsSessionOnly(false) {
   MOZ_ASSERT(aPrincipal);
-
-  if (nsContentUtils::IsSystemPrincipal(mPrincipal)) {
-    mIsSessionOnly = false;
-  } else if (mWindow) {
-    uint32_t rejectedReason = 0;
-    nsContentUtils::StorageAccess access =
-        nsContentUtils::StorageAllowedForWindow(mWindow, &rejectedReason);
-
-    MOZ_ASSERT(access != nsContentUtils::StorageAccess::eDeny ||
-               rejectedReason ==
-                   nsIWebProgressListener::STATE_COOKIES_BLOCKED_FOREIGN);
-
-    mIsSessionOnly = access <= nsContentUtils::StorageAccess::eSessionScoped;
-  }
 }
 
 Storage::~Storage() {}
@@ -52,10 +38,28 @@ Storage::~Storage() {}
 }
 
 bool Storage::CanUseStorage(nsIPrincipal& aSubjectPrincipal) {
+  // This method is responsible for correct setting of mIsSessionOnly.
   if (!StoragePrefIsEnabled()) {
     return false;
   }
 
+  if (nsContentUtils::IsSystemPrincipal(mPrincipal)) {
+    mIsSessionOnly = false;
+  } else if (mWindow) {
+    uint32_t rejectedReason = 0;
+    nsContentUtils::StorageAccess access =
+        nsContentUtils::StorageAllowedForWindow(mWindow, &rejectedReason);
+
+    // Note that we allow StorageAccess::ePartitionedOrDeny because we want
+    // tracker to have access to their sessionStorage.
+    if (access == nsContentUtils::StorageAccess::eDeny &&
+        ShouldThrowWhenStorageAccessDenied(rejectedReason)) {
+      return false;
+    }
+
+    mIsSessionOnly = access <= nsContentUtils::StorageAccess::eSessionScoped;
+  }
+
   return aSubjectPrincipal.Subsumes(mPrincipal);
 }
 
diff --git a/dom/storage/Storage.h b/dom/storage/Storage.h
index 41433771357f..8cd59b6ce80c 100644
--- a/dom/storage/Storage.h
+++ b/dom/storage/Storage.h
@@ -134,10 +134,23 @@ class Storage : public nsISupports, public nsWrapperCache {
   virtual ~Storage();
 
   // The method checks whether the caller can use a storage.
+  // CanUseStorage is called before any DOM initiated operation
+  // on a storage is about to happen and ensures that the storage's
+  // session-only flag is properly set according the current settings.
+  // It is an optimization since the privileges check and session only
+  // state determination are complex and share the code (comes hand in
+  // hand together).
   bool CanUseStorage(nsIPrincipal& aSubjectPrincipal);
 
   virtual void LastRelease() {}
 
+  // This method is called when StorageAccess is not granted for the owning
+  // window. aRejectedReason is one of the possible blocking states from
+  // nsIWebProgressListener.
+  virtual bool ShouldThrowWhenStorageAccessDenied(uint32_t aRejectedReason) {
+    return true;
+  }
+
  private:
   nsCOMPtr mWindow;
   nsCOMPtr mPrincipal;
diff --git a/dom/tests/mochitest/bugs/mochitest.ini b/dom/tests/mochitest/bugs/mochitest.ini
index 7537f99061dd..8b32d0f056bf 100644
--- a/dom/tests/mochitest/bugs/mochitest.ini
+++ b/dom/tests/mochitest/bugs/mochitest.ini
@@ -149,7 +149,6 @@ skip-if = toolkit == 'android'
 [test_bug1112040.html]
 [test_bug1160342_marquee.html]
 [test_bug1171215.html]
-support-files = window_bug1171215.html
 [test_bug1530292.html]
 [test_no_find_showDialog.html]
 skip-if = toolkit == 'android' # Bug 1358633 - window.find doesn't work for Android
diff --git a/dom/tests/mochitest/bugs/test_bug1171215.html b/dom/tests/mochitest/bugs/test_bug1171215.html
index f6e5660cda6c..5f06e74b0b8c 100644
--- a/dom/tests/mochitest/bugs/test_bug1171215.html
+++ b/dom/tests/mochitest/bugs/test_bug1171215.html
@@ -9,8 +9,11 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1022869
   
   
   
+  
   
 
 
 Mozilla Bug 1022869
+

+ +
+
diff --git a/dom/tests/mochitest/bugs/window_bug1171215.html b/dom/tests/mochitest/bugs/window_bug1171215.html deleted file mode 100644 index f196457b1834..000000000000 --- a/dom/tests/mochitest/bugs/window_bug1171215.html +++ /dev/null @@ -1,86 +0,0 @@ - - - - - - Test for Bug 1022869 - - - - - - diff --git a/dom/tests/mochitest/general/mochitest.ini b/dom/tests/mochitest/general/mochitest.ini index e1c9e55adb4f..fa60f86aa5ff 100644 --- a/dom/tests/mochitest/general/mochitest.ini +++ b/dom/tests/mochitest/general/mochitest.ini @@ -50,7 +50,6 @@ support-files = workerStorageAllowed.js workerStoragePrevented.js storagePermissionsUtils.js - window_storagePermissions.html frameSelectEvents.html !/image/test/mochitest/big.png !/image/test/mochitest/blue.png diff --git a/dom/tests/mochitest/general/storagePermissionsUtils.js b/dom/tests/mochitest/general/storagePermissionsUtils.js index 4345f4cbef8f..7bdda9f57bf8 100644 --- a/dom/tests/mochitest/general/storagePermissionsUtils.js +++ b/dom/tests/mochitest/general/storagePermissionsUtils.js @@ -242,33 +242,4 @@ function task(fn) { } } -// The test will run on a separate window in order to apply the new cookie settings. -async function runTestInWindow(test) { - let w = window.open("window_storagePermissions.html"); - await new Promise(resolve => { - w.onload = e => { - resolve(); - } - }); - - await new Promise(resolve => { - onmessage = e => { - if (e.data.type == "finish") { - w.close(); - resolve(); - return; - } - - if (e.data.type == "check") { - ok(e.data.test, e.data.msg); - return; - } - - ok(false, "Unknown message"); - }; - - w.postMessage(test.toString(), "*"); - }); -} - var thirdparty = "https://example.com/tests/dom/tests/mochitest/general/"; diff --git a/dom/tests/mochitest/general/test_storagePermissionsAccept.html b/dom/tests/mochitest/general/test_storagePermissionsAccept.html index 58b0ab6c595f..f8fb14181597 100644 --- a/dom/tests/mochitest/general/test_storagePermissionsAccept.html +++ b/dom/tests/mochitest/general/test_storagePermissionsAccept.html @@ -14,29 +14,27 @@ task(async function() { await setCookieBehavior(BEHAVIOR_ACCEPT); - await runTestInWindow(async function() { - // We should be able to access storage - await storageAllowed(); + // We should be able to access storage + await storageAllowed(); - // Same origin iframes should be allowed, unless they redirect to a URI with the null principal - await runIFrame("frameStorageAllowed.html"); - await runIFrame("frameStorageNullprincipal.sjs"); - await runIFrame("frameStorageChrome.html?allowed=yes"); + // Same origin iframes should be allowed, unless they redirect to a URI with the null principal + await runIFrame("frameStorageAllowed.html"); + await runIFrame("frameStorageNullprincipal.sjs"); + await runIFrame("frameStorageChrome.html?allowed=yes"); - // Sandboxed iframes should have the null principal, and thus can't access storage - document.querySelector('iframe').setAttribute('sandbox', 'allow-scripts'); - await runIFrame("frameStoragePrevented.html#nullprincipal"); - await runIFrame("frameStorageNullprincipal.sjs"); - document.querySelector('iframe').removeAttribute('sandbox'); + // Sandboxed iframes should have the null principal, and thus can't access storage + document.querySelector('iframe').setAttribute('sandbox', 'allow-scripts'); + await runIFrame("frameStoragePrevented.html#nullprincipal"); + await runIFrame("frameStorageNullprincipal.sjs"); + document.querySelector('iframe').removeAttribute('sandbox'); - // Thirdparty iframes should be allowed, unless they redirect to a URI with the null principal - await runIFrame(thirdparty + "frameStorageAllowed.html"); - await runIFrame(thirdparty + "frameStorageNullprincipal.sjs"); - await runIFrame(thirdparty + "frameStorageChrome.html?allowed=yes"); + // Thirdparty iframes should be allowed, unless they redirect to a URI with the null principal + await runIFrame(thirdparty + "frameStorageAllowed.html"); + await runIFrame(thirdparty + "frameStorageNullprincipal.sjs"); + await runIFrame(thirdparty + "frameStorageChrome.html?allowed=yes"); - // Workers should be able to access storage - await runWorker("workerStorageAllowed.js"); - }); + // Workers should be able to access storage + await runWorker("workerStorageAllowed.js"); }); diff --git a/dom/tests/mochitest/general/test_storagePermissionsLimitForeign.html b/dom/tests/mochitest/general/test_storagePermissionsLimitForeign.html index bdc4bd52e26f..ddc1003cb5e9 100644 --- a/dom/tests/mochitest/general/test_storagePermissionsLimitForeign.html +++ b/dom/tests/mochitest/general/test_storagePermissionsLimitForeign.html @@ -14,31 +14,29 @@ task(async function() { await setCookieBehavior(BEHAVIOR_LIMIT_FOREIGN); - await runTestInWindow(async function() { - // We should be able to access storage - await storageAllowed(); + // We should be able to access storage + await storageAllowed(); - // Same origin iframes should be allowed. - await runIFrame("frameStorageAllowed.html"); - await runIFrame("frameStorageChrome.html?allowed=yes"); + // Same origin iframes should be allowed. + await runIFrame("frameStorageAllowed.html"); + await runIFrame("frameStorageChrome.html?allowed=yes"); - // Null principal iframes should not. - await runIFrame("frameStorageNullprincipal.sjs"); + // Null principal iframes should not. + await runIFrame("frameStorageNullprincipal.sjs"); - // Sandboxed iframes should have the null principal, and thus can't access storage - document.querySelector('iframe').setAttribute('sandbox', 'allow-scripts'); - await runIFrame("frameStoragePrevented.html#nullprincipal"); - await runIFrame("frameStorageNullprincipal.sjs"); - document.querySelector('iframe').removeAttribute('sandbox'); + // Sandboxed iframes should have the null principal, and thus can't access storage + document.querySelector('iframe').setAttribute('sandbox', 'allow-scripts'); + await runIFrame("frameStoragePrevented.html#nullprincipal"); + await runIFrame("frameStorageNullprincipal.sjs"); + document.querySelector('iframe').removeAttribute('sandbox'); - // Thirdparty iframes should be blocked, even when accessed from chrome over Xrays. - await runIFrame(thirdparty + "frameStoragePrevented.html#thirdparty"); - await runIFrame(thirdparty + "frameStorageNullprincipal.sjs"); - await runIFrame(thirdparty + "frameStorageChrome.html?allowed=no"); + // Thirdparty iframes should be blocked, even when accessed from chrome over Xrays. + await runIFrame(thirdparty + "frameStoragePrevented.html#thirdparty"); + await runIFrame(thirdparty + "frameStorageNullprincipal.sjs"); + await runIFrame(thirdparty + "frameStorageChrome.html?allowed=no"); - // Workers should be unable to access storage - await runWorker("workerStorageAllowed.js"); - }); + // Workers should be unable to access storage + await runWorker("workerStorageAllowed.js"); }); diff --git a/dom/tests/mochitest/general/test_storagePermissionsReject.html b/dom/tests/mochitest/general/test_storagePermissionsReject.html index dda1f4a6f21b..fc45feb94720 100644 --- a/dom/tests/mochitest/general/test_storagePermissionsReject.html +++ b/dom/tests/mochitest/general/test_storagePermissionsReject.html @@ -14,29 +14,27 @@ task(async function() { await setCookieBehavior(BEHAVIOR_REJECT); - await runTestInWindow(async function() { - // We should be unable to access storage - await storagePrevented(); + // We should be unable to access storage + await storagePrevented(); - // Same origin iframes should be blocked. - await runIFrame("frameStoragePrevented.html"); - await runIFrame("frameStorageNullprincipal.sjs"); - await runIFrame("frameStorageChrome.html?allowed=no&blockSessionStorage=yes"); + // Same origin iframes should be blocked. + await runIFrame("frameStoragePrevented.html"); + await runIFrame("frameStorageNullprincipal.sjs"); + await runIFrame("frameStorageChrome.html?allowed=no&blockSessionStorage=yes"); - // Sandboxed iframes should have the null principal, and thus can't access storage - document.querySelector('iframe').setAttribute('sandbox', 'allow-scripts'); - await runIFrame("frameStoragePrevented.html#nullprincipal"); - await runIFrame("frameStorageNullprincipal.sjs"); - document.querySelector('iframe').removeAttribute('sandbox'); + // Sandboxed iframes should have the null principal, and thus can't access storage + document.querySelector('iframe').setAttribute('sandbox', 'allow-scripts'); + await runIFrame("frameStoragePrevented.html#nullprincipal"); + await runIFrame("frameStorageNullprincipal.sjs"); + document.querySelector('iframe').removeAttribute('sandbox'); - // thirdparty iframes should be blocked. - await runIFrame(thirdparty + "frameStoragePrevented.html"); - await runIFrame(thirdparty + "frameStorageNullprincipal.sjs"); - await runIFrame(thirdparty + "frameStorageChrome.html?allowed=no&blockSessionStorage=yes"); + // thirdparty iframes should be blocked. + await runIFrame(thirdparty + "frameStoragePrevented.html"); + await runIFrame(thirdparty + "frameStorageNullprincipal.sjs"); + await runIFrame(thirdparty + "frameStorageChrome.html?allowed=no&blockSessionStorage=yes"); - // Workers should be unable to access storage - await runWorker("workerStoragePrevented.js"); - }); + // Workers should be unable to access storage + await runWorker("workerStoragePrevented.js"); }); diff --git a/dom/tests/mochitest/general/test_storagePermissionsRejectForeign.html b/dom/tests/mochitest/general/test_storagePermissionsRejectForeign.html index a38ebb0bfc87..bbbb7ad9c515 100644 --- a/dom/tests/mochitest/general/test_storagePermissionsRejectForeign.html +++ b/dom/tests/mochitest/general/test_storagePermissionsRejectForeign.html @@ -14,29 +14,27 @@ task(async function() { await setCookieBehavior(BEHAVIOR_REJECT_FOREIGN); - await runTestInWindow(async function() { - // We should be able to access storage - await storageAllowed(); + // We should be able to access storage + await storageAllowed(); - // Same origin iframes should be allowed, unless they redirect to a URI with the null principal - await runIFrame("frameStorageAllowed.html"); - await runIFrame("frameStorageNullprincipal.sjs"); - await runIFrame("frameStorageChrome.html?allowed=yes"); + // Same origin iframes should be allowed, unless they redirect to a URI with the null principal + await runIFrame("frameStorageAllowed.html"); + await runIFrame("frameStorageNullprincipal.sjs"); + await runIFrame("frameStorageChrome.html?allowed=yes"); - // Sandboxed iframes should have the null principal, and thus can't access storage - document.querySelector('iframe').setAttribute('sandbox', 'allow-scripts'); - await runIFrame("frameStoragePrevented.html#nullprincipal"); - await runIFrame("frameStorageNullprincipal.sjs"); - document.querySelector('iframe').removeAttribute('sandbox'); + // Sandboxed iframes should have the null principal, and thus can't access storage + document.querySelector('iframe').setAttribute('sandbox', 'allow-scripts'); + await runIFrame("frameStoragePrevented.html#nullprincipal"); + await runIFrame("frameStorageNullprincipal.sjs"); + document.querySelector('iframe').removeAttribute('sandbox'); - // thirdparty iframes should be blocked. - await runIFrame(thirdparty + "frameStoragePrevented.html#thirdparty"); - await runIFrame(thirdparty + "frameStorageNullprincipal.sjs"); - await runIFrame(thirdparty + "frameStorageChrome.html?allowed=no"); + // thirdparty iframes should be blocked. + await runIFrame(thirdparty + "frameStoragePrevented.html#thirdparty"); + await runIFrame(thirdparty + "frameStorageNullprincipal.sjs"); + await runIFrame(thirdparty + "frameStorageChrome.html?allowed=no"); - // Workers should be able to access storage - await runWorker("workerStorageAllowed.js"); - }); + // Workers should be able to access storage + await runWorker("workerStorageAllowed.js"); }); diff --git a/dom/tests/mochitest/general/window_storagePermissions.html b/dom/tests/mochitest/general/window_storagePermissions.html deleted file mode 100644 index 3bab23c13b02..000000000000 --- a/dom/tests/mochitest/general/window_storagePermissions.html +++ /dev/null @@ -1,38 +0,0 @@ - - - Storage Permission Restrictions - - - - - - - - diff --git a/dom/tests/mochitest/localstorage/frameLocalStorageCookieSettings.html b/dom/tests/mochitest/localstorage/frameLocalStorageCookieSettings.html index 451c90c3925c..27d179bb795c 100644 --- a/dom/tests/mochitest/localstorage/frameLocalStorageCookieSettings.html +++ b/dom/tests/mochitest/localstorage/frameLocalStorageCookieSettings.html @@ -2,6 +2,8 @@ localStorage cookies settings test + + diff --git a/dom/tests/mochitest/localstorage/mochitest.ini b/dom/tests/mochitest/localstorage/mochitest.ini index 66719781cdb9..442b81ef2fa2 100644 --- a/dom/tests/mochitest/localstorage/mochitest.ini +++ b/dom/tests/mochitest/localstorage/mochitest.ini @@ -17,7 +17,6 @@ support-files = localStorageCommon.js frameLocalStorageSessionOnly.html file_tryAccessSessionStorage.html - windowProxy.html [test_brokenUTF-16.html] [test_bug600307-DBOps.html] @@ -25,6 +24,7 @@ support-files = [test_bug746272-2.html] skip-if = os == "android" || verify # bug 962029 [test_cookieBlock.html] +[test_cookieSession.html] [test_embededNulls.html] [test_keySync.html] [test_localStorageBase.html] @@ -49,3 +49,4 @@ skip-if = true # bug 1347690 [test_localStorageReplace.html] skip-if = toolkit == 'android' [test_storageConstructor.html] +[test_localStorageSessionPrefOverride.html] diff --git a/dom/tests/mochitest/localstorage/test_cookieBlock.html b/dom/tests/mochitest/localstorage/test_cookieBlock.html index 317c023edc8d..5e3cae6c8f90 100644 --- a/dom/tests/mochitest/localstorage/test_cookieBlock.html +++ b/dom/tests/mochitest/localstorage/test_cookieBlock.html @@ -9,28 +9,23 @@ function startTest() { - // Let's use a new window to have the cookie permission applied. - let w = window.open("windowProxy.html"); - w.onload = _ => { - try { - w.localStorage.setItem("blocked", "blockedvalue"); - ok(false, "Exception for localStorage.setItem, ACCESS_DENY"); - } - catch (ex) { - ok(true, "Exception for localStorage.setItem, ACCESS_DENY"); - } - - try { - w.localStorage.getItem("blocked"); - ok(false, "Exception for localStorage.getItem, ACCESS_DENY"); - } - catch (ex) { - ok(true, "Exception for localStorage.getItem, ACCESS_DENY"); - } - - w.close(); - SimpleTest.finish(); + try { + localStorage.setItem("blocked", "blockedvalue"); + ok(false, "Exception for localStorage.setItem, ACCESS_DENY"); } + catch (ex) { + ok(true, "Exception for localStorage.setItem, ACCESS_DENY"); + } + + try { + localStorage.getItem("blocked"); + ok(false, "Exception for localStorage.getItem, ACCESS_DENY"); + } + catch (ex) { + ok(true, "Exception for localStorage.getItem, ACCESS_DENY"); + } + + SimpleTest.finish(); } SimpleTest.waitForExplicitFinish(); diff --git a/dom/tests/mochitest/localstorage/test_cookieSession.html b/dom/tests/mochitest/localstorage/test_cookieSession.html new file mode 100644 index 000000000000..34989553509a --- /dev/null +++ b/dom/tests/mochitest/localstorage/test_cookieSession.html @@ -0,0 +1,139 @@ + + +cookie per-session only test + + + + + + + + + + + diff --git a/dom/tests/mochitest/localstorage/test_localStorageCookieSettings.html b/dom/tests/mochitest/localstorage/test_localStorageCookieSettings.html index 4f5ea329d173..50240854d7d9 100644 --- a/dom/tests/mochitest/localstorage/test_localStorageCookieSettings.html +++ b/dom/tests/mochitest/localstorage/test_localStorageCookieSettings.html @@ -8,6 +8,7 @@ + diff --git a/dom/tests/mochitest/localstorage/test_localStorageSessionPrefOverride.html b/dom/tests/mochitest/localstorage/test_localStorageSessionPrefOverride.html new file mode 100644 index 000000000000..57f9cacbdcac --- /dev/null +++ b/dom/tests/mochitest/localstorage/test_localStorageSessionPrefOverride.html @@ -0,0 +1,56 @@ + + + Local Storage Session Pref Override + + + + + + + + diff --git a/dom/tests/mochitest/localstorage/windowProxy.html b/dom/tests/mochitest/localstorage/windowProxy.html deleted file mode 100644 index 39ba8eab0f99..000000000000 --- a/dom/tests/mochitest/localstorage/windowProxy.html +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/dom/tests/mochitest/sessionstorage/mochitest.ini b/dom/tests/mochitest/sessionstorage/mochitest.ini index 99d6e0cabb09..30ef81dfb71f 100644 --- a/dom/tests/mochitest/sessionstorage/mochitest.ini +++ b/dom/tests/mochitest/sessionstorage/mochitest.ini @@ -8,6 +8,7 @@ support-files = interOriginSlave.js interOriginTest.js +[test_cookieSession.html] [test_sessionStorageBase.html] [test_sessionStorageBaseSessionOnly.html] [test_sessionStorageClone.html] diff --git a/dom/tests/mochitest/sessionstorage/test_cookieSession.html b/dom/tests/mochitest/sessionstorage/test_cookieSession.html new file mode 100644 index 000000000000..7203f552ac81 --- /dev/null +++ b/dom/tests/mochitest/sessionstorage/test_cookieSession.html @@ -0,0 +1,124 @@ + + +cookie per-session only test + + + + + + + + + + + + diff --git a/dom/workers/RuntimeService.cpp b/dom/workers/RuntimeService.cpp index 6e4ca8930470..9d3205b86773 100644 --- a/dom/workers/RuntimeService.cpp +++ b/dom/workers/RuntimeService.cpp @@ -2017,10 +2017,8 @@ void RuntimeService::PropagateFirstPartyStorageAccessGranted( nsPIDOMWindowInner* aWindow) { AssertIsOnMainThread(); MOZ_ASSERT(aWindow); - MOZ_ASSERT_IF( - aWindow->GetExtantDoc(), - aWindow->GetExtantDoc()->CookieSettings()->GetCookieBehavior() == - nsICookieService::BEHAVIOR_REJECT_TRACKER); + MOZ_ASSERT(StaticPrefs::network_cookie_cookieBehavior() == + nsICookieService::BEHAVIOR_REJECT_TRACKER); nsTArray workers; GetWorkersForWindow(aWindow, workers); @@ -2401,10 +2399,8 @@ void ResumeWorkersForWindow(nsPIDOMWindowInner* aWindow) { void PropagateFirstPartyStorageAccessGrantedToWorkers( nsPIDOMWindowInner* aWindow) { AssertIsOnMainThread(); - MOZ_ASSERT_IF( - aWindow->GetExtantDoc(), - aWindow->GetExtantDoc()->CookieSettings()->GetCookieBehavior() == - nsICookieService::BEHAVIOR_REJECT_TRACKER); + MOZ_ASSERT(StaticPrefs::network_cookie_cookieBehavior() == + nsICookieService::BEHAVIOR_REJECT_TRACKER); RuntimeService* runtime = RuntimeService::GetService(); if (runtime) { diff --git a/dom/workers/test/mochitest.ini b/dom/workers/test/mochitest.ini index fad3cbc0ef78..31adc283f012 100644 --- a/dom/workers/test/mochitest.ini +++ b/dom/workers/test/mochitest.ini @@ -55,6 +55,7 @@ support-files = redirect_to_foreign.sjs rvals_worker.js sharedWorker_sharedWorker.js + sharedWorker_thirdparty_frame.html simpleThread_worker.js suspend_window.html suspend_worker.js @@ -172,9 +173,6 @@ skip-if = toolkit == 'android' [test_rvals.html] [test_sharedWorker.html] [test_sharedWorker_thirdparty.html] -support-files = - sharedWorker_thirdparty_frame.html - sharedWorker_thirdparty_window.html [test_simpleThread.html] [test_suspend.html] [test_terminate.html] diff --git a/dom/workers/test/sharedWorker_thirdparty_window.html b/dom/workers/test/sharedWorker_thirdparty_window.html deleted file mode 100644 index f5f01066c2b4..000000000000 --- a/dom/workers/test/sharedWorker_thirdparty_window.html +++ /dev/null @@ -1,26 +0,0 @@ - - - - - Test for SharedWorker in 3rd Party Iframes - - - - - diff --git a/dom/workers/test/test_sharedWorker_thirdparty.html b/dom/workers/test/test_sharedWorker_thirdparty.html index dc20410ddb08..fce9128a7472 100644 --- a/dom/workers/test/test_sharedWorker_thirdparty.html +++ b/dom/workers/test/test_sharedWorker_thirdparty.html @@ -11,18 +11,22 @@ +

+ +
   
+  
diff --git a/extensions/cookie/test/unit/test_cookies_thirdparty.js b/extensions/cookie/test/unit/test_cookies_thirdparty.js index b9c8df792686..99be33158bcd 100644 --- a/extensions/cookie/test/unit/test_cookies_thirdparty.js +++ b/extensions/cookie/test/unit/test_cookies_thirdparty.js @@ -6,99 +6,57 @@ // 2) with channel, but with no docshell parent function run_test() { - Services.prefs.setBoolPref("network.cookieSettings.unblocked_for_testing", true); - // Create URIs and channels pointing to foo.com and bar.com. // We will use these to put foo.com into first and third party contexts. - let spec1 = "http://foo.com/foo.html"; - let spec2 = "http://bar.com/bar.html"; - let uri1 = NetUtil.newURI(spec1); - let uri2 = NetUtil.newURI(spec2); + var spec1 = "http://foo.com/foo.html"; + var spec2 = "http://bar.com/bar.html"; + var uri1 = NetUtil.newURI(spec1); + var uri2 = NetUtil.newURI(spec2); + var channel1 = NetUtil.newChannel({uri: uri1, loadUsingSystemPrincipal: true}); + var channel2 = NetUtil.newChannel({uri: uri2, loadUsingSystemPrincipal: true}); - // test with cookies enabled - { - Services.prefs.setIntPref("network.cookie.cookieBehavior", 0); - - let channel1 = NetUtil.newChannel({uri: uri1, loadUsingSystemPrincipal: true}); - let channel2 = NetUtil.newChannel({uri: uri2, loadUsingSystemPrincipal: true}); - - do_set_cookies(uri1, channel1, true, [1, 2, 3, 4]); - Services.cookies.removeAll(); - do_set_cookies(uri1, channel2, true, [1, 2, 3, 4]); - Services.cookies.removeAll(); - } + // test with cookies enabled + Services.prefs.setIntPref("network.cookie.cookieBehavior", 0); + do_set_cookies(uri1, channel1, true, [1, 2, 3, 4]); + Services.cookies.removeAll(); + do_set_cookies(uri1, channel2, true, [1, 2, 3, 4]); + Services.cookies.removeAll(); // test with third party cookies blocked - { - Services.prefs.setIntPref("network.cookie.cookieBehavior", 1); - - let channel1 = NetUtil.newChannel({uri: uri1, loadUsingSystemPrincipal: true}); - let channel2 = NetUtil.newChannel({uri: uri2, loadUsingSystemPrincipal: true}); - - do_set_cookies(uri1, channel1, true, [0, 0, 0, 0]); - Services.cookies.removeAll(); - do_set_cookies(uri1, channel2, true, [0, 0, 0, 0]); - Services.cookies.removeAll(); - } + Services.prefs.setIntPref("network.cookie.cookieBehavior", 1); + do_set_cookies(uri1, channel1, true, [0, 0, 0, 0]); + Services.cookies.removeAll(); + do_set_cookies(uri1, channel2, true, [0, 0, 0, 0]); + Services.cookies.removeAll(); // Force the channel URI to be used when determining the originating URI of // the channel. - // test with third party cookies blocked + var httpchannel1 = channel1.QueryInterface(Ci.nsIHttpChannelInternal); + var httpchannel2 = channel2.QueryInterface(Ci.nsIHttpChannelInternal); + httpchannel1.forceAllowThirdPartyCookie = true; + httpchannel2.forceAllowThirdPartyCookie = true; // test with cookies enabled - { - Services.prefs.setIntPref("network.cookie.cookieBehavior", 0); - - let channel1 = NetUtil.newChannel({uri: uri1, loadUsingSystemPrincipal: true}); - let httpchannel1 = channel1.QueryInterface(Ci.nsIHttpChannelInternal); - httpchannel1.forceAllowThirdPartyCookie = true; - - let channel2 = NetUtil.newChannel({uri: uri2, loadUsingSystemPrincipal: true}); - let httpchannel2 = channel2.QueryInterface(Ci.nsIHttpChannelInternal); - httpchannel2.forceAllowThirdPartyCookie = true; - - do_set_cookies(uri1, channel1, true, [1, 2, 3, 4]); - Services.cookies.removeAll(); - do_set_cookies(uri1, channel2, true, [1, 2, 3, 4]); - Services.cookies.removeAll(); - } + Services.prefs.setIntPref("network.cookie.cookieBehavior", 0); + do_set_cookies(uri1, channel1, true, [1, 2, 3, 4]); + Services.cookies.removeAll(); + do_set_cookies(uri1, channel2, true, [1, 2, 3, 4]); + Services.cookies.removeAll(); // test with third party cookies blocked - { - Services.prefs.setIntPref("network.cookie.cookieBehavior", 1); - - let channel1 = NetUtil.newChannel({uri: uri1, loadUsingSystemPrincipal: true}); - let httpchannel1 = channel1.QueryInterface(Ci.nsIHttpChannelInternal); - httpchannel1.forceAllowThirdPartyCookie = true; - - let channel2 = NetUtil.newChannel({uri: uri2, loadUsingSystemPrincipal: true}); - let httpchannel2 = channel2.QueryInterface(Ci.nsIHttpChannelInternal); - httpchannel2.forceAllowThirdPartyCookie = true; - - do_set_cookies(uri1, channel1, true, [0, 1, 1, 2]); - Services.cookies.removeAll(); - do_set_cookies(uri1, channel2, true, [0, 0, 0, 0]); - Services.cookies.removeAll(); - } + Services.prefs.setIntPref("network.cookie.cookieBehavior", 1); + do_set_cookies(uri1, channel1, true, [0, 1, 1, 2]); + Services.cookies.removeAll(); + do_set_cookies(uri1, channel2, true, [0, 0, 0, 0]); + Services.cookies.removeAll(); // test with third party cookies limited - { - Services.prefs.setIntPref("network.cookie.cookieBehavior", 3); - - let channel1 = NetUtil.newChannel({uri: uri1, loadUsingSystemPrincipal: true}); - let httpchannel1 = channel1.QueryInterface(Ci.nsIHttpChannelInternal); - httpchannel1.forceAllowThirdPartyCookie = true; - - let channel2 = NetUtil.newChannel({uri: uri2, loadUsingSystemPrincipal: true}); - let httpchannel2 = channel2.QueryInterface(Ci.nsIHttpChannelInternal); - httpchannel2.forceAllowThirdPartyCookie = true; - - do_set_cookies(uri1, channel1, true, [0, 1, 2, 3]); - Services.cookies.removeAll(); - do_set_cookies(uri1, channel2, true, [0, 0, 0, 0]); - Services.cookies.removeAll(); - do_set_single_http_cookie(uri1, channel1, 1); - do_set_cookies(uri1, channel2, true, [2, 3, 4, 5]); - Services.cookies.removeAll(); - } + Services.prefs.setIntPref("network.cookie.cookieBehavior", 3); + do_set_cookies(uri1, channel1, true, [0, 1, 2, 3]); + Services.cookies.removeAll(); + do_set_cookies(uri1, channel2, true, [0, 0, 0, 0]); + Services.cookies.removeAll(); + do_set_single_http_cookie(uri1, channel1, 1); + do_set_cookies(uri1, channel2, true, [2, 3, 4, 5]); + Services.cookies.removeAll(); } diff --git a/ipc/glue/BackgroundUtils.cpp b/ipc/glue/BackgroundUtils.cpp index 12f316533e26..9ce17c186732 100644 --- a/ipc/glue/BackgroundUtils.cpp +++ b/ipc/glue/BackgroundUtils.cpp @@ -12,7 +12,6 @@ #include "mozilla/NullPrincipal.h" #include "mozilla/ipc/PBackgroundSharedTypes.h" #include "mozilla/ipc/URIUtils.h" -#include "mozilla/net/CookieSettings.h" #include "mozilla/net/NeckoChannelParams.h" #include "ExpandedPrincipal.h" #include "nsIScriptSecurityManager.h" @@ -461,14 +460,6 @@ nsresult LoadInfoToLoadInfoArgs(nsILoadInfo* aLoadInfo, nsAutoString cspNonce; Unused << NS_WARN_IF(NS_FAILED(aLoadInfo->GetCspNonce(cspNonce))); - nsCOMPtr cookieSettings; - rv = aLoadInfo->GetCookieSettings(getter_AddRefs(cookieSettings)); - NS_ENSURE_SUCCESS(rv, rv); - - CookieSettingsArgs cookieSettingsArgs; - static_cast(cookieSettings.get()) - ->Serialize(cookieSettingsArgs); - *aOptionalLoadInfoArgs = LoadInfoArgs( loadingPrincipalInfo, triggeringPrincipalInfo, principalToInheritInfo, sandboxedLoadingPrincipalInfo, topLevelPrincipalInfo, @@ -499,7 +490,7 @@ nsresult LoadInfoToLoadInfoArgs(nsILoadInfo* aLoadInfo, aLoadInfo->GetDocumentHasUserInteracted(), aLoadInfo->GetDocumentHasLoaded(), cspNonce, aLoadInfo->GetIsFromProcessingFrameAttributes(), - aLoadInfo->GetOpenerPolicy(), cookieSettingsArgs); + aLoadInfo->GetOpenerPolicy()); return NS_OK; } @@ -628,15 +619,11 @@ nsresult LoadInfoArgsToLoadInfo( loadInfoArgs.controller().get_IPCServiceWorkerDescriptor())); } - nsCOMPtr cookieSettings; - CookieSettings::Deserialize(loadInfoArgs.cookieSettings(), - getter_AddRefs(cookieSettings)); - RefPtr loadInfo = new mozilla::LoadInfo( loadingPrincipal, triggeringPrincipal, principalToInherit, sandboxedLoadingPrincipal, topLevelPrincipal, - topLevelStorageAreaPrincipal, resultPrincipalURI, cookieSettings, - clientInfo, reservedClientInfo, initialClientInfo, controller, + topLevelStorageAreaPrincipal, resultPrincipalURI, clientInfo, + reservedClientInfo, initialClientInfo, controller, loadInfoArgs.securityFlags(), loadInfoArgs.contentPolicyType(), static_cast(loadInfoArgs.tainting()), loadInfoArgs.upgradeInsecureRequests(), @@ -679,7 +666,7 @@ void LoadInfoToParentLoadInfoForwarder( false, // serviceWorkerTaintingSynthesized false, // documentHasUserInteracted false, // documentHasLoaded - nsILoadInfo::OPENER_POLICY_NULL, void_t()); + nsILoadInfo::OPENER_POLICY_NULL); return; } @@ -695,23 +682,11 @@ void LoadInfoToParentLoadInfoForwarder( nsILoadInfo::CrossOriginOpenerPolicy openerPolicy = aLoadInfo->GetOpenerPolicy(); - OptionalCookieSettingsArgs cookieSettingsArgs; - - nsCOMPtr cookieSettings; - nsresult rv = aLoadInfo->GetCookieSettings(getter_AddRefs(cookieSettings)); - if (NS_SUCCEEDED(rv) && cookieSettings) { - CookieSettingsArgs args; - static_cast(cookieSettings.get())->Serialize(args); - cookieSettingsArgs = args; - } else { - cookieSettingsArgs = void_t(); - } - *aForwarderArgsOut = ParentLoadInfoForwarderArgs( aLoadInfo->GetAllowInsecureRedirectToDataURI(), ipcController, tainting, aLoadInfo->GetServiceWorkerTaintingSynthesized(), aLoadInfo->GetDocumentHasUserInteracted(), - aLoadInfo->GetDocumentHasLoaded(), openerPolicy, cookieSettingsArgs); + aLoadInfo->GetDocumentHasLoaded(), openerPolicy); } nsresult MergeParentLoadInfoForwarder( @@ -748,19 +723,6 @@ nsresult MergeParentLoadInfoForwarder( MOZ_ALWAYS_SUCCEEDS( aLoadInfo->SetDocumentHasLoaded(aForwarderArgs.documentHasLoaded())); - const OptionalCookieSettingsArgs& cookieSettingsArgs = - aForwarderArgs.cookieSettings(); - if (cookieSettingsArgs.type() != OptionalCookieSettingsArgs::Tvoid_t) { - const CookieSettingsArgs& args = - cookieSettingsArgs.get_CookieSettingsArgs(); - - nsCOMPtr cookieSettings; - nsresult rv = aLoadInfo->GetCookieSettings(getter_AddRefs(cookieSettings)); - if (NS_SUCCEEDED(rv) && cookieSettings) { - static_cast(cookieSettings.get())->Merge(args); - } - } - return NS_OK; } diff --git a/modules/libpref/init/StaticPrefList.h b/modules/libpref/init/StaticPrefList.h index c9d0b6f95e3c..a05443a3dc8f 100644 --- a/modules/libpref/init/StaticPrefList.h +++ b/modules/libpref/init/StaticPrefList.h @@ -1739,14 +1739,6 @@ VARCACHE_PREF( bool, true ) -// Allow CookieSettings to be unblocked for channels without a document. -// This is for testing only. -VARCACHE_PREF( - "network.cookieSettings.unblocked_for_testing", - network_cookieSettings_unblocked_for_testing, - bool, false -) - VARCACHE_PREF( "network.predictor.enable-hover-on-ssl", network_predictor_enable_hover_on_ssl, diff --git a/netwerk/base/LoadInfo.cpp b/netwerk/base/LoadInfo.cpp index 013ab5604e94..aeac78962c49 100644 --- a/netwerk/base/LoadInfo.cpp +++ b/netwerk/base/LoadInfo.cpp @@ -13,17 +13,13 @@ #include "mozilla/dom/TabChild.h" #include "mozilla/dom/ToJSValue.h" #include "mozilla/dom/BrowsingContext.h" -#include "mozilla/net/CookieSettings.h" #include "mozilla/NullPrincipal.h" -#include "mozilla/StaticPrefs.h" #include "mozIThirdPartyUtil.h" #include "nsFrameLoader.h" #include "nsFrameLoaderOwner.h" #include "nsIContentSecurityPolicy.h" #include "nsIDocShell.h" #include "mozilla/dom/Document.h" -#include "nsCookiePermission.h" -#include "nsICookieService.h" #include "nsIInterfaceRequestorUtils.h" #include "nsISupportsImpl.h" #include "nsISupportsUtils.h" @@ -209,10 +205,6 @@ LoadInfo::LoadInfo( } } } - - // Let's inherit the cookie behavior and permission from the parent - // document. - mCookieSettings = aLoadingContext->OwnerDoc()->CookieSettings(); } mInnerWindowID = aLoadingContext->OwnerDoc()->InnerWindowID(); @@ -282,17 +274,6 @@ LoadInfo::LoadInfo( } } - // Create a new CookieSettings for SharedWorkers and ServiceWorkers because - // they cannot inherit it from other contexts: - // - ServiceWorkers does not belong to any windows. - // - SharedWorkers belong to many windows which could have different - // CookieSettings objects. - if (!mCookieSettings && - (aContentPolicyType == nsIContentPolicy::TYPE_INTERNAL_SHARED_WORKER || - aContentPolicyType == nsIContentPolicy::TYPE_INTERNAL_SERVICE_WORKER)) { - mCookieSettings = CookieSettings::Create(); - } - // If CSP requires SRI (require-sri-for), then store that information // in the loadInfo so we can enforce SRI before loading the subresource. if (!mEnforceSRI) { @@ -445,11 +426,6 @@ LoadInfo::LoadInfo(nsPIDOMWindowOuter* aOuterWindow, "chrome docshell shouldn't have mPrivateBrowsingId set."); } #endif - - // Let's take the current cookie behavior and current cookie permission - // for the documents' loadInfo. Note that for any other loadInfos, - // cookieBehavior will be BEHAVIOR_REJECT for security reasons. - mCookieSettings = CookieSettings::Create(); } LoadInfo::LoadInfo(const LoadInfo& rhs) @@ -460,7 +436,6 @@ LoadInfo::LoadInfo(const LoadInfo& rhs) mTopLevelPrincipal(rhs.mTopLevelPrincipal), mTopLevelStorageAreaPrincipal(rhs.mTopLevelStorageAreaPrincipal), mResultPrincipalURI(rhs.mResultPrincipalURI), - mCookieSettings(rhs.mCookieSettings), mClientInfo(rhs.mClientInfo), // mReservedClientSource must be handled specially during redirect // mReservedClientInfo must be handled specially during redirect @@ -519,7 +494,7 @@ LoadInfo::LoadInfo( nsIPrincipal* aPrincipalToInherit, nsIPrincipal* aSandboxedLoadingPrincipal, nsIPrincipal* aTopLevelPrincipal, nsIPrincipal* aTopLevelStorageAreaPrincipal, nsIURI* aResultPrincipalURI, - nsICookieSettings* aCookieSettings, const Maybe& aClientInfo, + const Maybe& aClientInfo, const Maybe& aReservedClientInfo, const Maybe& aInitialClientInfo, const Maybe& aController, @@ -551,7 +526,6 @@ LoadInfo::LoadInfo( mTopLevelPrincipal(aTopLevelPrincipal), mTopLevelStorageAreaPrincipal(aTopLevelStorageAreaPrincipal), mResultPrincipalURI(aResultPrincipalURI), - mCookieSettings(aCookieSettings), mClientInfo(aClientInfo), mReservedClientInfo(aReservedClientInfo), mInitialClientInfo(aInitialClientInfo), @@ -797,21 +771,6 @@ LoadInfo::GetCookiePolicy(uint32_t* aResult) { return NS_OK; } -NS_IMETHODIMP -LoadInfo::GetCookieSettings(nsICookieSettings** aCookieSettings) { - if (!mCookieSettings) { - if (StaticPrefs::network_cookieSettings_unblocked_for_testing()) { - mCookieSettings = CookieSettings::Create(); - } else { - mCookieSettings = CookieSettings::CreateBlockingAll(); - } - } - - nsCOMPtr cookieSettings = mCookieSettings; - cookieSettings.forget(aCookieSettings); - return NS_OK; -} - void LoadInfo::SetIncludeCookiesSecFlag() { MOZ_ASSERT((mSecurityFlags & sCookiePolicyMask) == nsILoadInfo::SEC_COOKIES_DEFAULT); diff --git a/netwerk/base/LoadInfo.h b/netwerk/base/LoadInfo.h index 98dba60ac0b7..bbab1e296d9a 100644 --- a/netwerk/base/LoadInfo.h +++ b/netwerk/base/LoadInfo.h @@ -19,7 +19,6 @@ #include "mozilla/dom/ClientInfo.h" #include "mozilla/dom/ServiceWorkerDescriptor.h" -class nsICookieSettings; class nsINode; class nsPIDOMWindowOuter; @@ -71,7 +70,6 @@ class LoadInfo final : public nsILoadInfo { // create an exact copy of the loadinfo already_AddRefed Clone() const; - // hands off!!! don't use CloneWithNewSecFlags unless you know // exactly what you are doing - it should only be used within // nsBaseChannel::Redirect() @@ -98,7 +96,7 @@ class LoadInfo final : public nsILoadInfo { nsIPrincipal* aSandboxedLoadingPrincipal, nsIPrincipal* aTopLevelPrincipal, nsIPrincipal* aTopLevelStorageAreaPrincipal, - nsIURI* aResultPrincipalURI, nsICookieSettings* aCookieSettings, + nsIURI* aResultPrincipalURI, const Maybe& aClientInfo, const Maybe& aReservedClientInfo, const Maybe& aInitialClientInfo, @@ -157,7 +155,6 @@ class LoadInfo final : public nsILoadInfo { nsCOMPtr mTopLevelStorageAreaPrincipal; nsCOMPtr mResultPrincipalURI; nsCOMPtr mCSPEventListener; - nsCOMPtr mCookieSettings; Maybe mClientInfo; UniquePtr mReservedClientSource; diff --git a/netwerk/base/nsILoadInfo.idl b/netwerk/base/nsILoadInfo.idl index 78c66d455b5e..53fd149dcf8e 100644 --- a/netwerk/base/nsILoadInfo.idl +++ b/netwerk/base/nsILoadInfo.idl @@ -8,7 +8,6 @@ #include "nsIContentPolicy.idl" interface nsIChannel; -interface nsICookieSettings; interface nsICSPEventListener; interface nsINode; interface nsIPrincipal; @@ -427,12 +426,6 @@ interface nsILoadInfo : nsISupports */ [infallible] readonly attribute unsigned long cookiePolicy; - /** - * The cookie settings inherited from the top-level document's loadInfo. - * It cannot be null. - */ - readonly attribute nsICookieSettings cookieSettings; - /** * If forceInheritPrincipal is true, the data coming from the channel should * inherit its principal, even when the data is loaded over http:// or another diff --git a/netwerk/cookie/CookieSettings.cpp b/netwerk/cookie/CookieSettings.cpp deleted file mode 100644 index 01d07744909d..000000000000 --- a/netwerk/cookie/CookieSettings.cpp +++ /dev/null @@ -1,206 +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 "mozilla/net/CookieSettings.h" -#include "mozilla/Unused.h" -#include "nsGlobalWindowInner.h" -#include "nsPermission.h" -#include "nsPermissionManager.h" - -namespace mozilla { -namespace net { - -namespace { - -class PermissionComparator { - public: - bool Equals(nsIPermission* aA, nsIPermission* aB) const { - nsCOMPtr principalA; - nsresult rv = aA->GetPrincipal(getter_AddRefs(principalA)); - if (NS_WARN_IF(NS_FAILED(rv))) { - return false; - } - - nsCOMPtr principalB; - rv = aB->GetPrincipal(getter_AddRefs(principalB)); - if (NS_WARN_IF(NS_FAILED(rv))) { - return false; - } - - bool equals = false; - rv = principalA->Equals(principalB, &equals); - if (NS_WARN_IF(NS_FAILED(rv))) { - return false; - } - - return equals; - } -}; - -} // namespace - -// static -already_AddRefed CookieSettings::CreateBlockingAll() { - RefPtr cookieSettings = - new CookieSettings(nsICookieService::BEHAVIOR_REJECT, eFixed); - return cookieSettings.forget(); -} - -// static -already_AddRefed CookieSettings::Create() { - RefPtr cookieSettings = new CookieSettings( - StaticPrefs::network_cookie_cookieBehavior(), eProgressive); - return cookieSettings.forget(); -} - -CookieSettings::CookieSettings(uint32_t aCookieBehavior, State aState) - : mCookieBehavior(aCookieBehavior), mState(aState) {} - -CookieSettings::~CookieSettings() = default; - -NS_IMETHODIMP -CookieSettings::GetCookieBehavior(uint32_t* aCookieBehavior) { - *aCookieBehavior = mCookieBehavior; - return NS_OK; -} - -NS_IMETHODIMP -CookieSettings::CookiePermission(nsIPrincipal* aPrincipal, - uint32_t* aCookiePermission) { - NS_ENSURE_ARG_POINTER(aPrincipal); - NS_ENSURE_ARG_POINTER(aCookiePermission); - - *aCookiePermission = nsIPermissionManager::UNKNOWN_ACTION; - - nsresult rv; - - // Let's see if we know this permission. - for (const RefPtr& permission : mCookiePermissions) { - bool match = false; - rv = permission->Matches(aPrincipal, false, &match); - if (NS_WARN_IF(NS_FAILED(rv)) || !match) { - continue; - } - - rv = permission->GetCapability(aCookiePermission); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - - return NS_OK; - } - - // Let's ask the permission manager. - nsPermissionManager* pm = nsPermissionManager::GetInstance(); - if (NS_WARN_IF(!pm)) { - return NS_ERROR_FAILURE; - } - - rv = pm->TestPermissionFromPrincipal(aPrincipal, NS_LITERAL_CSTRING("cookie"), - aCookiePermission); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - - // Let's store the permission, also if the result is UNKNOWN in order to avoid - // race conditions. - - nsCOMPtr permission = nsPermission::Create( - aPrincipal, NS_LITERAL_CSTRING("cookie"), *aCookiePermission, 0, 0); - if (permission) { - mCookiePermissions.AppendElement(permission); - } - - return NS_OK; -} - -void CookieSettings::Serialize(CookieSettingsArgs& aData) { - aData.isFixed() = mState == eFixed; - aData.cookieBehavior() = mCookieBehavior; - - for (const RefPtr& permission : mCookiePermissions) { - nsCOMPtr principal; - nsresult rv = permission->GetPrincipal(getter_AddRefs(principal)); - if (NS_WARN_IF(NS_FAILED(rv))) { - continue; - } - - PrincipalInfo principalInfo; - rv = PrincipalToPrincipalInfo(principal, &principalInfo); - if (NS_WARN_IF(NS_FAILED(rv))) { - continue; - } - - uint32_t cookiePermission = 0; - rv = permission->GetCapability(&cookiePermission); - if (NS_WARN_IF(NS_FAILED(rv))) { - continue; - } - - aData.cookiePermissions().AppendElement( - CookiePermissionData(principalInfo, cookiePermission)); - } -} - -/* static */ void CookieSettings::Deserialize( - const CookieSettingsArgs& aData, nsICookieSettings** aCookieSettings) { - CookiePermissionList list; - for (const CookiePermissionData& data : aData.cookiePermissions()) { - nsCOMPtr principal = - PrincipalInfoToPrincipal(data.principalInfo()); - if (NS_WARN_IF(!principal)) { - continue; - } - - nsCOMPtr permission = nsPermission::Create( - principal, NS_LITERAL_CSTRING("cookie"), data.cookiePermission(), 0, 0); - if (NS_WARN_IF(!permission)) { - continue; - } - - list.AppendElement(permission); - } - - RefPtr cookieSettings = new CookieSettings( - aData.cookieBehavior(), aData.isFixed() ? eFixed : eProgressive); - - cookieSettings->mCookiePermissions.SwapElements(list); - - cookieSettings.forget(aCookieSettings); -} - -void CookieSettings::Merge(const CookieSettingsArgs& aData) { - MOZ_ASSERT(mCookieBehavior == aData.cookieBehavior()); - - if (mState == eFixed) { - return; - } - - PermissionComparator comparator; - - for (const CookiePermissionData& data : aData.cookiePermissions()) { - nsCOMPtr principal = - PrincipalInfoToPrincipal(data.principalInfo()); - if (NS_WARN_IF(!principal)) { - continue; - } - - nsCOMPtr permission = nsPermission::Create( - principal, NS_LITERAL_CSTRING("cookie"), data.cookiePermission(), 0, 0); - if (NS_WARN_IF(!permission)) { - continue; - } - - if (!mCookiePermissions.Contains(permission, comparator)) { - mCookiePermissions.AppendElement(permission); - } - } -} - -NS_IMPL_ISUPPORTS(CookieSettings, nsICookieSettings) - -} // namespace net -} // namespace mozilla diff --git a/netwerk/cookie/CookieSettings.h b/netwerk/cookie/CookieSettings.h deleted file mode 100644 index b0d3eae971c3..000000000000 --- a/netwerk/cookie/CookieSettings.h +++ /dev/null @@ -1,63 +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_net_CookieSettings_h -#define mozilla_net_CookieSettings_h - -#include "nsICookieSettings.h" -#include "nsDataHashtable.h" - -class nsIPermission; - -namespace mozilla { -namespace net { - -class CookieSettingsArgs; - -/** - * Class that provides an nsICookieSettings implementation. - */ -class CookieSettings final : public nsICookieSettings { - public: - typedef nsTArray> CookiePermissionList; - - NS_DECL_ISUPPORTS - NS_DECL_NSICOOKIESETTINGS - - static already_AddRefed CreateBlockingAll(); - - static already_AddRefed Create(); - - void Serialize(CookieSettingsArgs& aData); - - static void Deserialize(const CookieSettingsArgs& aData, - nsICookieSettings** aCookieSettings); - - void Merge(const CookieSettingsArgs& aData); - - private: - enum State { - // No cookie permissions are allowed to be stored in this object. - eFixed, - - // Cookie permissions can be stored in case they are unknown when they are - // asked or when they are sent from the parent process. - eProgressive, - }; - - CookieSettings(uint32_t aCookieBehavior, State aState); - ~CookieSettings(); - - uint32_t mCookieBehavior; - CookiePermissionList mCookiePermissions; - - State mState; -}; - -} // namespace net -} // namespace mozilla - -#endif // mozilla_net_CookieSettings_h diff --git a/netwerk/cookie/moz.build b/netwerk/cookie/moz.build index 40c37e19d190..96a406b14a83 100644 --- a/netwerk/cookie/moz.build +++ b/netwerk/cookie/moz.build @@ -14,7 +14,6 @@ XPIDL_SOURCES += [ 'nsICookieManager.idl', 'nsICookiePermission.idl', 'nsICookieService.idl', - 'nsICookieSettings.idl', ] XPIDL_MODULE = 'necko_cookie' @@ -23,13 +22,11 @@ if CONFIG['NECKO_COOKIES']: EXPORTS.mozilla.net = [ 'CookieServiceChild.h', 'CookieServiceParent.h', - 'CookieSettings.h', 'nsCookieKey.h', ] UNIFIED_SOURCES += [ 'CookieServiceChild.cpp', 'CookieServiceParent.cpp', - 'CookieSettings.cpp', 'nsCookie.cpp', ] # nsCookieService.cpp can't be unified because of symbol conflicts @@ -37,7 +34,6 @@ if CONFIG['NECKO_COOKIES']: 'nsCookieService.cpp', ] LOCAL_INCLUDES += [ - '/extensions/cookie', '/intl/uconv', ] diff --git a/netwerk/cookie/nsICookieSettings.idl b/netwerk/cookie/nsICookieSettings.idl deleted file mode 100644 index 2dfa1396be31..000000000000 --- a/netwerk/cookie/nsICookieSettings.idl +++ /dev/null @@ -1,30 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * vim: ft=cpp tw=78 sw=2 et ts=2 sts=2 cin - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "nsISupports.idl" - -interface nsIPrincipal; - -/** - * Cookie settings for top-level documents. - */ -[builtinclass, uuid(3ec40331-7cf0-4b71-ba2a-2265aab8f6bc)] -interface nsICookieSettings : nsISupports -{ - /** - * CookieBehavior at the loading of the document. Any other loadInfo - * inherits it from its document's loadInfo. If there is not a document - * involved, cookieBehavior is reject. - */ - [infallible] readonly attribute unsigned long cookieBehavior; - - /** - * CookiePermission at the loading of the document for a particular - * principal. It returns the same cookiePermission also in case it changes - * during the life-time of the top document. - */ - unsigned long cookiePermission(in nsIPrincipal aPrincipal); -}; diff --git a/netwerk/cookie/test/browser/browser.ini b/netwerk/cookie/test/browser/browser.ini index adf1d6193cdb..342e145789f1 100644 --- a/netwerk/cookie/test/browser/browser.ini +++ b/netwerk/cookie/test/browser/browser.ini @@ -1,13 +1,5 @@ [DEFAULT] support-files = file_empty.html - file_empty.js - head.js -[browser_broadcastChannel.js] -[browser_domCache.js] -[browser_indexedDB.js] [browser_originattributes.js] -[browser_storage.js] -[browser_serviceWorker.js] -[browser_sharedWorker.js] diff --git a/netwerk/cookie/test/browser/browser_broadcastChannel.js b/netwerk/cookie/test/browser/browser_broadcastChannel.js deleted file mode 100644 index 33c340b299e0..000000000000 --- a/netwerk/cookie/test/browser/browser_broadcastChannel.js +++ /dev/null @@ -1,77 +0,0 @@ -// BroadcastChannel is not considered part of CookieJar. It's not allowed to -// communicate with other windows with different cookie settings. - -CookiePolicyHelper.runTest("BroadcastChannel", { - cookieJarAccessAllowed: async w => { - new w.BroadcastChannel("hello"); - ok(true, "BroadcastChannel be used"); - }, - - cookieJarAccessDenied: async w => { - try { - new w.BroadcastChannel("hello"); - ok(false, "BroadcastChannel cannot be used!"); - } catch (e) { - ok(true, "BroadcastChannel cannot be used!"); - is(e.name, "SecurityError", "We want a security error message."); - } - } -}); - -CookiePolicyHelper.runTest("BroadcastChannel in workers", { - cookieJarAccessAllowed: async w => { - function nonBlockingCode() { - new BroadcastChannel("hello"); - postMessage(true); - } - - let blob = new w.Blob([nonBlockingCode.toString() + "; nonBlockingCode();"]); - ok(blob, "Blob has been created"); - - let blobURL = w.URL.createObjectURL(blob); - ok(blobURL, "Blob URL has been created"); - - let worker = new w.Worker(blobURL); - ok(worker, "Worker has been created"); - - await new w.Promise((resolve, reject) => { - worker.onmessage = function(e) { - if (e) { - resolve(); - } else { - reject(); - } - }; - }); - }, - - cookieJarAccessDenied: async w => { - function blockingCode() { - try { - new BroadcastChannel("hello"); - postMessage(false); - } catch (e) { - postMessage(e.name == "SecurityError"); - } - } - - let blob = new w.Blob([blockingCode.toString() + "; blockingCode();"]); - ok(blob, "Blob has been created"); - - let blobURL = w.URL.createObjectURL(blob); - ok(blobURL, "Blob URL has been created"); - - let worker = new w.Worker(blobURL); - ok(worker, "Worker has been created"); - - await new w.Promise((resolve, reject) => { - worker.onmessage = function(e) { - if (e) { - resolve(); - } else { - reject(); - } - }; - }); - } -}); diff --git a/netwerk/cookie/test/browser/browser_domCache.js b/netwerk/cookie/test/browser/browser_domCache.js deleted file mode 100644 index 89ada5ed5a9a..000000000000 --- a/netwerk/cookie/test/browser/browser_domCache.js +++ /dev/null @@ -1,13 +0,0 @@ -CookiePolicyHelper.runTest("DOM Cache", { - cookieJarAccessAllowed: async w => { - await w.caches.open("wow").then( - _ => { ok(true, "DOM Cache can be used!"); }, - _ => { ok(false, "DOM Cache can be used!"); }); - }, - - cookieJarAccessDenied: async w => { - await w.caches.open("wow").then( - _ => { ok(false, "DOM Cache cannot be used!"); }, - _ => { ok(true, "DOM Cache cannot be used!"); }); - }, -}); diff --git a/netwerk/cookie/test/browser/browser_indexedDB.js b/netwerk/cookie/test/browser/browser_indexedDB.js deleted file mode 100644 index e672b9b7a2f2..000000000000 --- a/netwerk/cookie/test/browser/browser_indexedDB.js +++ /dev/null @@ -1,82 +0,0 @@ -CookiePolicyHelper.runTest("IndexedDB", { - cookieJarAccessAllowed: async w => { - w.indexedDB.open("test", "1"); - ok(true, "IDB should be allowed"); - }, - - cookieJarAccessDenied: async w => { - try { - w.indexedDB.open("test", "1"); - ok(false, "IDB should be blocked"); - } catch (e) { - ok(true, "IDB should be blocked"); - is(e.name, "SecurityError", "We want a security error message."); - } - }, -}); - -CookiePolicyHelper.runTest("IndexedDB in workers", { - cookieJarAccessAllowed: async w => { - function nonBlockCode() { - indexedDB.open("test", "1"); - postMessage(true); - } - - let blob = new w.Blob([nonBlockCode.toString() + "; nonBlockCode();"]); - ok(blob, "Blob has been created"); - - let blobURL = w.URL.createObjectURL(blob); - ok(blobURL, "Blob URL has been created"); - - let worker = new w.Worker(blobURL); - ok(worker, "Worker has been created"); - - await new w.Promise((resolve, reject) => { - worker.onmessage = function(e) { - if (e.data) { - resolve(); - } else { - reject(); - } - }; - - worker.onerror = function(e) { - reject(); - }; - }); - }, - - cookieJarAccessDenied: async w => { - function blockCode() { - try { - indexedDB.open("test", "1"); - postMessage(false); - } catch (e) { - postMessage(e.name == "SecurityError"); - } - } - - let blob = new w.Blob([blockCode.toString() + "; blockCode();"]); - ok(blob, "Blob has been created"); - - let blobURL = w.URL.createObjectURL(blob); - ok(blobURL, "Blob URL has been created"); - - let worker = new w.Worker(blobURL); - ok(worker, "Worker has been created"); - - await new w.Promise((resolve, reject) => { - worker.onmessage = function(e) { - if (e.data) { - resolve(); - } else { - reject(); - } - }; - - worker.onerror = function(e) { - reject(); - }; - }); - }, -}); diff --git a/netwerk/cookie/test/browser/browser_serviceWorker.js b/netwerk/cookie/test/browser/browser_serviceWorker.js deleted file mode 100644 index fd6f021450b7..000000000000 --- a/netwerk/cookie/test/browser/browser_serviceWorker.js +++ /dev/null @@ -1,24 +0,0 @@ -CookiePolicyHelper.runTest("ServiceWorker", { - prefs: [ - ["dom.serviceWorkers.exemptFromPerDomainMax", true], - ["dom.ipc.processCount", 1], - ["dom.serviceWorkers.enabled", true], - ["dom.serviceWorkers.testing.enabled", true], - ], - - cookieJarAccessAllowed: async w => { - await w.navigator.serviceWorker.register("file_empty.js").then( - reg => { ok(true, "ServiceWorker can be used!"); return reg; }, - _ => { ok(false, "ServiceWorker cannot be used! " + _); }).then( - reg => reg.unregister(), - _ => { ok(false, "unregister failed"); }). - catch(e => ok(false, "Promise rejected: " + e)); - }, - - cookieJarAccessDenied: async w => { - await w.navigator.serviceWorker.register("file_empty.js").then( - _ => { ok(false, "ServiceWorker cannot be used!"); }, - _ => { ok(true, "ServiceWorker cannot be used!"); }). - catch(e => ok(false, "Promise rejected: " + e)); - }, -}); diff --git a/netwerk/cookie/test/browser/browser_sharedWorker.js b/netwerk/cookie/test/browser/browser_sharedWorker.js deleted file mode 100644 index f8b08e9d4b4d..000000000000 --- a/netwerk/cookie/test/browser/browser_sharedWorker.js +++ /dev/null @@ -1,16 +0,0 @@ -CookiePolicyHelper.runTest("SharedWorker", { - cookieJarAccessAllowed: async w => { - new w.SharedWorker("a.js", "foo"); - ok(true, "SharedWorker is allowed"); - }, - - cookieJarAccessDenied: async w => { - try { - new w.SharedWorker("a.js", "foo"); - ok(false, "SharedWorker cannot be used!"); - } catch (e) { - ok(true, "SharedWorker cannot be used!"); - is(e.name, "SecurityError", "We want a security error message."); - } - }, -}); diff --git a/netwerk/cookie/test/browser/browser_storage.js b/netwerk/cookie/test/browser/browser_storage.js deleted file mode 100644 index 510dd457b90d..000000000000 --- a/netwerk/cookie/test/browser/browser_storage.js +++ /dev/null @@ -1,41 +0,0 @@ -CookiePolicyHelper.runTest("SessionStorage", { - cookieJarAccessAllowed: async w => { - try { - w.sessionStorage.foo = 42; - ok(true, "SessionStorage works"); - } catch (e) { - ok(false, "SessionStorage works"); - } - }, - - cookieJarAccessDenied: async w => { - try { - w.sessionStorage.foo = 42; - ok(false, "SessionStorage doesn't work"); - } catch (e) { - ok(true, "SessionStorage doesn't work"); - is(e.name, "SecurityError", "We want a security error message."); - } - }, -}); - -CookiePolicyHelper.runTest("LocalStorage", { - cookieJarAccessAllowed: async w => { - try { - w.localStorage.foo = 42; - ok(true, "LocalStorage works"); - } catch (e) { - ok(false, "LocalStorage works"); - } - }, - - cookieJarAccessDenied: async w => { - try { - w.localStorage.foo = 42; - ok(false, "LocalStorage doesn't work"); - } catch (e) { - ok(true, "LocalStorage doesn't work"); - is(e.name, "TypeError", "We want a security error message."); - } - }, -}); diff --git a/netwerk/cookie/test/browser/file_empty.js b/netwerk/cookie/test/browser/file_empty.js deleted file mode 100644 index 3053583c7616..000000000000 --- a/netwerk/cookie/test/browser/file_empty.js +++ /dev/null @@ -1 +0,0 @@ -/* nothing here */ diff --git a/netwerk/cookie/test/browser/head.js b/netwerk/cookie/test/browser/head.js deleted file mode 100644 index 354776413acf..000000000000 --- a/netwerk/cookie/test/browser/head.js +++ /dev/null @@ -1,173 +0,0 @@ -const BEHAVIOR_ACCEPT = Ci.nsICookieService.BEHAVIOR_ACCEPT; -const BEHAVIOR_REJECT = Ci.nsICookieService.BEHAVIOR_REJECT; - -const PERM_DEFAULT = Ci.nsICookiePermission.ACCESS_DEFAULT; -const PERM_ALLOW = Ci.nsICookiePermission.ACCESS_ALLOW; -const PERM_DENY = Ci.nsICookiePermission.ACCESS_DENY; - -const TEST_DOMAIN = "https://example.com/"; -const TEST_PATH = "browser/netwerk/cookie/test/browser/"; -const TEST_TOP_PAGE = TEST_DOMAIN + TEST_PATH + "file_empty.html"; - -// Helper to eval() provided cookieJarAccessAllowed and cookieJarAccessDenied -// toString()ed optionally async function in freshly created tabs with -// BEHAVIOR_ACCEPT and BEHAVIOR_REJECT configured, respectively, in a number of -// permutations. This includes verifying that changing the permission while the -// page is open still results in the state of the permission when the -// document/global was created still applying. Code will execute in the -// ContentTask.spawn frame-script context, use content to access the underlying -// page. -this.CookiePolicyHelper = { - runTest(testName, config) { - // Testing allowed to blocked by cookie behavior - this._createTest(testName, - config.cookieJarAccessAllowed, - config.cookieJarAccessDenied, - config.cleanup, - config.prefs, - { - fromBehavior: BEHAVIOR_ACCEPT, - toBehavior: BEHAVIOR_REJECT, - fromPermission: PERM_DEFAULT, - toPermission: PERM_DEFAULT, - }); - - // Testing blocked to allowed by cookie behavior - this._createTest(testName, - config.cookieJarAccessDenied, - config.cookieJarAccessAllowed, - config.cleanup, - config.prefs, - { - fromBehavior: BEHAVIOR_REJECT, - toBehavior: BEHAVIOR_ACCEPT, - fromPermission: PERM_DEFAULT, - toPermission: PERM_DEFAULT, - }); - - // Testing allowed to blocked by cookie permission - this._createTest(testName, - config.cookieJarAccessAllowed, - config.cookieJarAccessDenied, - config.cleanup, - config.prefs, - { - fromBehavior: BEHAVIOR_REJECT, - toBehavior: BEHAVIOR_REJECT, - fromPermission: PERM_ALLOW, - toPermission: PERM_DEFAULT, - }); - - // Testing blocked to allowed by cookie permission - this._createTest(testName, - config.cookieJarAccessDenied, - config.cookieJarAccessAllowed, - config.cleanup, - config.prefs, - { - fromBehavior: BEHAVIOR_ACCEPT, - toBehavior: BEHAVIOR_ACCEPT, - fromPermission: PERM_DENY, - toPermission: PERM_DEFAULT, - }); - }, - - _createTest(testName, goodCb, badCb, cleanupCb, prefs, config) { - add_task(async _ => { - info("Starting " + testName + ": " + config.toSource()); - - await SpecialPowers.flushPrefEnv(); - - if (prefs) { - await SpecialPowers.pushPrefEnv({"set": prefs }); - } - - let uri = Services.io.newURI(TEST_DOMAIN); - - // Let's set the first cookie pref. - Services.perms.add(uri, "cookie", config.fromPermission); - await SpecialPowers.pushPrefEnv({"set": [ - ["network.cookie.cookieBehavior", config.fromBehavior], - ]}); - - // Let's open a tab and load content. - let tab = BrowserTestUtils.addTab(gBrowser, TEST_TOP_PAGE); - gBrowser.selectedTab = tab; - - let browser = gBrowser.getBrowserForTab(tab); - await BrowserTestUtils.browserLoaded(browser); - - // Let's create an iframe. - await ContentTask.spawn(browser, { url: TEST_TOP_PAGE }, - async obj => { - return new content.Promise(resolve => { - let ifr = content.document.createElement('iframe'); - ifr.setAttribute("id", "iframe"); - ifr.src = obj.url; - ifr.onload = resolve; - content.document.body.appendChild(ifr); - }); - }); - - // Let's exec the "good" callback. - info("Executing the test after setting the cookie behavior to " + config.fromBehavior + " and permission to " + config.fromPermission); - await ContentTask.spawn(browser, - { callback: goodCb.toString() }, - async obj => { - let runnableStr = `(() => {return (${obj.callback});})();`; - let runnable = eval(runnableStr); // eslint-disable-line no-eval - await runnable(content); - - let ifr = content.document.getElementById("iframe"); - await runnable(ifr.contentWindow); - }); - - // Now, let's change the cookie settings - Services.perms.add(uri, "cookie", config.toPermission); - await SpecialPowers.pushPrefEnv({"set": [ - ["network.cookie.cookieBehavior", config.toBehavior], - ]}); - - // We still want the good callback to succeed. - info("Executing the test after setting the cookie behavior to " + config.toBehavior + " and permission to " + config.toPermission); - await ContentTask.spawn(browser, - { callback: goodCb.toString() }, - async obj => { - let runnableStr = `(() => {return (${obj.callback});})();`; - let runnable = eval(runnableStr); // eslint-disable-line no-eval - await runnable(content); - - let ifr = content.document.getElementById("iframe"); - await runnable(ifr.contentWindow); - }); - - // Let's close the tab. - BrowserTestUtils.removeTab(tab); - - // Let's open a new tab and load content again. - tab = BrowserTestUtils.addTab(gBrowser, TEST_TOP_PAGE); - gBrowser.selectedTab = tab; - - browser = gBrowser.getBrowserForTab(tab); - await BrowserTestUtils.browserLoaded(browser); - - // Let's exec the "bad" callback. - info("Executing the test in a new tab"); - await ContentTask.spawn(browser, - { callback: badCb.toString() }, - async obj => { - let runnableStr = `(() => {return (${obj.callback});})();`; - let runnable = eval(runnableStr); // eslint-disable-line no-eval - await runnable(content); - }); - - // Let's close the tab. - BrowserTestUtils.removeTab(tab); - - // Cleanup. - await new Promise(resolve => { - Services.clearData.deleteData(Ci.nsIClearDataService.CLEAR_ALL, resolve); - }); - }); - }, -}; diff --git a/netwerk/ipc/NeckoChannelParams.ipdlh b/netwerk/ipc/NeckoChannelParams.ipdlh index a716b57414f9..21b5135abcc6 100644 --- a/netwerk/ipc/NeckoChannelParams.ipdlh +++ b/netwerk/ipc/NeckoChannelParams.ipdlh @@ -27,30 +27,6 @@ using nsILoadInfo::CrossOriginOpenerPolicy from "ipc/IPCMessageUtils.h"; namespace mozilla { namespace net { -//----------------------------------------------------------------------------- -// CookieSettings IPDL structs -//----------------------------------------------------------------------------- - -struct CookiePermissionData -{ - PrincipalInfo principalInfo; - uint32_t cookiePermission; -}; - -struct CookieSettingsArgs -{ - // Copy of the cookie behavior and permissions for the top-level document. - uint32_t cookieBehavior; - CookiePermissionData[] cookiePermissions; - bool isFixed; -}; - -union OptionalCookieSettingsArgs -{ - void_t; - CookieSettingsArgs; -}; - //----------------------------------------------------------------------------- // Preferrer alternative data type //----------------------------------------------------------------------------- @@ -149,8 +125,6 @@ struct LoadInfoArgs nsString cspNonce; bool isFromProcessingFrameAttributes; CrossOriginOpenerPolicy openerPolicy; - - CookieSettingsArgs cookieSettings; }; /** @@ -193,8 +167,6 @@ struct ParentLoadInfoForwarderArgs CrossOriginOpenerPolicy openerPolicy; - OptionalCookieSettingsArgs cookieSettings; - // IMPORTANT: when you add new properites here you must also update // LoadInfoToParentLoadInfoForwarder and MergeParentLoadInfoForwarder // in BackgroundUtils.cpp/.h! diff --git a/toolkit/components/antitracking/AntiTrackingCommon.cpp b/toolkit/components/antitracking/AntiTrackingCommon.cpp index c73faa004d0a..b21adf045c74 100644 --- a/toolkit/components/antitracking/AntiTrackingCommon.cpp +++ b/toolkit/components/antitracking/AntiTrackingCommon.cpp @@ -156,51 +156,57 @@ void CreatePermissionKey(const nsCString& aTrackingOrigin, // This internal method returns ACCESS_DENY if the access is denied, // ACCESS_DEFAULT if unknown, some other access code if granted. -uint32_t CheckCookiePermissionForPrincipal(nsICookieSettings* aCookieSettings, - nsIPrincipal* aPrincipal) { - MOZ_ASSERT(aCookieSettings); - MOZ_ASSERT(aPrincipal); - - uint32_t cookiePermission = nsICookiePermission::ACCESS_DEFAULT; +nsCookieAccess CheckCookiePermissionForPrincipal(nsIPrincipal* aPrincipal) { + nsCookieAccess access = nsICookiePermission::ACCESS_DEFAULT; if (!aPrincipal->GetIsCodebasePrincipal()) { - return cookiePermission; + return access; } - nsresult rv = - aCookieSettings->CookiePermission(aPrincipal, &cookiePermission); + nsCOMPtr cps = nsCookiePermission::GetOrCreate(); + + nsresult rv = cps->CanAccess(aPrincipal, &access); if (NS_WARN_IF(NS_FAILED(rv))) { return nsICookiePermission::ACCESS_DEFAULT; } // If we have a custom cookie permission, let's use it. - return cookiePermission; + return access; } -int32_t CookiesBehavior(Document* aTopLevelDocument, - Document* a3rdPartyDocument) { - MOZ_ASSERT(aTopLevelDocument); - MOZ_ASSERT(a3rdPartyDocument); +// This internal method returns ACCESS_DENY if the access is denied, +// ACCESS_DEFAULT if unknown, some other access code if granted. +nsCookieAccess CheckCookiePermissionForURI(nsIURI* aURI) { + nsCookieAccess access = nsICookiePermission::ACCESS_DEFAULT; + nsCOMPtr cps = nsCookiePermission::GetOrCreate(); + + nsresult rv = cps->CanAccessURI(aURI, &access); + if (NS_WARN_IF(NS_FAILED(rv))) { + return nsICookiePermission::ACCESS_DEFAULT; + } + + // If we have a custom cookie permission, let's use it. + return access; +} + +int32_t CookiesBehavior(nsIPrincipal* aTopLevelPrincipal, + nsIPrincipal* a3rdPartyPrincipal) { // WebExtensions principals always get BEHAVIOR_ACCEPT as cookieBehavior // (See Bug 1406675 for rationale). - if (BasePrincipal::Cast(aTopLevelDocument->NodePrincipal())->AddonPolicy()) { + if (BasePrincipal::Cast(aTopLevelPrincipal)->AddonPolicy()) { return nsICookieService::BEHAVIOR_ACCEPT; } - if (BasePrincipal::Cast(a3rdPartyDocument->NodePrincipal())->AddonPolicy()) { + if (a3rdPartyPrincipal && + BasePrincipal::Cast(a3rdPartyPrincipal)->AddonPolicy()) { return nsICookieService::BEHAVIOR_ACCEPT; } - return a3rdPartyDocument->CookieSettings()->GetCookieBehavior(); + return StaticPrefs::network_cookie_cookieBehavior(); } -int32_t CookiesBehavior(nsILoadInfo* aLoadInfo, - nsIPrincipal* aTopLevelPrincipal, +int32_t CookiesBehavior(nsIPrincipal* aTopLevelPrincipal, nsIURI* a3rdPartyURI) { - MOZ_ASSERT(aLoadInfo); - MOZ_ASSERT(aTopLevelPrincipal); - MOZ_ASSERT(a3rdPartyURI); - // WebExtensions principals always get BEHAVIOR_ACCEPT as cookieBehavior // (See Bug 1406675 for rationale). if (BasePrincipal::Cast(aTopLevelPrincipal)->AddonPolicy()) { @@ -209,30 +215,13 @@ int32_t CookiesBehavior(nsILoadInfo* aLoadInfo, // This is semantically equivalent to the principal having a AddonPolicy(). bool is3rdPartyMozExt = false; - if (NS_SUCCEEDED( + if (a3rdPartyURI && + NS_SUCCEEDED( a3rdPartyURI->SchemeIs("moz-extension", &is3rdPartyMozExt)) && is3rdPartyMozExt) { return nsICookieService::BEHAVIOR_ACCEPT; } - nsCOMPtr cookieSettings; - nsresult rv = aLoadInfo->GetCookieSettings(getter_AddRefs(cookieSettings)); - if (NS_WARN_IF(NS_FAILED(rv))) { - return nsICookieService::BEHAVIOR_REJECT; - } - - return cookieSettings->GetCookieBehavior(); -} - -int32_t CookiesBehavior(nsIPrincipal* aPrincipal) { - MOZ_ASSERT(aPrincipal); - - // WebExtensions principals always get BEHAVIOR_ACCEPT as cookieBehavior - // (See Bug 1406675 for rationale). - if (BasePrincipal::Cast(aPrincipal)->AddonPolicy()) { - return nsICookieService::BEHAVIOR_ACCEPT; - } - return StaticPrefs::network_cookie_cookieBehavior(); } @@ -1077,50 +1066,31 @@ bool AntiTrackingCommon::IsFirstPartyStorageAccessGrantedFor( aURI); nsGlobalWindowInner* innerWindow = nsGlobalWindowInner::Cast(aWindow); - Document* document = innerWindow->GetExtantDoc(); - if (!document) { - LOG(("Our window has no document")); + nsIPrincipal* windowPrincipal = innerWindow->GetPrincipal(); + if (!windowPrincipal) { + LOG(("Our window has no principal")); return false; } - nsGlobalWindowOuter* outerWindow = - nsGlobalWindowOuter::Cast(aWindow->GetOuterWindow()); - if (!outerWindow) { - LOG(("Our window has no outer window")); - return false; + nsIPrincipal* toplevelPrincipal = innerWindow->GetTopLevelPrincipal(); + if (!toplevelPrincipal) { + // We are already the top-level principal. Let's use the window's principal. + LOG( + ("Our inner window lacks a top-level principal, use the window's " + "principal instead")); + toplevelPrincipal = windowPrincipal; } - nsCOMPtr topOuterWindow = outerWindow->GetTop(); - nsGlobalWindowOuter* topWindow = nsGlobalWindowOuter::Cast(topOuterWindow); - if (NS_WARN_IF(!topWindow)) { - LOG(("No top outer window")); - return false; - } + MOZ_ASSERT(toplevelPrincipal); - nsPIDOMWindowInner* topInnerWindow = topWindow->GetCurrentInnerWindow(); - if (NS_WARN_IF(!topInnerWindow)) { - LOG(("No top inner window.")); - return false; - } - - Document* toplevelDocument = topInnerWindow->GetExtantDoc(); - if (!toplevelDocument) { - LOG(("No top level document.")); - return false; - } - - MOZ_ASSERT(toplevelDocument); - - uint32_t cookiePermission = CheckCookiePermissionForPrincipal( - toplevelDocument->CookieSettings(), toplevelDocument->NodePrincipal()); - if (cookiePermission != nsICookiePermission::ACCESS_DEFAULT) { + nsCookieAccess access = CheckCookiePermissionForPrincipal(toplevelPrincipal); + if (access != nsICookiePermission::ACCESS_DEFAULT) { LOG( ("CheckCookiePermissionForPrincipal() returned a non-default access " "code (%d) for top-level window's principal, returning %s", - int(cookiePermission), - cookiePermission != nsICookiePermission::ACCESS_DENY ? "success" - : "failure")); - if (cookiePermission != nsICookiePermission::ACCESS_DENY) { + int(access), + access != nsICookiePermission::ACCESS_DENY ? "success" : "failure")); + if (access != nsICookiePermission::ACCESS_DENY) { return true; } @@ -1129,16 +1099,14 @@ bool AntiTrackingCommon::IsFirstPartyStorageAccessGrantedFor( return false; } - cookiePermission = CheckCookiePermissionForPrincipal( - toplevelDocument->CookieSettings(), document->NodePrincipal()); - if (cookiePermission != nsICookiePermission::ACCESS_DEFAULT) { + access = CheckCookiePermissionForPrincipal(windowPrincipal); + if (access != nsICookiePermission::ACCESS_DEFAULT) { LOG( ("CheckCookiePermissionForPrincipal() returned a non-default access " "code (%d) for window's principal, returning %s", - int(cookiePermission), - cookiePermission != nsICookiePermission::ACCESS_DENY ? "success" - : "failure")); - if (cookiePermission != nsICookiePermission::ACCESS_DENY) { + int(access), + access != nsICookiePermission::ACCESS_DENY ? "success" : "failure")); + if (access != nsICookiePermission::ACCESS_DENY) { return true; } @@ -1147,7 +1115,7 @@ bool AntiTrackingCommon::IsFirstPartyStorageAccessGrantedFor( return false; } - int32_t behavior = CookiesBehavior(toplevelDocument, document); + int32_t behavior = CookiesBehavior(toplevelPrincipal, windowPrincipal); if (behavior == nsICookieService::BEHAVIOR_ACCEPT) { LOG(("The cookie behavior pref mandates accepting all cookies!")); return true; @@ -1226,6 +1194,26 @@ bool AntiTrackingCommon::IsFirstPartyStorageAccessGrantedFor( return false; } + nsGlobalWindowOuter* outerWindow = + nsGlobalWindowOuter::Cast(aWindow->GetOuterWindow()); + if (NS_WARN_IF(!outerWindow)) { + LOG(("No outer window.")); + return false; + } + + nsCOMPtr topOuterWindow = outerWindow->GetTop(); + nsGlobalWindowOuter* topWindow = nsGlobalWindowOuter::Cast(topOuterWindow); + if (NS_WARN_IF(!topWindow)) { + LOG(("No top outer window.")); + return false; + } + + nsPIDOMWindowInner* topInnerWindow = topWindow->GetCurrentInnerWindow(); + if (NS_WARN_IF(!topInnerWindow)) { + LOG(("No top inner window.")); + return false; + } + nsAutoCString type; CreatePermissionKey(trackingOrigin, grantedOrigin, type); @@ -1241,7 +1229,8 @@ bool AntiTrackingCommon::IsFirstPartyStorageAccessGrantedFor( } uint32_t result = 0; - rv = permManager->TestPermissionFromPrincipal(parentPrincipal, type, &result); + rv = permManager->TestPermissionWithoutDefaultsFromPrincipal(parentPrincipal, + type, &result); if (NS_WARN_IF(NS_FAILED(rv))) { LOG(("Failed to test the permission")); return false; @@ -1272,10 +1261,6 @@ bool AntiTrackingCommon::IsFirstPartyStorageAccessGrantedFor( aRejectedReason = &rejectedReason; } - nsIScriptSecurityManager* ssm = - nsScriptSecurityManager::GetScriptSecurityManager(); - MOZ_ASSERT(ssm); - nsCOMPtr channelURI; nsresult rv = NS_GetFinalChannelURI(aChannel, getter_AddRefs(channelURI)); if (NS_FAILED(rv)) { @@ -1311,6 +1296,8 @@ bool AntiTrackingCommon::IsFirstPartyStorageAccessGrantedFor( bool isDocument = false; rv = aChannel->GetIsMainDocumentChannel(&isDocument); if (NS_SUCCEEDED(rv) && isDocument) { + nsIScriptSecurityManager* ssm = + nsScriptSecurityManager::GetScriptSecurityManager(); rv = ssm->GetChannelResultPrincipal(aChannel, getter_AddRefs(toplevelPrincipal)); if (NS_SUCCEEDED(rv)) { @@ -1338,25 +1325,14 @@ bool AntiTrackingCommon::IsFirstPartyStorageAccessGrantedFor( return false; } - nsCOMPtr cookieSettings; - rv = loadInfo->GetCookieSettings(getter_AddRefs(cookieSettings)); - if (NS_WARN_IF(NS_FAILED(rv))) { - LOG( - ("Failed to get the cookie settings from the loadinfo, bail out " - "early")); - return true; - } - - uint32_t cookiePermission = - CheckCookiePermissionForPrincipal(cookieSettings, toplevelPrincipal); - if (cookiePermission != nsICookiePermission::ACCESS_DEFAULT) { + nsCookieAccess access = CheckCookiePermissionForPrincipal(toplevelPrincipal); + if (access != nsICookiePermission::ACCESS_DEFAULT) { LOG( ("CheckCookiePermissionForPrincipal() returned a non-default access " "code (%d) for top-level window's principal, returning %s", - int(cookiePermission), - cookiePermission != nsICookiePermission::ACCESS_DENY ? "success" - : "failure")); - if (cookiePermission != nsICookiePermission::ACCESS_DENY) { + int(access), + access != nsICookiePermission::ACCESS_DENY ? "success" : "failure")); + if (access != nsICookiePermission::ACCESS_DENY) { return true; } @@ -1365,24 +1341,19 @@ bool AntiTrackingCommon::IsFirstPartyStorageAccessGrantedFor( return false; } - nsCOMPtr channelPrincipal; - rv = ssm->GetChannelResultPrincipal(aChannel, - getter_AddRefs(channelPrincipal)); - if (NS_WARN_IF(NS_FAILED(rv))) { + if (NS_WARN_IF(NS_FAILED(rv) || !channelURI)) { LOG(("No channel principal, bail out early")); return false; } - cookiePermission = - CheckCookiePermissionForPrincipal(cookieSettings, channelPrincipal); - if (cookiePermission != nsICookiePermission::ACCESS_DEFAULT) { + access = CheckCookiePermissionForURI(channelURI); + if (access != nsICookiePermission::ACCESS_DEFAULT) { LOG( ("CheckCookiePermissionForPrincipal() returned a non-default access " "code (%d) for channel's principal, returning %s", - int(cookiePermission), - cookiePermission != nsICookiePermission::ACCESS_DENY ? "success" - : "failure")); - if (cookiePermission != nsICookiePermission::ACCESS_DENY) { + int(access), + access != nsICookiePermission::ACCESS_DENY ? "success" : "failure")); + if (access != nsICookiePermission::ACCESS_DENY) { return true; } @@ -1391,12 +1362,7 @@ bool AntiTrackingCommon::IsFirstPartyStorageAccessGrantedFor( return false; } - if (!channelURI) { - LOG(("No channel uri, bail out early")); - return false; - } - - int32_t behavior = CookiesBehavior(loadInfo, toplevelPrincipal, channelURI); + int32_t behavior = CookiesBehavior(toplevelPrincipal, channelURI); if (behavior == nsICookieService::BEHAVIOR_ACCEPT) { LOG(("The cookie behavior pref mandates accepting all cookies!")); return true; @@ -1531,17 +1497,13 @@ bool AntiTrackingCommon::IsFirstPartyStorageAccessGrantedFor( nsIPrincipal* aPrincipal) { MOZ_ASSERT(aPrincipal); - nsCookieAccess access = nsICookiePermission::ACCESS_DEFAULT; - if (aPrincipal->GetIsCodebasePrincipal()) { - nsCOMPtr cps = nsCookiePermission::GetOrCreate(); - Unused << NS_WARN_IF(NS_FAILED(cps->CanAccess(aPrincipal, &access))); - } - + nsCookieAccess access = CheckCookiePermissionForPrincipal(aPrincipal); if (access != nsICookiePermission::ACCESS_DEFAULT) { return access != nsICookiePermission::ACCESS_DENY; } - int32_t behavior = CookiesBehavior(aPrincipal); + int32_t behavior = + CookiesBehavior(aPrincipal, static_cast(nullptr)); return behavior != nsICookieService::BEHAVIOR_REJECT; } @@ -1555,14 +1517,7 @@ bool AntiTrackingCommon::IsFirstPartyStorageAccessGrantedFor( aFirstPartyWindow, _spec), aURI); - Document* parentDocument = - nsGlobalWindowInner::Cast(aFirstPartyWindow)->GetExtantDoc(); - if (NS_WARN_IF(!parentDocument)) { - LOG(("Failed to get the first party window's document")); - return false; - } - - if (parentDocument->CookieSettings()->GetCookieBehavior() != + if (StaticPrefs::network_cookie_cookieBehavior() != nsICookieService::BEHAVIOR_REJECT_TRACKER) { LOG(("Disabled by the pref (%d), bail out early", StaticPrefs::network_cookie_cookieBehavior())); @@ -1579,16 +1534,21 @@ bool AntiTrackingCommon::IsFirstPartyStorageAccessGrantedFor( return true; } - uint32_t cookiePermission = CheckCookiePermissionForPrincipal( - parentDocument->CookieSettings(), parentDocument->NodePrincipal()); - if (cookiePermission != nsICookiePermission::ACCESS_DEFAULT) { + nsCOMPtr parentPrincipal = + nsGlobalWindowInner::Cast(aFirstPartyWindow)->GetPrincipal(); + if (NS_WARN_IF(!parentPrincipal)) { + LOG(("Failed to get the first party window's principal")); + return false; + } + + nsCookieAccess access = CheckCookiePermissionForPrincipal(parentPrincipal); + if (access != nsICookiePermission::ACCESS_DEFAULT) { LOG( ("CheckCookiePermissionForPrincipal() returned a non-default access " "code (%d), returning %s", - int(cookiePermission), - cookiePermission != nsICookiePermission::ACCESS_DENY ? "success" - : "failure")); - return cookiePermission != nsICookiePermission::ACCESS_DENY; + int(access), + access != nsICookiePermission::ACCESS_DENY ? "success" : "failure")); + return access != nsICookiePermission::ACCESS_DENY; } nsAutoCString origin; @@ -1608,8 +1568,8 @@ bool AntiTrackingCommon::IsFirstPartyStorageAccessGrantedFor( } uint32_t result = 0; - rv = permManager->TestPermissionWithoutDefaultsFromPrincipal( - parentDocument->NodePrincipal(), type, &result); + rv = permManager->TestPermissionWithoutDefaultsFromPrincipal(parentPrincipal, + type, &result); if (NS_WARN_IF(NS_FAILED(rv))) { LOG(("Failed to test the permission")); return false; @@ -1617,8 +1577,7 @@ bool AntiTrackingCommon::IsFirstPartyStorageAccessGrantedFor( if (MOZ_LOG_TEST(gAntiTrackingLog, LogLevel::Debug)) { nsCOMPtr parentPrincipalURI; - Unused << parentDocument->NodePrincipal()->GetURI( - getter_AddRefs(parentPrincipalURI)); + Unused << parentPrincipal->GetURI(getter_AddRefs(parentPrincipalURI)); LOG_SPEC( ("Testing permission type %s for %s resulted in %d (%s)", type.get(), _spec, int(result), diff --git a/toolkit/components/antitracking/test/browser/browser_storageAccessWithHeuristics.js b/toolkit/components/antitracking/test/browser/browser_storageAccessWithHeuristics.js index 8317d7c4a0c0..7e2d8543216e 100644 --- a/toolkit/components/antitracking/test/browser/browser_storageAccessWithHeuristics.js +++ b/toolkit/components/antitracking/test/browser/browser_storageAccessWithHeuristics.js @@ -267,6 +267,43 @@ add_task(async function testUserInteractionHeuristic() { }); }); + info("Now ensure that the storage access is removed if the cookie policy is changed."); + await SpecialPowers.pushPrefEnv({"set": [ + ["network.cookie.cookieBehavior", Ci.nsICookieService.BEHAVIOR_REJECT], + ]}); + await ContentTask.spawn(browser, {}, async obj => { + await new content.Promise(resolve => { + let ifr = content.document.querySelectorAll("iframe"); + ifr = ifr[ifr.length - 1]; + + let msg = {}; + msg.blockingCallback = (async _ => { + await noStorageAccessInitially(); + }).toString(); + + 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: msg.blockingCallback }, "*"); + }); + }); + info("Removing the tab"); BrowserTestUtils.removeTab(tab); });