mirror of
https://github.com/apache/cordova-android.git
synced 2025-01-31 17:32:51 +08:00
Moving whitelisting into the WebView, still need to read the config in the WebView if required
This commit is contained in:
parent
6dabe4c010
commit
f3c29840a7
@ -1,16 +1,32 @@
|
|||||||
package org.apache.cordova;
|
package org.apache.cordova;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.Hashtable;
|
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.Context;
|
||||||
|
import android.content.res.XmlResourceParser;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
import android.webkit.WebView;
|
import android.webkit.WebView;
|
||||||
|
|
||||||
public class CordovaWebView extends WebView {
|
public class CordovaWebView extends WebView {
|
||||||
|
|
||||||
|
public static final String TAG = "CordovaWebView";
|
||||||
|
|
||||||
/** The authorization tokens. */
|
/** The authorization tokens. */
|
||||||
private Hashtable<String, AuthenticationToken> authenticationTokens = new Hashtable<String, AuthenticationToken>();
|
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) {
|
public CordovaWebView(Context context) {
|
||||||
super(context);
|
super(context);
|
||||||
}
|
}
|
||||||
@ -109,4 +125,71 @@ public class CordovaWebView extends WebView {
|
|||||||
authenticationTokens.clear();
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -152,8 +152,6 @@ public class DroidGap extends Activity implements CordovaInterface {
|
|||||||
// The webview for our app
|
// The webview for our app
|
||||||
protected CordovaWebView appView;
|
protected CordovaWebView appView;
|
||||||
protected WebViewClient webViewClient;
|
protected WebViewClient webViewClient;
|
||||||
private ArrayList<Pattern> whiteList = new ArrayList<Pattern>();
|
|
||||||
private HashMap<String, Boolean> whiteListCache = new HashMap<String,Boolean>();
|
|
||||||
|
|
||||||
protected LinearLayout root;
|
protected LinearLayout root;
|
||||||
public boolean bound = false;
|
public boolean bound = false;
|
||||||
@ -220,11 +218,6 @@ public class DroidGap extends Activity implements CordovaInterface {
|
|||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
preferences = new PreferenceSet();
|
preferences = new PreferenceSet();
|
||||||
|
|
||||||
// Load Cordova configuration:
|
|
||||||
// white list of allowed URLs
|
|
||||||
// debug setting
|
|
||||||
this.loadConfiguration();
|
|
||||||
|
|
||||||
LOG.d(TAG, "DroidGap.onCreate()");
|
LOG.d(TAG, "DroidGap.onCreate()");
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
@ -281,6 +274,11 @@ public class DroidGap extends Activity implements CordovaInterface {
|
|||||||
// Set up web container
|
// Set up web container
|
||||||
this.appView = webView;
|
this.appView = webView;
|
||||||
this.appView.setId(100);
|
this.appView.setId(100);
|
||||||
|
|
||||||
|
// Load Cordova configuration:
|
||||||
|
// white list of allowed URLs
|
||||||
|
// debug setting
|
||||||
|
this.loadConfiguration();
|
||||||
|
|
||||||
this.appView.setLayoutParams(new LinearLayout.LayoutParams(
|
this.appView.setLayoutParams(new LinearLayout.LayoutParams(
|
||||||
ViewGroup.LayoutParams.FILL_PARENT,
|
ViewGroup.LayoutParams.FILL_PARENT,
|
||||||
@ -1190,7 +1188,7 @@ public class DroidGap extends Activity implements CordovaInterface {
|
|||||||
String origin = xml.getAttributeValue(null, "origin");
|
String origin = xml.getAttributeValue(null, "origin");
|
||||||
String subdomains = xml.getAttributeValue(null, "subdomains");
|
String subdomains = xml.getAttributeValue(null, "subdomains");
|
||||||
if (origin != null) {
|
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")) {
|
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.
|
* Determine if URL is in approved list of URLs to load.
|
||||||
@ -1268,25 +1230,8 @@ public class DroidGap extends Activity implements CordovaInterface {
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public boolean isUrlWhiteListed(String url) {
|
public boolean isUrlWhiteListed(String url) {
|
||||||
|
|
||||||
// Check to see if we have matched url previously
|
// Check to see if we have matched url previously
|
||||||
if (whiteListCache.get(url) != null) {
|
return this.appView.isUrlWhiteListed(url);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
Reference in New Issue
Block a user