1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this file, 5 * You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #ifndef mozilla_antitrackingservice_h 8 #define mozilla_antitrackingservice_h 9 10 #include "nsString.h" 11 #include "mozilla/ContentBlockingNotifier.h" 12 #include "mozilla/MozPromise.h" 13 #include "mozilla/RefPtr.h" 14 #include "mozilla/StaticPrefs_privacy.h" 15 16 class nsIChannel; 17 class nsICookieJarSettings; 18 class nsIPermission; 19 class nsIPrincipal; 20 class nsIURI; 21 class nsPIDOMWindowInner; 22 class nsPIDOMWindowOuter; 23 24 namespace mozilla { 25 26 class OriginAttributes; 27 28 namespace dom { 29 class BrowsingContext; 30 class ContentParent; 31 } // namespace dom 32 33 class ContentBlocking final { 34 public: 35 // This method returns true if the URI has first party storage access when 36 // loaded inside the passed 3rd party context tracking resource window. 37 // If the window is first party context, please use 38 // ApproximateAllowAccessForWithoutChannel(); 39 // 40 // aRejectedReason could be set to one of these values if passed and if the 41 // storage permission is not granted: 42 // * nsIWebProgressListener::STATE_COOKIES_BLOCKED_BY_PERMISSION 43 // * nsIWebProgressListener::STATE_COOKIES_BLOCKED_TRACKER 44 // * nsIWebProgressListener::STATE_COOKIES_BLOCKED_SOCIALTRACKER 45 // * nsIWebProgressListener::STATE_COOKIES_BLOCKED_ALL 46 // * nsIWebProgressListener::STATE_COOKIES_BLOCKED_FOREIGN 47 static bool ShouldAllowAccessFor(nsPIDOMWindowInner* a3rdPartyTrackingWindow, 48 nsIURI* aURI, uint32_t* aRejectedReason); 49 50 // Note: you should use ShouldAllowAccessFor() passing the nsIChannel! Use 51 // this method _only_ if the channel is not available. For first party 52 // window, it's impossible to know if the aURI is a tracking resource 53 // synchronously, so here we return the best guest: if we are sure that the 54 // permission is granted for the origin of aURI, this method returns true, 55 // otherwise false. 56 static bool ApproximateAllowAccessForWithoutChannel( 57 nsPIDOMWindowInner* aFirstPartyWindow, nsIURI* aURI); 58 59 // It returns true if the URI has access to the first party storage. 60 // aChannel can be a 3rd party channel, or not. 61 // See ShouldAllowAccessFor(window) to see the possible values of 62 // aRejectedReason. 63 static bool ShouldAllowAccessFor(nsIChannel* aChannel, nsIURI* aURI, 64 uint32_t* aRejectedReason); 65 66 // This method checks if the principal has the permission to access to the 67 // first party storage. 68 static bool ShouldAllowAccessFor(nsIPrincipal* aPrincipal, 69 nsICookieJarSettings* aCookieJarSettings); 70 71 enum StorageAccessPromptChoices { eAllow, eAllowAutoGrant }; 72 73 // Grant the permission for aOrigin to have access to the first party storage. 74 // This method can handle 2 different scenarios: 75 // - aParentContext is a 3rd party context, it opens an aOrigin window and the 76 // user interacts with it. We want to grant the permission at the 77 // combination: top-level + aParentWindow + aOrigin. 78 // Ex: example.net loads an iframe tracker.com, which opens a popup 79 // tracker.prg and the user interacts with it. tracker.org is allowed if 80 // loaded by tracker.com when loaded by example.net. 81 // - aParentContext is a first party context and a 3rd party resource 82 // (probably 83 // becuase of a script) opens a popup and the user interacts with it. We 84 // want to grant the permission for the 3rd party context to have access to 85 // the first party stoage when loaded in aParentWindow. 86 // Ex: example.net import tracker.com/script.js which does opens a popup and 87 // the user interacts with it. tracker.com is allowed when loaded by 88 // example.net. 89 typedef MozPromise<int, bool, true> StorageAccessFinalCheckPromise; 90 typedef std::function<RefPtr<StorageAccessFinalCheckPromise>()> 91 PerformFinalChecks; 92 typedef MozPromise<int, bool, true> StorageAccessGrantPromise; 93 static MOZ_MUST_USE RefPtr<StorageAccessGrantPromise> AllowAccessFor( 94 nsIPrincipal* aPrincipal, dom::BrowsingContext* aParentContext, 95 ContentBlockingNotifier::StorageAccessGrantedReason aReason, 96 const PerformFinalChecks& aPerformFinalChecks = nullptr); 97 98 // This function handles tasks that have to be done in the process 99 // of the window that we just grant permission for. 100 static void OnAllowAccessFor( 101 dom::BrowsingContext* aParentContext, const nsCString& aTrackingOrigin, 102 uint32_t aCookieBehavior, 103 ContentBlockingNotifier::StorageAccessGrantedReason aReason); 104 105 // For IPC only. 106 typedef MozPromise<nsresult, bool, true> ParentAccessGrantPromise; 107 static RefPtr<ParentAccessGrantPromise> SaveAccessForOriginOnParentProcess( 108 nsIPrincipal* aParentPrincipal, nsIPrincipal* aTrackingPrinciapl, 109 const nsCString& aTrackingOrigin, int aAllowMode, 110 uint64_t aExpirationTime = 111 StaticPrefs::privacy_restrict3rdpartystorage_expiration()); 112 113 static RefPtr<ParentAccessGrantPromise> SaveAccessForOriginOnParentProcess( 114 uint64_t aTopLevelWindowId, dom::BrowsingContext* aParentContext, 115 nsIPrincipal* aTrackingPrinciapl, const nsCString& aTrackingOrigin, 116 int aAllowMode, 117 uint64_t aExpirationTime = 118 StaticPrefs::privacy_restrict3rdpartystorage_expiration()); 119 120 private: 121 friend class dom::ContentParent; 122 // This should be running either in the parent process or in the child 123 // processes with an in-process browsing context. 124 static MOZ_MUST_USE RefPtr<StorageAccessGrantPromise> CompleteAllowAccessFor( 125 dom::BrowsingContext* aParentContext, uint64_t aTopLevelWindowId, 126 nsIPrincipal* aTrackingPrincipal, const nsCString& aTrackingOrigin, 127 uint32_t aCookieBehavior, 128 ContentBlockingNotifier::StorageAccessGrantedReason aReason, 129 const PerformFinalChecks& aPerformFinalChecks = nullptr); 130 131 static void UpdateAllowAccessOnCurrentProcess( 132 dom::BrowsingContext* aParentContext, const nsACString& aTrackingOrigin); 133 134 static void UpdateAllowAccessOnParentProcess( 135 dom::BrowsingContext* aParentContext, const nsACString& aTrackingOrigin); 136 }; 137 138 } // namespace mozilla 139 140 #endif // mozilla_antitrackingservice_h 141