[tor-commits] [tor-browser/tor-browser-60.1.0esr-8.0-1] Bug 26670: Make canvas permission respect FPI

gk at torproject.org gk at torproject.org
Wed Aug 29 22:06:56 UTC 2018


commit 79db24856a23ec7ae1f6d8cf46919a499ae5bb9f
Author: Arthur Edelstein <arthuredelstein at gmail.com>
Date:   Wed Aug 29 09:56:57 2018 -0700

    Bug 26670: Make canvas permission respect FPI
---
 browser/base/content/browser.js | 21 ++++++++++++---------
 dom/canvas/CanvasUtils.cpp      | 23 ++++++++++++++++-------
 dom/ipc/PBrowser.ipdl           |  4 ++--
 dom/ipc/TabParent.cpp           |  4 ++--
 dom/ipc/TabParent.h             |  2 +-
 5 files changed, 33 insertions(+), 21 deletions(-)

diff --git a/browser/base/content/browser.js b/browser/base/content/browser.js
index fbfbf3e809ca..443619533567 100644
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -6824,7 +6824,7 @@ var CanvasPermissionPromptHelper = {
   },
 
   // aSubject is an nsIBrowser (e10s) or an nsIDOMWindow (non-e10s).
-  // aData is an URL string.
+  // aData is an Origin string.
   observe(aSubject, aTopic, aData) {
     if (aTopic != this._permissionsPrompt) {
       return;
@@ -6838,7 +6838,6 @@ var CanvasPermissionPromptHelper = {
       browser = aSubject.QueryInterface(Ci.nsIBrowser);
     }
 
-    let uri = Services.io.newURI(aData);
     if (gBrowser.selectedBrowser !== browser) {
       // Must belong to some other window.
       return;
@@ -6846,17 +6845,21 @@ var CanvasPermissionPromptHelper = {
 
     let message = gNavigatorBundle.getFormattedString("canvas.siteprompt", ["<>"], 1);
 
-    function setCanvasPermission(aURI, aPerm, aPersistent) {
-      Services.perms.add(aURI, "canvas", aPerm,
-                          aPersistent ? Ci.nsIPermissionManager.EXPIRE_NEVER
-                                      : Ci.nsIPermissionManager.EXPIRE_SESSION);
+    let principal = Services.scriptSecurityManager
+                            .createCodebasePrincipalFromOrigin(aData);
+
+    function setCanvasPermission(aPerm, aPersistent) {
+      Services.perms.addFromPrincipal(
+        principal, "canvas", aPerm,
+        aPersistent ? Ci.nsIPermissionManager.EXPIRE_NEVER
+                    : Ci.nsIPermissionManager.EXPIRE_SESSION);
     }
 
     let mainAction = {
       label: gNavigatorBundle.getString("canvas.allow"),
       accessKey: gNavigatorBundle.getString("canvas.allow.accesskey"),
       callback(state) {
-        setCanvasPermission(uri, Ci.nsIPermissionManager.ALLOW_ACTION,
+        setCanvasPermission(Ci.nsIPermissionManager.ALLOW_ACTION,
                             state && state.checkboxChecked);
       }
     };
@@ -6865,7 +6868,7 @@ var CanvasPermissionPromptHelper = {
       label: gNavigatorBundle.getString("canvas.notAllow"),
       accessKey: gNavigatorBundle.getString("canvas.notAllow.accesskey"),
       callback(state) {
-        setCanvasPermission(uri, Ci.nsIPermissionManager.DENY_ACTION,
+        setCanvasPermission(Ci.nsIPermissionManager.DENY_ACTION,
                             state && state.checkboxChecked);
       }
     }];
@@ -6881,7 +6884,7 @@ var CanvasPermissionPromptHelper = {
 
     let options = {
       checkbox,
-      name: uri.asciiHost,
+      name: principal.URI.host,
       learnMoreURL: Services.urlFormatter.formatURLPref("app.support.baseURL") + "fingerprint-permission",
     };
     PopupNotifications.show(browser, aTopic, message, this._notificationIcon,
diff --git a/dom/canvas/CanvasUtils.cpp b/dom/canvas/CanvasUtils.cpp
index 0a8d7f0e2e59..ca8d91d92181 100644
--- a/dom/canvas/CanvasUtils.cpp
+++ b/dom/canvas/CanvasUtils.cpp
@@ -58,8 +58,13 @@ bool IsImageExtractionAllowed(nsIDocument *aDocument, JSContext *aCx)
     // Documents with system principal can always extract canvas data.
     nsPIDOMWindowOuter *win = aDocument->GetWindow();
     nsCOMPtr<nsIScriptObjectPrincipal> sop(do_QueryInterface(win));
-    if (sop && nsContentUtils::IsSystemPrincipal(sop->GetPrincipal())) {
-        return true;
+    if (!sop) {
+      return false;
+    }
+
+    nsCOMPtr<nsIPrincipal> principal(sop->GetPrincipal());
+    if (principal && nsContentUtils::IsSystemPrincipal(principal)) {
+      return true;
     }
 
     // Always give permission to chrome scripts (e.g. Page Inspector).
@@ -127,9 +132,9 @@ bool IsImageExtractionAllowed(nsIDocument *aDocument, JSContext *aCx)
     // Check if the site has permission to extract canvas data.
     // Either permit or block extraction if a stored permission setting exists.
     uint32_t permission;
-    rv = permissionManager->TestPermission(topLevelDocURI,
-                                           PERMISSION_CANVAS_EXTRACT_DATA,
-                                           &permission);
+    rv = permissionManager->TestPermissionFromPrincipal(principal,
+                                                        PERMISSION_CANVAS_EXTRACT_DATA,
+                                                        &permission);
     NS_ENSURE_SUCCESS(rv, false);
     switch (permission) {
     case nsIPermissionManager::ALLOW_ACTION:
@@ -165,16 +170,20 @@ bool IsImageExtractionAllowed(nsIDocument *aDocument, JSContext *aCx)
     nsContentUtils::LogMessageToConsole(message.get());
 
     // Prompt the user (asynchronous).
+    nsAutoCString origin;
+    rv = principal->GetOrigin(origin);
+    NS_ENSURE_SUCCESS(rv, false);
+
     if (XRE_IsContentProcess()) {
         TabChild* tabChild = TabChild::GetFrom(win);
         if (tabChild) {
-            tabChild->SendShowCanvasPermissionPrompt(topLevelDocURISpec);
+            tabChild->SendShowCanvasPermissionPrompt(origin);
         }
     } else {
         nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
         if (obs) {
             obs->NotifyObservers(win, TOPIC_CANVAS_PERMISSIONS_PROMPT,
-                                 NS_ConvertUTF8toUTF16(topLevelDocURISpec).get());
+                                 NS_ConvertUTF8toUTF16(origin).get());
         }
     }
 
diff --git a/dom/ipc/PBrowser.ipdl b/dom/ipc/PBrowser.ipdl
index 024ebc5b6cf7..118eaf15af1f 100644
--- a/dom/ipc/PBrowser.ipdl
+++ b/dom/ipc/PBrowser.ipdl
@@ -579,9 +579,9 @@ parent:
      * This function is used to notify the parent that it should display a
      * canvas permission prompt.
      *
-     * @param aFirstPartyURI first party of the tab that is requesting access.
+     * @param aOrigin origin string of the document that is requesting access.
      */
-    async ShowCanvasPermissionPrompt(nsCString aFirstPartyURI);
+    async ShowCanvasPermissionPrompt(nsCString aOrigin);
 
 child:
     /**
diff --git a/dom/ipc/TabParent.cpp b/dom/ipc/TabParent.cpp
index 86bb854962be..d8f4567626e1 100644
--- a/dom/ipc/TabParent.cpp
+++ b/dom/ipc/TabParent.cpp
@@ -3567,7 +3567,7 @@ TabParent::RecvLookUpDictionary(const nsString& aText,
 }
 
 mozilla::ipc::IPCResult
-TabParent::RecvShowCanvasPermissionPrompt(const nsCString& aFirstPartyURI)
+TabParent::RecvShowCanvasPermissionPrompt(const nsCString& aOrigin)
 {
   nsCOMPtr<nsIBrowser> browser = do_QueryInterface(mFrameElement);
   if (!browser) {
@@ -3580,7 +3580,7 @@ TabParent::RecvShowCanvasPermissionPrompt(const nsCString& aFirstPartyURI)
     return IPC_FAIL_NO_REASON(this);
   }
   nsresult rv = os->NotifyObservers(browser, "canvas-permissions-prompt",
-                                    NS_ConvertUTF8toUTF16(aFirstPartyURI).get());
+                                    NS_ConvertUTF8toUTF16(aOrigin).get());
   if (NS_FAILED(rv)) {
     return IPC_FAIL_NO_REASON(this);
   }
diff --git a/dom/ipc/TabParent.h b/dom/ipc/TabParent.h
index 7d62663835d7..6f3d6de10c10 100644
--- a/dom/ipc/TabParent.h
+++ b/dom/ipc/TabParent.h
@@ -631,7 +631,7 @@ protected:
 
   virtual mozilla::ipc::IPCResult RecvGetTabCount(uint32_t* aValue) override;
 
-  virtual mozilla::ipc::IPCResult RecvShowCanvasPermissionPrompt(const nsCString& aFirstPartyURI) override;
+  virtual mozilla::ipc::IPCResult RecvShowCanvasPermissionPrompt(const nsCString& aOrigin) override;
 
   ContentCacheInParent mContentCache;
 



More information about the tor-commits mailing list