Bug 1554260 - Send WebExtension Page messages to GeckoSession. r=snorp, a=jcristau
authorAgi Sferro <agi@sferro.dev>
Mon, 10 Jun 2019 20:09:25 +0000
changeset 536892 aac6fce419affdab022c4877a0690976d975d71a
parent 536891 55b21bb55d9eda98292b0af8931222f7ef0825f2
child 536893 3d31a0e1b47e48c382364a560c65fe44fee0954a
push id2082
push userffxbld-merge
push dateMon, 01 Jul 2019 08:34:18 +0000
treeherdermozilla-release@2fb19d0466d2 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssnorp, jcristau
bugs1554260
milestone68.0
Bug 1554260 - Send WebExtension Page messages to GeckoSession. r=snorp, a=jcristau WebExtension pages introduce a case that was previously not possible: a script with full WebExtension privileges that runs on a page with a GeckoSession associated to it. This breaks the assumption that all messages from a privileged context don't have a GeckoSession associated to it. We fix this by checking if we can find an eventDispatcher for the given window. This also fixes the test which had the same wrong assumption. Differential Revision: https://phabricator.services.mozilla.com/D32512
mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/WebExtensionTest.kt
mobile/android/geckoview/src/main/java/org/mozilla/geckoview/WebExtensionEventDispatcher.java
mobile/android/modules/geckoview/GeckoViewWebExtension.jsm
--- a/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/WebExtensionTest.kt
+++ b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/WebExtensionTest.kt
@@ -476,19 +476,19 @@ class WebExtensionTest : BaseSessionTest
                         sender.environmentType)
                 result.complete(message as String)
 
                 return null
             }
         }
 
         extension = WebExtension("resource://android/assets/web_extensions/extension-page-update/")
-        extension.setMessageDelegate(messageDelegate, "browser")
 
         sessionRule.waitForResult(sessionRule.runtime.registerWebExtension(extension))
+        mainSession.setMessageDelegate(messageDelegate, "browser")
 
         mainSession.loadUri("http://example.com");
 
         mainSession.waitUntilCalled(object : Callbacks.NavigationDelegate, Callbacks.ProgressDelegate {
             @GeckoSessionTestRule.AssertCalled(count = 1)
             override fun onLocationChange(session: GeckoSession, url: String?) {
                 assertThat("Url should load example.com first",
                         url, equalTo("http://example.com/"))
--- a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/WebExtensionEventDispatcher.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/WebExtensionEventDispatcher.java
@@ -68,22 +68,17 @@ import java.util.Map;
         }
 
         final String envType = sender.getString("envType");
         @WebExtension.MessageSender.EnvType int environmentType;
 
         if ("content_child".equals(envType)) {
             environmentType = WebExtension.MessageSender.ENV_TYPE_CONTENT_SCRIPT;
         } else if ("addon_child".equals(envType)) {
-            if (session != null) {
-                // This message came from a content process but it claims to be from an extension
-                // environment, which can't be true. This maybe caused by a compromised content process.
-                // TODO: Bug 1534640, we need to check for extension process here too.
-                return null;
-            }
+            // TODO Bug 1554277: check that this message is coming from the right process
             environmentType = WebExtension.MessageSender.ENV_TYPE_EXTENSION;
         } else {
             environmentType = WebExtension.MessageSender.ENV_TYPE_UNKNOWN;
         }
 
         if (environmentType == WebExtension.MessageSender.ENV_TYPE_UNKNOWN) {
             if (BuildConfig.DEBUG) {
                 throw new RuntimeException("Missing or unknown envType.");
--- a/mobile/android/modules/geckoview/GeckoViewWebExtension.jsm
+++ b/mobile/android/modules/geckoview/GeckoViewWebExtension.jsm
@@ -73,17 +73,25 @@ class GeckoViewConnection {
     if (aTarget.frameLoader) {
       return aTarget.frameLoader.messageManager;
     }
     return aTarget;
   }
 
   get dispatcher() {
     if (this.sender.envType === "addon_child") {
-      // For background scripts, use the global event handler
+      // If this is a WebExtension Page we will have a GeckoSession associated
+      // to it and thus a dispatcher.
+      const dispatcher = GeckoViewUtils.getDispatcherForWindow(this.target.ownerGlobal);
+      if (dispatcher) {
+        return dispatcher;
+      }
+
+      // No dispatcher means this message is coming from a background script,
+      // use the global event handler
       return EventDispatcher.instance;
     } else if (this.sender.envType === "content_child"
         && this.allowContentMessaging) {
       // If this message came from a content script, send the message to
       // the corresponding tab messenger so that GeckoSession can pick it
       // up.
       return GeckoViewUtils.getDispatcherForWindow(this.target.ownerGlobal);
     }