summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Miller <paulmiller@google.com>2015-04-02 21:54:09 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2015-04-02 21:54:10 +0000
commitb1da6cff83eab4f707456fbdb0d64f28d26c4889 (patch)
tree6fdc14a6952bcc43068d6cf773b0779b021e6386
parent36180ed8521a178ddf682a9cc831c072810d77ae (diff)
parentca7ecd85ac925ef44dbef327310f2baad13322f2 (diff)
downloadBrowser-b1da6cff83eab4f707456fbdb0d64f28d26c4889.tar.gz
Merge "Restrict "javascript" and "file" scheme intents"
-rw-r--r--AndroidManifest.xml11
-rw-r--r--src/com/android/browser/IntentHandler.java79
-rw-r--r--src/com/android/browser/Tab.java26
3 files changed, 61 insertions, 55 deletions
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index a90468bd..9ea41e6a 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -86,7 +86,6 @@
<data android:scheme="http" />
<data android:scheme="https" />
<data android:scheme="about" />
- <data android:scheme="javascript" />
</intent-filter>
<!-- For these schemes where any of these particular MIME types
have been supplied, we are a good candidate. -->
@@ -101,16 +100,6 @@
<data android:mimeType="application/xhtml+xml"/>
<data android:mimeType="application/vnd.wap.xhtml+xml"/>
</intent-filter>
- <!-- For viewing saved web archives. -->
- <intent-filter>
- <action android:name="android.intent.action.VIEW" />
- <category android:name="android.intent.category.BROWSABLE" />
- <category android:name="android.intent.category.DEFAULT" />
- <data android:scheme="http" />
- <data android:scheme="https" />
- <data android:scheme="file" />
- <data android:mimeType="application/x-webarchive-xml"/>
- </intent-filter>
<!-- Accept inbound NFC URLs at a low priority -->
<intent-filter android:priority="-101">
<action android:name="android.nfc.action.NDEF_DISCOVERED" />
diff --git a/src/com/android/browser/IntentHandler.java b/src/com/android/browser/IntentHandler.java
index 1b8dfc75..fbe7b25e 100644
--- a/src/com/android/browser/IntentHandler.java
+++ b/src/com/android/browser/IntentHandler.java
@@ -29,6 +29,7 @@ import android.os.Bundle;
import android.provider.Browser;
import android.provider.MediaStore;
import android.text.TextUtils;
+import android.util.Log;
import android.util.Patterns;
import com.android.browser.UI.ComboViews;
@@ -37,6 +38,7 @@ import com.android.common.Search;
import java.util.HashMap;
import java.util.Iterator;
+import java.util.Locale;
import java.util.Map;
/**
@@ -44,6 +46,8 @@ import java.util.Map;
*/
public class IntentHandler {
+ private static final String TAG = "IntentHandler";
+
// "source" parameter for Google search suggested by the browser
final static String GOOGLE_SEARCH_SOURCE_SUGGEST = "browser-suggest";
// "source" parameter for Google search from unknown source
@@ -51,6 +55,19 @@ public class IntentHandler {
/* package */ static final UrlData EMPTY_URL_DATA = new UrlData(null);
+ private static final String[] SCHEME_WHITELIST = {
+ "http",
+ "https",
+ "about",
+ };
+
+ // "file" is handled separately from other schemes and limited to certain directories -
+ // directories which do not support sym/hardlinks, to prevent trickery
+ private static final String[] FILE_WHITELIST = {
+ "/sdcard",
+ "/mnt/sdcard"
+ };
+
private Activity mActivity;
private Controller mController;
private TabControl mTabControl;
@@ -64,6 +81,12 @@ public class IntentHandler {
}
void onNewIntent(Intent intent) {
+ Uri uri = intent.getData();
+ if (uri != null && isForbiddenUri(uri)) {
+ Log.e(TAG, "Aborting intent with forbidden uri, \"" + uri + "\"");
+ return;
+ }
+
Tab current = mTabControl.getCurrentTab();
// When a tab is closed on exit, the current tab index is set to -1.
// Reset before proceed as Browser requires the current tab to be set.
@@ -107,33 +130,18 @@ public class IntentHandler {
urlData = new UrlData(mSettings.getHomePage());
}
- // If url is to view private data files, don't allow.
- Uri uri = intent.getData();
- if (uri != null && uri.getScheme().toLowerCase().startsWith("file") &&
- uri.getPath().startsWith(mActivity.getDatabasePath("foo").getParent())) {
- return;
- }
-
if (intent.getBooleanExtra(Browser.EXTRA_CREATE_NEW_TAB, false)
|| urlData.isPreloaded()) {
Tab t = mController.openTab(urlData);
return;
}
/*
- * TODO: Don't allow javascript URIs
- * 0) If this is a javascript: URI, *always* open a new tab
- * 1) If the URL is already opened, switch to that tab
- * 2-phone) Reuse tab with same appId
- * 2-tablet) Open new tab
+ * If the URL is already opened, switch to that tab
+ * phone: Reuse tab with same appId
+ * tablet: Open new tab
*/
final String appId = intent
.getStringExtra(Browser.EXTRA_APPLICATION_ID);
- if (!TextUtils.isEmpty(urlData.mUrl) &&
- urlData.mUrl.startsWith("javascript:")) {
- // Always open javascript: URIs in new tabs
- mController.openTab(urlData);
- return;
- }
if (Intent.ACTION_VIEW.equals(action)
&& (appId != null)
&& appId.startsWith(mActivity.getPackageName())) {
@@ -314,8 +322,41 @@ public class IntentHandler {
return true;
}
+ private static boolean isForbiddenUri(Uri uri) {
+ String scheme = uri.getScheme();
+ // Allow URIs with no scheme
+ if (scheme == null) {
+ return false;
+ }
+ scheme = scheme.toLowerCase(Locale.US);
+ if ("file".equals(scheme)) {
+ String path = uri.getPath();
+ // Deny file URIs with invalid paths
+ if (path == null) {
+ return true;
+ }
+
+ // Allow file URIs in certain directories
+ for (String allowed : FILE_WHITELIST) {
+ if (path.startsWith(allowed)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ // Allow certain schemes other than file
+ for (String allowed : SCHEME_WHITELIST) {
+ if (allowed.equals(scheme)) {
+ return false;
+ }
+ }
+ // Deny all other schemes
+ return true;
+ }
+
/**
- * A UrlData class to abstract how the content will be set to WebView.
+ * A UrlData class to abstract how the content will be sent to WebView.
* This base class uses loadUrl to show the content.
*/
static class UrlData {
diff --git a/src/com/android/browser/Tab.java b/src/com/android/browser/Tab.java
index dc1944e3..a4d2ce01 100644
--- a/src/com/android/browser/Tab.java
+++ b/src/com/android/browser/Tab.java
@@ -74,9 +74,7 @@ import com.android.browser.TabControl.OnThumbnailUpdatedListener;
import com.android.browser.homepages.HomeProvider;
import com.android.browser.provider.SnapshotProvider.Snapshots;
-import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
-import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.ByteBuffer;
@@ -105,8 +103,6 @@ class Tab implements PictureListener {
private static final int CAPTURE_DELAY = 100;
private static final int INITIAL_PROGRESS = 5;
- private static final String RESTRICTED = "<html><body>not allowed</body></html>";
-
private static Bitmap sDefaultFavicon;
private static Paint sAlphaPaint = new Paint();
@@ -609,27 +605,7 @@ class Tab implements PictureListener {
@Override
public WebResourceResponse shouldInterceptRequest(WebView view,
String url) {
- Uri uri = Uri.parse(url);
- if (uri.getScheme().toLowerCase().equals("file")) {
- File file = new File(uri.getPath());
- try {
- if (file.getCanonicalPath().startsWith(
- mContext.getApplicationContext().getApplicationInfo().dataDir)) {
- return new WebResourceResponse("text/html","UTF-8",
- new ByteArrayInputStream(RESTRICTED.getBytes("UTF-8")));
- }
- } catch (Exception ex) {
- Log.e(LOGTAG, "Bad canonical path" + ex.toString());
- try {
- return new WebResourceResponse("text/html","UTF-8",
- new ByteArrayInputStream(RESTRICTED.getBytes("UTF-8")));
- } catch (java.io.UnsupportedEncodingException e) {
- }
- }
- }
- WebResourceResponse res = HomeProvider.shouldInterceptRequest(
- mContext, url);
- return res;
+ return HomeProvider.shouldInterceptRequest(mContext, url);
}
@Override