From 26a029d407be480d791972afb5975cf62c9360a6 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Fri, 19 Apr 2024 02:47:55 +0200 Subject: Adding upstream version 124.0.1. Signed-off-by: Daniel Baumann --- .../antitracking/StorageAccessAPIHelper.h | 222 +++++++++++++++++++++ 1 file changed, 222 insertions(+) create mode 100644 toolkit/components/antitracking/StorageAccessAPIHelper.h (limited to 'toolkit/components/antitracking/StorageAccessAPIHelper.h') diff --git a/toolkit/components/antitracking/StorageAccessAPIHelper.h b/toolkit/components/antitracking/StorageAccessAPIHelper.h new file mode 100644 index 0000000000..dd6f326604 --- /dev/null +++ b/toolkit/components/antitracking/StorageAccessAPIHelper.h @@ -0,0 +1,222 @@ +/* -*- 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_antitrackingservice_h +#define mozilla_antitrackingservice_h + +#include "nsString.h" +#include "mozilla/ContentBlockingNotifier.h" +#include "mozilla/MozPromise.h" +#include "mozilla/RefPtr.h" +#include "mozilla/StaticPrefs_privacy.h" + +#include "nsIUrlClassifierFeature.h" + +class nsIChannel; +class nsICookieJarSettings; +class nsIPermission; +class nsIPrincipal; +class nsIURI; +class nsPIDOMWindowInner; +class nsPIDOMWindowOuter; + +namespace mozilla { + +class OriginAttributes; + +namespace dom { +class BrowsingContext; +class ContentParent; +class Document; +} // namespace dom + +class StorageAccessAPIHelper final { + public: + enum StorageAccessPromptChoices { eAllow, eAllowAutoGrant }; + + // Grant the permission for aOrigin to have access to the first party storage. + // This methods can handle 2 different scenarios: + // - aParentContext is a 3rd party context, it opens an aOrigin window and the + // user interacts with it. We want to grant the permission at the + // combination: top-level + aParentWindow + aOrigin. + // Ex: example.net loads an iframe tracker.com, which opens a popup + // tracker.org and the user interacts with it. tracker.org is allowed if + // loaded by tracker.com when loaded by example.net. + // - aParentContext is a first party context and a 3rd party resource + // (probably becuase of a script) opens a popup and the user interacts with + // it. We want to grant the permission for the 3rd party context to have + // access to the first party stoage when loaded in aParentWindow. Ex: + // example.net import tracker.com/script.js which does opens a popup and the + // user interacts with it. tracker.com is allowed when loaded by + // example.net. + typedef MozPromise StorageAccessPermissionGrantPromise; + typedef std::function()> + PerformPermissionGrant; + [[nodiscard]] static RefPtr + AllowAccessForOnParentProcess( + nsIPrincipal* aPrincipal, dom::BrowsingContext* aParentContext, + ContentBlockingNotifier::StorageAccessPermissionGrantedReason aReason, + const PerformPermissionGrant& aPerformFinalChecks = nullptr); + + [[nodiscard]] static RefPtr + AllowAccessForOnChildProcess( + nsIPrincipal* aPrincipal, dom::BrowsingContext* aParentContext, + ContentBlockingNotifier::StorageAccessPermissionGrantedReason aReason, + const PerformPermissionGrant& aPerformFinalChecks = nullptr); + + // This function handles tasks that have to be done in the process + // of the window that we just grant permission for. + static void OnAllowAccessFor( + dom::BrowsingContext* aParentContext, const nsACString& aTrackingOrigin, + uint32_t aCookieBehavior, + ContentBlockingNotifier::StorageAccessPermissionGrantedReason aReason); + + // For IPC only. + typedef MozPromise ParentAccessGrantPromise; + static RefPtr SaveAccessForOriginOnParentProcess( + nsIPrincipal* aParentPrincipal, nsIPrincipal* aTrackingPrincipal, + int aAllowMode, bool aFrameOnly, + uint64_t aExpirationTime = + StaticPrefs::privacy_restrict3rdpartystorage_expiration()); + + static RefPtr SaveAccessForOriginOnParentProcess( + uint64_t aTopLevelWindowId, dom::BrowsingContext* aParentContext, + nsIPrincipal* aTrackingPrincipal, int aAllowMode, bool aFrameOnly, + uint64_t aExpirationTime = + StaticPrefs::privacy_restrict3rdpartystorage_expiration()); + + // This function checks if the document has explicit permission either to + // allow or deny access to cookies. This may be because of the "cookie" + // permission or because the domain is on the ContentBlockingAllowList + // e.g. because the user flipped the sheild. + // This returns: + // Some(true) if unpartitioned cookies will be permitted + // Some(false) if unpartitioned cookies will be blocked + // None if it is not clear from permission alone what to do + static Maybe CheckCookiesPermittedDecidesStorageAccessAPI( + nsICookieJarSettings* aCookieJarSettings, + nsIPrincipal* aRequestingPrincipal); + + // Calls CheckCookiesPermittedDecidesStorageAccessAPI in the Content Parent + // using aBrowsingContext's Top's Window Global's CookieJarSettings. + static RefPtr, nsresult, true>> + AsyncCheckCookiesPermittedDecidesStorageAccessAPIOnChildProcess( + dom::BrowsingContext* aBrowsingContext, + nsIPrincipal* aRequestingPrincipal); + + // This function checks if the browser settings give explicit permission + // either to allow or deny access to cookies. This only checks the + // cookieBehavior setting. This requires an additional bool to indicate + // whether or not the context considered is third-party. This returns: + // Some(true) if unpartitioned cookies will be permitted + // Some(false) if unpartitioned cookies will be blocked + // None if it is not clear from settings alone what to do + static Maybe CheckBrowserSettingsDecidesStorageAccessAPI( + nsICookieJarSettings* aCookieJarSettings, bool aThirdParty, + bool aIsOnThirdPartySkipList, bool aIsThirdPartyTracker); + + // This function checks if the document's context (like if it is third-party + // or an iframe) gives an answer of how a the StorageAccessAPI call, that is + // meant to be called by an embedded third party, should return. + // This requires an argument that allows some checks to be run only if the + // caller of this function is performing a request for storage access. + // This returns: + // Some(true) if the calling context has access to cookies if it is not + // disallowed by the browser settings and cookie permissions + // Some(false) if the calling context should not have access to cookies if + // it is not expressly allowed by the browser settings and + // cookie permissions + // None if the calling context does not determine the document's access to + // unpartitioned cookies + static Maybe CheckCallingContextDecidesStorageAccessAPI( + dom::Document* aDocument, bool aRequestingStorageAccess); + + // This function checks if the document's context (like if it is third-party + // or an iframe) gives an answer of how a the StorageAccessAPI call that is + // meant to be called in a top-level context, should return. + // This returns: + // Some(true) if the calling context indicates calls to the top-level + // API must resolve if it is not + // disallowed by the browser settings and cookie permissions + // Some(false) if the calling context must reject when calling top level + // portions of the API if it is not expressly allowed by the + // browser settings and cookie permissions + // None if the calling context does not determine the outcome of the + // document's use of the top-level portions of the Storage Access API. + static Maybe CheckSameSiteCallingContextDecidesStorageAccessAPI( + dom::Document* aDocument, bool aRequireUserActivation); + + // This function checks if the document has already been granted or denied + // access to its unpartitioned cookies by the StorageAccessAPI + // This returns: + // Some(true) if the document has been granted access by the Storage Access + // API before + // Some(false) if the document has been denied access by the Storage Access + // API before + // None if the document has not been granted or denied access by the Storage + // Access API before + static Maybe CheckExistingPermissionDecidesStorageAccessAPI( + dom::Document* aDocument, bool aRequestingStorageAccess); + + // This function performs the asynchronous portion of checking if requests + // for storage access will be successful or not. This includes calling + // Document member functions that creating a permission prompt request and + // trying to perform an "autogrant" if aRequireGrant is true. + // This will return a promise whose values correspond to those of a + // ContentBlocking::AllowAccessFor call that ends the function. + static RefPtr + RequestStorageAccessAsyncHelper( + dom::Document* aDocument, nsPIDOMWindowInner* aInnerWindow, + dom::BrowsingContext* aBrowsingContext, nsIPrincipal* aPrincipal, + bool aHasUserInteraction, bool aRequireUserInteraction, bool aFrameOnly, + ContentBlockingNotifier::StorageAccessPermissionGrantedReason aNotifier, + bool aRequireGrant); + + private: + friend class dom::ContentParent; + + // This function performs browser setting, cookie behavior and requesting + // context checks that might grant/reject storage access immediately using + // information provided by the inputs aPrincipal and aParentContext. To reduce + // redundancy the following out parameters with information also required in + // AllowAccessFor() are set in the function: aTrackingPrinciple, + // aTrackingOrigin, aTopLevelWindowId, aBehavior. If storage access can be + // granted/rejected due to settings/behavior returns a promise, else returns + // nullptr. + [[nodiscard]] static RefPtr< + StorageAccessAPIHelper::StorageAccessPermissionGrantPromise> + AllowAccessForHelper( + nsIPrincipal* aPrincipal, dom::BrowsingContext* aParentContext, + ContentBlockingNotifier::StorageAccessPermissionGrantedReason aReason, + nsCOMPtr* aTrackingPrincipal, nsACString& aTrackingOrigin, + uint64_t* aTopLevelWindowId, uint32_t* aBehavior); + + [[nodiscard]] static RefPtr + CompleteAllowAccessForOnParentProcess( + dom::BrowsingContext* aParentContext, uint64_t aTopLevelWindowId, + nsIPrincipal* aTrackingPrincipal, const nsACString& aTrackingOrigin, + uint32_t aCookieBehavior, + ContentBlockingNotifier::StorageAccessPermissionGrantedReason aReason, + const PerformPermissionGrant& aPerformFinalChecks = nullptr); + + [[nodiscard]] static RefPtr + CompleteAllowAccessForOnChildProcess( + dom::BrowsingContext* aParentContext, uint64_t aTopLevelWindowId, + nsIPrincipal* aTrackingPrincipal, const nsACString& aTrackingOrigin, + uint32_t aCookieBehavior, + ContentBlockingNotifier::StorageAccessPermissionGrantedReason aReason, + const PerformPermissionGrant& aPerformFinalChecks = nullptr); + + static void UpdateAllowAccessOnCurrentProcess( + dom::BrowsingContext* aParentContext, const nsACString& aTrackingOrigin); + + static void UpdateAllowAccessOnParentProcess( + dom::BrowsingContext* aParentContext, const nsACString& aTrackingOrigin); +}; + +} // namespace mozilla + +#endif // mozilla_antitrackingservice_h -- cgit v1.2.3