summaryrefslogtreecommitdiffstats
path: root/toolkit/components/antitracking/StorageAccessAPIHelper.h
diff options
context:
space:
mode:
Diffstat (limited to 'toolkit/components/antitracking/StorageAccessAPIHelper.h')
-rw-r--r--toolkit/components/antitracking/StorageAccessAPIHelper.h195
1 files changed, 195 insertions, 0 deletions
diff --git a/toolkit/components/antitracking/StorageAccessAPIHelper.h b/toolkit/components/antitracking/StorageAccessAPIHelper.h
new file mode 100644
index 0000000000..9be39df1c5
--- /dev/null
+++ b/toolkit/components/antitracking/StorageAccessAPIHelper.h
@@ -0,0 +1,195 @@
+/* -*- 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 method 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.prg 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<int, bool, true> StorageAccessPermissionGrantPromise;
+ typedef std::function<RefPtr<StorageAccessPermissionGrantPromise>()>
+ PerformPermissionGrant;
+ [[nodiscard]] static RefPtr<StorageAccessPermissionGrantPromise>
+ AllowAccessFor(
+ 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<nsresult, bool, true> ParentAccessGrantPromise;
+ static RefPtr<ParentAccessGrantPromise> SaveAccessForOriginOnParentProcess(
+ nsIPrincipal* aParentPrincipal, nsIPrincipal* aTrackingPrincipal,
+ int aAllowMode,
+ uint64_t aExpirationTime =
+ StaticPrefs::privacy_restrict3rdpartystorage_expiration());
+
+ static RefPtr<ParentAccessGrantPromise> SaveAccessForOriginOnParentProcess(
+ uint64_t aTopLevelWindowId, dom::BrowsingContext* aParentContext,
+ nsIPrincipal* aTrackingPrincipal, int aAllowMode,
+ 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<bool> CheckCookiesPermittedDecidesStorageAccessAPI(
+ nsICookieJarSettings* aCookieJarSettings,
+ nsIPrincipal* aRequestingPrincipal);
+
+ // Calls CheckCookiesPermittedDecidesStorageAccessAPI in the Content Parent
+ // using aBrowsingContext's Top's Window Global's CookieJarSettings.
+ static RefPtr<MozPromise<Maybe<bool>, nsresult, true>>
+ AsyncCheckCookiesPermittedDecidesStorageAccessAPI(
+ 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<bool> CheckBrowserSettingsDecidesStorageAccessAPI(
+ nsICookieJarSettings* aCookieJarSettings, bool aThirdParty,
+ bool aOnRejectForeignAllowlist, 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<bool> 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<bool> 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<bool> 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<StorageAccessPermissionGrantPromise>
+ RequestStorageAccessAsyncHelper(
+ dom::Document* aDocument, nsPIDOMWindowInner* aInnerWindow,
+ dom::BrowsingContext* aBrowsingContext, nsIPrincipal* aPrincipal,
+ bool aHasUserInteraction,
+ ContentBlockingNotifier::StorageAccessPermissionGrantedReason aNotifier,
+ bool aRequireGrant);
+
+ private:
+ friend class dom::ContentParent;
+ // This should be running either in the parent process or in the child
+ // processes with an in-process browsing context.
+ [[nodiscard]] static RefPtr<StorageAccessPermissionGrantPromise>
+ CompleteAllowAccessFor(
+ 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