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