Moving whitelisting into the WebView, still need to read the config in the WebView if required

This commit is contained in:
Joe Bowser 2012-03-26 15:39:58 -07:00
parent 6dabe4c010
commit f3c29840a7
2 changed files with 91 additions and 63 deletions

View File

@ -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<String, AuthenticationToken> authenticationTokens = new Hashtable<String, AuthenticationToken>();
/** The whitelist **/
private ArrayList<Pattern> whiteList = new ArrayList<Pattern>();
private HashMap<String, Boolean> whiteListCache = new HashMap<String,Boolean>();
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<Pattern> 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;
}
}

View File

@ -152,8 +152,6 @@ public class DroidGap extends Activity implements CordovaInterface {
// The webview for our app
protected CordovaWebView appView;
protected WebViewClient webViewClient;
private ArrayList<Pattern> whiteList = new ArrayList<Pattern>();
private HashMap<String, Boolean> whiteListCache = new HashMap<String,Boolean>();
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<Pattern> 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);
}
/*