From f3c29840a737917683888f79253bdb9d39a19859 Mon Sep 17 00:00:00 2001 From: Joe Bowser Date: Mon, 26 Mar 2012 15:39:58 -0700 Subject: [PATCH] Moving whitelisting into the WebView, still need to read the config in the WebView if required --- .../org/apache/cordova/CordovaWebView.java | 83 +++++++++++++++++++ .../src/org/apache/cordova/DroidGap.java | 71 ++-------------- 2 files changed, 91 insertions(+), 63 deletions(-) diff --git a/framework/src/org/apache/cordova/CordovaWebView.java b/framework/src/org/apache/cordova/CordovaWebView.java index 526a1832..b24fc2c9 100644 --- a/framework/src/org/apache/cordova/CordovaWebView.java +++ b/framework/src/org/apache/cordova/CordovaWebView.java @@ -1,16 +1,32 @@ package org.apache.cordova; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; import java.util.Hashtable; +import java.util.Iterator; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.apache.cordova.api.LOG; +import org.xmlpull.v1.XmlPullParserException; import android.content.Context; +import android.content.res.XmlResourceParser; import android.util.AttributeSet; import android.webkit.WebView; public class CordovaWebView extends WebView { + public static final String TAG = "CordovaWebView"; + /** The authorization tokens. */ private Hashtable authenticationTokens = new Hashtable(); + /** The whitelist **/ + private ArrayList whiteList = new ArrayList(); + private HashMap whiteListCache = new HashMap(); + public CordovaWebView(Context context) { super(context); } @@ -109,4 +125,71 @@ public class CordovaWebView extends WebView { authenticationTokens.clear(); } + + /** + * Add entry to approved list of URLs (whitelist) + * + * @param origin URL regular expression to allow + * @param subdomains T=include all subdomains under origin + */ + public void addWhiteListEntry(String origin, boolean subdomains) { + try { + // Unlimited access to network resources + if(origin.compareTo("*") == 0) { + LOG.d(TAG, "Unlimited access to network resources"); + whiteList.add(Pattern.compile(".*")); + } else { // specific access + // check if subdomains should be included + // TODO: we should not add more domains if * has already been added + if (subdomains) { + // XXX making it stupid friendly for people who forget to include protocol/SSL + if(origin.startsWith("http")) { + whiteList.add(Pattern.compile(origin.replaceFirst("https?://", "^https?://(.*\\.)?"))); + } else { + whiteList.add(Pattern.compile("^https?://(.*\\.)?"+origin)); + } + LOG.d(TAG, "Origin to allow with subdomains: %s", origin); + } else { + // XXX making it stupid friendly for people who forget to include protocol/SSL + if(origin.startsWith("http")) { + whiteList.add(Pattern.compile(origin.replaceFirst("https?://", "^https?://"))); + } else { + whiteList.add(Pattern.compile("^https?://"+origin)); + } + LOG.d(TAG, "Origin to allow: %s", origin); + } + } + } catch(Exception e) { + LOG.d(TAG, "Failed to add origin %s", origin); + } + } + + /** + * Determine if URL is in approved list of URLs to load. + * + * @param url + * @return + */ + public boolean isUrlWhiteListed(String url) { + + // Check to see if we have matched url previously + if (whiteListCache.get(url) != null) { + return true; + } + + // Look for match in white list + Iterator pit = whiteList.iterator(); + while (pit.hasNext()) { + Pattern p = pit.next(); + Matcher m = p.matcher(url); + + // If match found, then cache it to speed up subsequent comparisons + if (m.find()) { + whiteListCache.put(url, true); + return true; + } + } + return false; + } + } diff --git a/framework/src/org/apache/cordova/DroidGap.java b/framework/src/org/apache/cordova/DroidGap.java index f5e256ec..07eb837b 100755 --- a/framework/src/org/apache/cordova/DroidGap.java +++ b/framework/src/org/apache/cordova/DroidGap.java @@ -152,8 +152,6 @@ public class DroidGap extends Activity implements CordovaInterface { // The webview for our app protected CordovaWebView appView; protected WebViewClient webViewClient; - private ArrayList whiteList = new ArrayList(); - private HashMap whiteListCache = new HashMap(); protected LinearLayout root; public boolean bound = false; @@ -220,11 +218,6 @@ public class DroidGap extends Activity implements CordovaInterface { public void onCreate(Bundle savedInstanceState) { preferences = new PreferenceSet(); - // Load Cordova configuration: - // white list of allowed URLs - // debug setting - this.loadConfiguration(); - LOG.d(TAG, "DroidGap.onCreate()"); super.onCreate(savedInstanceState); @@ -281,6 +274,11 @@ public class DroidGap extends Activity implements CordovaInterface { // Set up web container this.appView = webView; this.appView.setId(100); + + // Load Cordova configuration: + // white list of allowed URLs + // debug setting + this.loadConfiguration(); this.appView.setLayoutParams(new LinearLayout.LayoutParams( ViewGroup.LayoutParams.FILL_PARENT, @@ -1190,7 +1188,7 @@ public class DroidGap extends Activity implements CordovaInterface { String origin = xml.getAttributeValue(null, "origin"); String subdomains = xml.getAttributeValue(null, "subdomains"); if (origin != null) { - this.addWhiteListEntry(origin, (subdomains != null) && (subdomains.compareToIgnoreCase("true") == 0)); + this.appView.addWhiteListEntry(origin, (subdomains != null) && (subdomains.compareToIgnoreCase("true") == 0)); } } else if (strNode.equals("log")) { @@ -1223,43 +1221,7 @@ public class DroidGap extends Activity implements CordovaInterface { } } - /** - * Add entry to approved list of URLs (whitelist) - * - * @param origin URL regular expression to allow - * @param subdomains T=include all subdomains under origin - */ - private void addWhiteListEntry(String origin, boolean subdomains) { - try { - // Unlimited access to network resources - if(origin.compareTo("*") == 0) { - LOG.d(TAG, "Unlimited access to network resources"); - whiteList.add(Pattern.compile(".*")); - } else { // specific access - // check if subdomains should be included - // TODO: we should not add more domains if * has already been added - if (subdomains) { - // XXX making it stupid friendly for people who forget to include protocol/SSL - if(origin.startsWith("http")) { - whiteList.add(Pattern.compile(origin.replaceFirst("https?://", "^https?://(.*\\.)?"))); - } else { - whiteList.add(Pattern.compile("^https?://(.*\\.)?"+origin)); - } - LOG.d(TAG, "Origin to allow with subdomains: %s", origin); - } else { - // XXX making it stupid friendly for people who forget to include protocol/SSL - if(origin.startsWith("http")) { - whiteList.add(Pattern.compile(origin.replaceFirst("https?://", "^https?://"))); - } else { - whiteList.add(Pattern.compile("^https?://"+origin)); - } - LOG.d(TAG, "Origin to allow: %s", origin); - } - } - } catch(Exception e) { - LOG.d(TAG, "Failed to add origin %s", origin); - } - } + /** * Determine if URL is in approved list of URLs to load. @@ -1268,25 +1230,8 @@ public class DroidGap extends Activity implements CordovaInterface { * @return */ public boolean isUrlWhiteListed(String url) { - // Check to see if we have matched url previously - if (whiteListCache.get(url) != null) { - return true; - } - - // Look for match in white list - Iterator pit = whiteList.iterator(); - while (pit.hasNext()) { - Pattern p = pit.next(); - Matcher m = p.matcher(url); - - // If match found, then cache it to speed up subsequent comparisons - if (m.find()) { - whiteListCache.put(url, true); - return true; - } - } - return false; + return this.appView.isUrlWhiteListed(url); } /*