From afdac9b413dc06ef63af9fb535f92bd5e1d257e9 Mon Sep 17 00:00:00 2001 From: Andrew Grieve Date: Mon, 2 Mar 2015 20:40:08 -0500 Subject: [PATCH] Split out `shouldAllowBridgeAccess` from `shouldAllowNavigation` This will allow a plugin to be created that allows iframes to be navigated to, but disallow them from accessing the bridge. Note: This isn't a configuration that we're planning on supporting with the default whitelist plugin, but still does make sense to enable for the experts in the room --- .../src/org/apache/cordova/CordovaBridge.java | 2 +- .../src/org/apache/cordova/CordovaPlugin.java | 12 +++++++++++- .../src/org/apache/cordova/PluginManager.java | 19 +++++++++++++++++++ 3 files changed, 31 insertions(+), 2 deletions(-) diff --git a/framework/src/org/apache/cordova/CordovaBridge.java b/framework/src/org/apache/cordova/CordovaBridge.java index b9c60983..7bc4a552 100644 --- a/framework/src/org/apache/cordova/CordovaBridge.java +++ b/framework/src/org/apache/cordova/CordovaBridge.java @@ -167,7 +167,7 @@ public class CordovaBridge { else if (defaultValue != null && defaultValue.startsWith("gap_init:")) { // Protect against random iframes being able to talk through the bridge. // Trust only pages which the app would have been allowed to navigate to anyway. - if (pluginManager.shouldAllowNavigation(origin)) { + if (pluginManager.shouldAllowBridgeAccess(origin)) { // Enable the bridge int bridgeMode = Integer.parseInt(defaultValue.substring(9)); jsMessageQueue.setBridgeMode(bridgeMode); diff --git a/framework/src/org/apache/cordova/CordovaPlugin.java b/framework/src/org/apache/cordova/CordovaPlugin.java index 71bf5cd6..c223f5cc 100644 --- a/framework/src/org/apache/cordova/CordovaPlugin.java +++ b/framework/src/org/apache/cordova/CordovaPlugin.java @@ -192,7 +192,8 @@ public class CordovaPlugin { } /** - * Hook for blocking navigation by the Cordova WebView. + * Hook for blocking navigation by the Cordova WebView. This applies both to top-level and + * iframe navigations. * * This will be called when the WebView's needs to know whether to navigate * to a new page. Return false to block the navigation: if any plugin @@ -204,6 +205,15 @@ public class CordovaPlugin { return null; } + /** + * Hook for allowing page to call exec(). By default, this returns the result of + * shouldAllowNavigation(). It's generally unsafe to allow untrusted content to be loaded + * into a CordovaWebView, even within an iframe, so it's best not to touch this. + */ + public Boolean shouldAllowBridgeAccess(String url) { + return shouldAllowNavigation(url); + } + /** * Hook for blocking the launching of Intents by the Cordova application. * diff --git a/framework/src/org/apache/cordova/PluginManager.java b/framework/src/org/apache/cordova/PluginManager.java index 4d7c8236..f8503424 100755 --- a/framework/src/org/apache/cordova/PluginManager.java +++ b/framework/src/org/apache/cordova/PluginManager.java @@ -365,6 +365,25 @@ public class PluginManager { return url.startsWith("file://"); } + + /** + * Called when the webview is requesting the exec() bridge be enabled. + */ + public boolean shouldAllowBridgeAccess(String url) { + for (PluginEntry entry : this.entryMap.values()) { + CordovaPlugin plugin = pluginMap.get(entry.service); + if (plugin != null) { + Boolean result = plugin.shouldAllowBridgeAccess(url); + if (result != null) { + return result; + } + } + } + + // Default policy: + return url.startsWith("file://"); + } + /** * Called when the webview is going not going to navigate, but may launch * an Intent for an URL.