Index: chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappLauncherActivity.java |
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappLauncherActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappLauncherActivity.java |
index 61777d059362a5bd6fa71c98329e9c1ab0712881..8a624c4a4d943d3180def2308c5b20859de6c62f 100644 |
--- a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappLauncherActivity.java |
+++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappLauncherActivity.java |
@@ -23,7 +23,7 @@ import org.chromium.chrome.browser.document.ChromeLauncherActivity; |
import org.chromium.chrome.browser.metrics.LaunchMetrics; |
import org.chromium.chrome.browser.tab.Tab; |
import org.chromium.chrome.browser.util.IntentUtils; |
-import org.chromium.webapk.lib.common.WebApkConstants; |
+import org.chromium.webapk.lib.client.WebApkValidator; |
import java.lang.ref.WeakReference; |
@@ -58,25 +58,18 @@ public class WebappLauncherActivity extends Activity { |
int webappSource = webappInfo.source(); |
if (webappId != null && webappUrl != null) { |
- String webappMacString = IntentUtils.safeGetStringExtra( |
- intent, ShortcutHelper.EXTRA_MAC); |
- byte[] webappMac = |
- webappMacString == null ? null : Base64.decode(webappMacString, Base64.DEFAULT); |
- |
Intent launchIntent = null; |
- // Permit the launch to a standalone web app frame if the intent was sent by Chrome, or |
- // if the MAC is present and valid for the URL to be opened. |
- boolean isTrusted = IntentHandler.wasIntentSenderChrome(intent, |
- ContextUtils.getApplicationContext()); |
- boolean isUrlValid = (webappMac != null |
- && WebappAuthenticator.isUrlValid(this, webappUrl, webappMac)); |
- boolean isValidWebApk = isValidWebApk(webApkPackageName); |
- if (webApkPackageName != null && !isValidWebApk) { |
- isUrlValid = false; |
- } |
+ // Permit the launch to a standalone web app frame if any of the following are true: |
+ // - the request was for a WebAPK that is valid; |
+ // - the MAC is present and valid for the homescreen shortcut to be opened; |
+ // - the intent was sent by Chrome. |
+ boolean isValidWebApk = isValidWebApk(webApkPackageName, webappUrl); |
- if (isTrusted || isUrlValid) { |
+ if (isValidWebApk |
+ || isValidMacForUrl(webappUrl, IntentUtils.safeGetStringExtra( |
+ intent, ShortcutHelper.EXTRA_MAC)) |
+ || wasIntentFromChrome(intent)) { |
LaunchMetrics.recordHomeScreenLaunchIntoStandaloneActivity(webappUrl, webappSource); |
launchIntent = createWebappLaunchIntent(webappInfo, isValidWebApk); |
} else { |
@@ -99,6 +92,25 @@ public class WebappLauncherActivity extends Activity { |
} |
/** |
+ * Checks whether or not the MAC is present and valid for the web app shortcut. |
+ * |
+ * The MAC is used to prevent malicious apps from launching Chrome into a full screen |
+ * Activity for phishing attacks (among other reasons). |
+ * |
+ * @param url The URL for the web app. |
+ * @param mac MAC to compare the URL against. See {@link WebappAuthenticator}. |
+ * @return Whether the MAC is valid for the URL. |
+ */ |
+ private boolean isValidMacForUrl(String url, String mac) { |
+ return mac != null |
+ && WebappAuthenticator.isUrlValid(this, url, Base64.decode(mac, Base64.DEFAULT)); |
+ } |
+ |
+ private boolean wasIntentFromChrome(Intent intent) { |
+ return IntentHandler.wasIntentSenderChrome(intent, ContextUtils.getApplicationContext()); |
+ } |
+ |
+ /** |
* Creates an Intent to launch the web app. |
* @param info Information about the web app. |
* @param isWebApk If true, launch the app as a WebApkActivity. If false, launch the app as |
@@ -157,15 +169,26 @@ public class WebappLauncherActivity extends Activity { |
} |
/** |
- * Checks whether the package being targeted is a valid WebAPK. |
- * @param webapkPackageName The package name of the requested WebAPK. |
+ * Checks whether the package being targeted is a valid WebAPK and whether the url supplied |
+ * can be fulfilled by that WebAPK. |
+ * |
+ * @param webApkPackage The package name of the requested WebAPK. |
+ * @param url The url to navigate to. |
* @return true iff all validation criteria are met. |
*/ |
- private boolean isValidWebApk(String webapkPackageName) { |
- // TODO(hanxi): Adds more validation checks. For example, whether the WebAPK is signed |
- // by the WebAPK Minting Server. |
- return CommandLine.getInstance().hasSwitch(ChromeSwitches.ENABLE_WEBAPK) |
- && webapkPackageName != null |
- && webapkPackageName.startsWith(WebApkConstants.WEBAPK_PACKAGE_PREFIX); |
+ private boolean isValidWebApk(String webApkPackage, String url) { |
+ if (!CommandLine.getInstance().hasSwitch(ChromeSwitches.ENABLE_WEBAPK) |
+ || webApkPackage == null) { |
+ return false; |
+ } |
+ if (!WebApkValidator.isValidWebApk(this, webApkPackage)) { |
+ Log.d(TAG, "%s is not valid WebAPK", webApkPackage); |
+ return false; |
+ } |
+ if (!webApkPackage.equals(WebApkValidator.queryWebApkPackage(this, url))) { |
+ Log.d(TAG, "%s is not within scope of %s WebAPK", url, webApkPackage); |
+ return false; |
+ } |
+ return true; |
} |
} |