Bug 1379842 - Check content principal when dragging and dropping from browser. r=smaug
authorTooru Fujisawa <arai_a@mac.com>
Thu, 10 Aug 2017 09:43:35 +0900
changeset 373909 9de512d55bb4e3ba087329f6867d703e76e50a5f
parent 373908 c038cbe885669230c179fe1cbcd903fb877eee34
child 373910 e360f835124223f465b2d035582a1f725298faa9
push id32311
push userkwierso@gmail.com
push dateFri, 11 Aug 2017 01:14:57 +0000
treeherdermozilla-central@253a8560dc34 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs1379842
milestone57.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1379842 - Check content principal when dragging and dropping from browser. r=smaug
browser/base/content/browser.js
browser/base/content/tabbrowser.xml
dom/base/contentAreaDropListener.js
dom/base/nsIDroppedLinkHandler.idl
toolkit/content/widgets/browser.xml
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -3585,16 +3585,20 @@ var browserDragAndDrop = {
   canDropLink: aEvent => Services.droppedLinkHandler.canDropLink(aEvent, true),
 
   dragOver(aEvent) {
     if (this.canDropLink(aEvent)) {
       aEvent.preventDefault();
     }
   },
 
+  getTriggeringPrincipal(aEvent) {
+    return Services.droppedLinkHandler.getTriggeringPrincipal(aEvent);
+  },
+
   dropLinks(aEvent, aDisallowInherit) {
     return Services.droppedLinkHandler.dropLinks(aEvent, aDisallowInherit);
   }
 };
 
 var homeButtonObserver = {
   onDrop(aEvent) {
       // disallow setting home pages that inherit the principal
--- a/browser/base/content/tabbrowser.xml
+++ b/browser/base/content/tabbrowser.xml
@@ -7158,22 +7158,17 @@
             inBackground = !inBackground;
 
           let targetTab = this._getDragTargetTab(event, true);
           let userContextId = this.selectedItem.getAttribute("usercontextid");
           let replace = !!targetTab;
           let newIndex = this._getDropIndex(event, true);
           let urls = links.map(link => link.url);
 
-
-          // Bug 1367038: mozSourceNode is null if the drag event originated
-          // in an external application - needs better fallback!
-          let triggeringPrincipal = dt.mozSourceNode
-            ? dt.mozSourceNode.nodePrincipal
-            : Services.scriptSecurityManager.getSystemPrincipal();
+          let triggeringPrincipal = browserDragAndDrop.getTriggeringPrincipal(event);
           this.tabbrowser.loadTabs(urls, {
             inBackground,
             replace,
             allowThirdPartyFixup: true,
             targetTab,
             newIndex,
             userContextId,
             triggeringPrincipal,
--- a/dom/base/contentAreaDropListener.js
+++ b/dom/base/contentAreaDropListener.js
@@ -117,25 +117,52 @@ ContentAreaDropListener.prototype =
     // uriString is a valid URI, so do the security check.
     let secMan = Cc["@mozilla.org/scriptsecuritymanager;1"].
                    getService(Ci.nsIScriptSecurityManager);
     let sourceNode = dataTransfer.mozSourceNode;
     let flags = secMan.STANDARD;
     if (disallowInherit)
       flags |= secMan.DISALLOW_INHERIT_PRINCIPAL;
 
-    // Use file:/// as the default uri so that drops of file URIs are always allowed
-    let principal = sourceNode ? sourceNode.nodePrincipal
-                               : secMan.createCodebasePrincipal(ioService.newURI("file:///"), {});
-
+    let principal;
+    if (sourceNode) {
+      principal = this._getTriggeringPrincipalFromSourceNode(sourceNode);
+    } else {
+      // Use file:/// as the default uri so that drops of file URIs are always
+      // allowed.
+      principal = secMan.createCodebasePrincipal(ioService.newURI("file:///"), {});
+    }
     secMan.checkLoadURIStrWithPrincipal(principal, uriString, flags);
 
     return uriString;
   },
 
+  _getTriggeringPrincipalFromSourceNode: function(aSourceNode)
+  {
+    if (aSourceNode.localName == "browser" &&
+        aSourceNode.namespaceURI == "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul") {
+      return aSourceNode.contentPrincipal;
+    }
+    return aSourceNode.nodePrincipal;
+  },
+
+  getTriggeringPrincipal: function(aEvent)
+  {
+    let dataTransfer = aEvent.dataTransfer;
+    let sourceNode = dataTransfer.mozSourceNode;
+    if (sourceNode) {
+      return this._getTriggeringPrincipalFromSourceNode(sourceNode, false);
+    }
+    // Bug 1367038: mozSourceNode is null if the drag event originated
+    // in an external application - needs better fallback!
+    let secMan = Cc["@mozilla.org/scriptsecuritymanager;1"].
+                   getService(Ci.nsIScriptSecurityManager);
+    return secMan.getSystemPrincipal();
+  },
+
   canDropLink: function(aEvent, aAllowSameDocument)
   {
     if (this._eventTargetIsDisabled(aEvent))
       return false;
 
     let dataTransfer = aEvent.dataTransfer;
     let types = dataTransfer.types;
     if (!types.includes("application/x-moz-file") &&
--- a/dom/base/nsIDroppedLinkHandler.idl
+++ b/dom/base/nsIDroppedLinkHandler.idl
@@ -1,13 +1,14 @@
 /* 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/. */
 
 #include "nsISupports.idl"
+#include "nsIPrincipal.idl"
 
 interface nsIDOMDragEvent;
 
 [scriptable, uuid(69E14F91-2E09-4CA6-A511-A715C99A2804)]
 interface nsIDroppedLinkItem : nsISupports
 {
   /**
    * Returns the URL of the link.
@@ -72,9 +73,15 @@ interface nsIDroppedLinkHandler : nsISup
    *    the user into a dragging a chrome url, for example.
    *  - aDisallowInherit is true, and the URI being dropped would inherit the
    *    current document's security context (URI_INHERITS_SECURITY_CONTEXT).
    */
   void dropLinks(in nsIDOMDragEvent aEvent,
                  [optional] in boolean aDisallowInherit,
                  [optional] out unsigned long aCount,
                  [retval, array, size_is(aCount)] out nsIDroppedLinkItem aLinks);
+
+  /**
+   * Given a drop event aEvent, determines the triggering principal for the
+   * event and returns it.
+   */
+  nsIPrincipal getTriggeringPrincipal(in nsIDOMDragEvent aEvent);
 };
--- a/toolkit/content/widgets/browser.xml
+++ b/toolkit/content/widgets/browser.xml
@@ -1691,27 +1691,17 @@
         try {
           // Pass true to prevent the dropping of javascript:/data: URIs
           var links = linkHandler.dropLinks(event, true);
         } catch (ex) {
           return;
         }
 
         if (links.length) {
-          // Bug 1368481: mozSourceNode is null if the drag event originated
-          // in an external application - needs better fallback!
-          let triggeringPrincipal;
-          let sourceNode = event.dataTransfer.mozSourceNode;
-          if (sourceNode) {
-            triggeringPrincipal = sourceNode.nodePrincipal;
-          } else {
-            var secMan = Components.classes["@mozilla.org/scriptsecuritymanager;1"].
-              getService(Components.interfaces.nsIScriptSecurityManager);
-            triggeringPrincipal = secMan.getSystemPrincipal();
-          }
+          let triggeringPrincipal = linkHandler.getTriggeringPrincipal(event);
           this.droppedLinkHandler(event, links, triggeringPrincipal);
         }
       ]]>
       </handler>
     </handlers>
 
   </binding>