CVE-2025-3068
Overview
Files Changed
components/external_intents/android/external_intents_features.cccomponents/external_intents/android/external_intents_features.hcomponents/external_intents/android/java/src/org/chromium/components/external_intents/ExternalIntentsFeatures.javacomponents/external_intents/android/java/src/org/chromium/components/external_intents/ExternalNavigationHandler.javacomponents/external_intents/android/javatests/src/org/chromium/components/external_intents/ExternalNavigationHandlerTest.java
Patch
From 720a32bd47d3188bbf824743147bc17de31de8c4 Mon Sep 17 00:00:00 2001 From: Ken Buchanan <[email protected]> Date: Thu, 20 Mar 2025 11:10:50 -0700 Subject: [PATCH] Normalize intent URIs for external navigations This is a follow-up to https://chromium-review.googlesource.com/c/chromium/src/+/6367258. Intent URIs will now be normalized to lower case. There is a flag to act as a kill switch if any breakage results. Bug: 401823929 Change-Id: I9346c8ed2f80469c81bebfe192d9a88d1dfebcae Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6367784 Commit-Queue: Ken Buchanan <[email protected]> Reviewed-by: Michael Thiessen <[email protected]> Cr-Commit-Position: refs/heads/main@{#1435559} --- diff --git a/components/external_intents/android/external_intents_features.cc b/components/external_intents/android/external_intents_features.cc index 6c81905..afae110f 100644 --- a/components/external_intents/android/external_intents_features.cc +++ b/components/external_intents/android/external_intents_features.cc @@ -26,7 +26,7 @@ // Array of features exposed through the Java ExternalIntentsFeatures API. const base::Feature* const kFeaturesExposedToJava[] = { &kExternalNavigationDebugLogs, &kBlockFrameRenavigations, - &kBlockIntentsToSelf}; + &kBlockIntentsToSelf, &kLowerCaseIntentSchemes}; } // namespace @@ -44,6 +44,11 @@ "BlockIntentsToSelf", base::FEATURE_ENABLED_BY_DEFAULT); +// Enabled by default in M136. +BASE_FEATURE(kLowerCaseIntentSchemes, + "LowerCaseIntentSchemes", + base::FEATURE_ENABLED_BY_DEFAULT); + static jlong JNI_ExternalIntentsFeatures_GetFeature(JNIEnv* env, jint ordinal) { return reinterpret_cast<jlong>(kFeaturesExposedToJava[ordinal]); } diff --git a/components/external_intents/android/external_intents_features.h b/components/external_intents/android/external_intents_features.h index 1c7535d..9644a25 100644 --- a/components/external_intents/android/external_intents_features.h +++ b/components/external_intents/android/external_intents_features.h @@ -13,6 +13,9 @@ BASE_DECLARE_FEATURE(kBlockFrameRenavigations); BASE_DECLARE_FEATURE(kBlockIntentsToSelf); +// When enabled, forces intent schemes to be lower case. +BASE_DECLARE_FEATURE(kLowerCaseIntentSchemes); + } // namespace external_intents #endif // COMPONENTS_EXTERNAL_INTENTS_ANDROID_EXTERNAL_INTENTS_FEATURES_H_ diff --git a/components/external_intents/android/java/src/org/chromium/components/external_intents/ExternalIntentsFeatures.java b/components/external_intents/android/java/src/org/chromium/components/external_intents/ExternalIntentsFeatures.java index e2e4578..fab0065 100644 --- a/components/external_intents/android/java/src/org/chromium/components/external_intents/ExternalIntentsFeatures.java +++ b/components/external_intents/android/java/src/org/chromium/components/external_intents/ExternalIntentsFeatures.java @@ -23,6 +23,7 @@ public static final String EXTERNAL_NAVIGATION_DEBUG_LOGS_NAME = "ExternalNavigationDebugLogs"; public static final String BLOCK_FRAME_RENAVIGATIONS_NAME = "BlockFrameRenavigations3"; public static final String BLOCK_INTENTS_TO_SELF_NAME = "BlockIntentsToSelf"; + public static final String LOWER_CASE_INTENT_SCHEMES_NAME = "LowerCaseIntentSchemes"; public static final ExternalIntentsFeatures EXTERNAL_NAVIGATION_DEBUG_LOGS = new ExternalIntentsFeatures(0, EXTERNAL_NAVIGATION_DEBUG_LOGS_NAME); @@ -33,6 +34,9 @@ public static final ExternalIntentsFeatures BLOCK_INTENTS_TO_SELF = new ExternalIntentsFeatures(2, BLOCK_INTENTS_TO_SELF_NAME); + public static final ExternalIntentsFeatures LOWER_CASE_INTENT_SCHEMES = + new ExternalIntentsFeatures(3, LOWER_CASE_INTENT_SCHEMES_NAME); + private final int mOrdinal; private ExternalIntentsFeatures(int ordinal, String name) { diff --git a/components/external_intents/android/java/src/org/chromium/components/external_intents/ExternalNavigationHandler.java b/components/external_intents/android/java/src/org/chromium/components/external_intents/ExternalNavigationHandler.java index c7ebed0..58e81d3 100644 --- a/components/external_intents/android/java/src/org/chromium/components/external_intents/ExternalNavigationHandler.java +++ b/components/external_intents/android/java/src/org/chromium/components/external_intents/ExternalNavigationHandler.java @@ -1824,6 +1824,12 @@ // Intent Selectors allow intents to bypass the intent filter and potentially send apps URIs // they were not expecting to handle. https://crbug.com/1254422 intent.setSelector(null); + + // Intent schemes should be normalized to lower case. https://crbug.com/401823929 + if (ExternalIntentsFeatures.LOWER_CASE_INTENT_SCHEMES.isEnabled() + && intent.getData() != null) { + intent.setDataAndType(intent.getData().normalizeScheme(), intent.getType()); + } } /** diff --git a/components/external_intents/android/javatests/src/org/chromium/components/external_intents/ExternalNavigationHandlerTest.java b/components/external_intents/android/javatests/src/org/chromium/components/external_intents/ExternalNavigationHandlerTest.java index ce43bf8..ae11749 100644 --- a/components/external_intents/android/javatests/src/org/chromium/components/external_intents/ExternalNavigationHandlerTest.java +++ b/components/external_intents/android/javatests/src/org/chromium/components/external_intents/ExternalNavigationHandlerTest.java @@ -1999,8 +1999,8 @@ .expecting( OverrideUrlLoadingResultType.OVERRIDE_WITH_EXTERNAL_INTENT, START_OTHER_ACTIVITY); - // Schemes on Android are case-sensitive, so ensure the scheme is passed through as-is. - Assert.assertEquals("w3irD", mUrlHandler.mStartActivityIntent.getScheme()); + // Intent schemes should be normalized. + Assert.assertEquals("w3ird", mUrlHandler.mStartActivityIntent.getScheme()); } @Test
Original Bug Report
intent:// can bypass fido:/ URI bock (see: 370482421)
VULNERABILITY DETAILS It’s possbile to bypass the fix for 370482421 by using a intent URI.
VERSION Chrome Version: 133.0.6943.137 stable Operating System: Pixel 7 Pro Android 15 March security updates.
REPRODUCTION CASE See https://issues.chromium.org/issues/370482421 for the original discussion. TL;DR: A website should not be allowed to open FIDO:/ URLs on mobile devices.
The issue is that the original fix was never tested on intent:// URLs. The original fix is a case sensitive check on the intent, it checks for “fido” and not “FIDO”. I have attached a html file whit a POC link that will start FIDO activity when clicked. The file also includes links that are blocked and the console output when clicked.
The fix seams to be fairly straight forward. Use a case insensitive match like what “hasFileSchemeInIntentURI” dose. See attached diff.
CREDIT INFORMATION Externally reported security bugs may appear in Chrome release notes. If this bug is included, how would you like to be credited? Reporter credit: [goes here]