Chrome · Voice
CVE-2026-113164
Memory Corruption in Voice
Overview
Medium
Severity
—
CVSS
No
Exploited ITW
Fixed
Fix Status
Changed Functions
| Function | Change | Notes |
|---|---|---|
ifchrome/android/java/src/org/chromium/chrome/browser/IntentHandler.java |
modified |
Files Changed
chrome/android/java/src/org/chromium/chrome/browser/IntentHandler.javachrome/android/javatests/src/org/chromium/chrome/browser/IntentHandlerBrowserTest.java
Patch
From f2e24c37ecb1148590bbec98d98a11b483d77f5d Mon Sep 17 00:00:00 2001 From: Sky Malice <[email protected]> Date: Fri, 18 Sep 2026 10:56:21 -0700 Subject: [PATCH] Validate voice search and share intent result URLs Ensure URLs derived from voice search results and share intent extras are validated via isUrlUnsafe() before returning them. When candidate URLs from intent extras or AutocompleteCoordinator classification fail validation, fall back to generating a search query URL using the default search engine template. TAG=agy CONV=92dacbf6-8488-4ddc-8241-e41babdc8a4c Bug: 500497398 Change-Id: I395567db24acd0f4ec484b757ef9f5246b286c4e Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/8421858 Reviewed-by: Tomasz Wiszkowski <[email protected]> Commit-Queue: Sky Malice <[email protected]> Cr-Commit-Position: refs/heads/main@{#1700953} --- diff --git a/chrome/android/java/src/org/chromium/chrome/browser/IntentHandler.java b/chrome/android/java/src/org/chromium/chrome/browser/IntentHandler.java index 632a1e37..54e78075 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/IntentHandler.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/IntentHandler.java @@ -836,18 +836,23 @@ AutocompleteMatch match = AutocompleteCoordinator.classify(profile, query); assert match != null; - if (!match.isSearchSuggestion()) return match.getUrl().getSpec(); + if (!match.isSearchSuggestion() + && !ExternalIntentUrlChecker.isUnsafeExternalIntentUrl(match.getUrl())) { + return match.getUrl().getSpec(); + } List<String> urls = IntentUtils.safeGetStringArrayListExtra( intent, RecognizerResultsIntent.EXTRA_VOICE_SEARCH_RESULT_URLS); - if (urls != null && urls.size() > 0) { - return urls.get(0); - } else { - return TemplateUrlServiceFactory.getForProfile(profile) - .getUrlForVoiceSearchQuery(query) - .getSpec(); + if (urls != null && !urls.isEmpty()) { + String url = urls.get(0); + if (!TextUtils.isEmpty(url) && !isUrlUnsafe(url)) { + return url; + } } + return TemplateUrlServiceFactory.getForProfile(profile) + .getUrlForVoiceSearchQuery(query) + .getSpec(); } /** @@ -1381,7 +1386,7 @@ Profile profile = ProfileManager.getLastUsedRegularProfile(); AutocompleteMatch match = AutocompleteCoordinator.classify(profile, text); - if (match != null) { + if (match != null && !ExternalIntentUrlChecker.isUnsafeExternalIntentUrl(match.getUrl())) { urls.add(match.getUrl().getSpec()); return urls; } diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/IntentHandlerBrowserTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/IntentHandlerBrowserTest.java index ef68a07b..b5c42772 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/IntentHandlerBrowserTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/IntentHandlerBrowserTest.java @@ -22,6 +22,7 @@ import org.chromium.base.test.BaseJUnit4ClassRunner; import org.chromium.base.test.util.Batch; import org.chromium.base.test.util.Feature; +import org.chromium.components.embedder_support.util.UrlConstants; import org.chromium.content_public.browser.test.NativeLibraryTestUtils; import org.chromium.url.JUnitTestGURLs; @@ -84,6 +85,43 @@ @Test @MediumTest @UiThreadTest + @Feature({"Android-AppBase"}) + public void testGetQueryFromVoiceSearchResultIntent_internalResultUrl() { + Intent intent = new Intent(RecognizerResultsIntent.ACTION_VOICE_SEARCH_RESULTS); + intent.putStringArrayListExtra( + RecognizerResultsIntent.EXTRA_VOICE_SEARCH_RESULT_STRINGS, + new ArrayList<>(Collections.singletonList(VOICE_SEARCH_QUERY))); + intent.putStringArrayListExtra( + RecognizerResultsIntent.EXTRA_VOICE_SEARCH_RESULT_URLS, + new ArrayList<>(Collections.singletonList(UrlConstants.VERSION_URL))); + String url = IntentHandler.getUrlFromVoiceSearchResult(intent); + Assert.assertNotNull(url); + Assert.assertFalse( + "Supplied internal URL should not be used: " + url, + url.startsWith(UrlConstants.CHROME_SCHEME)); + assertThat(url, startsWith(VOICE_SEARCH_QUERY_URL)); + } + + @Test + @MediumTest + @UiThreadTest + @Feature({"Android-AppBase"}) + public void testGetQueryFromVoiceSearchResultIntent_internalUrlQuery() { + Intent intent = new Intent(RecognizerResultsIntent.ACTION_VOICE_SEARCH_RESULTS); + intent.putStringArrayListExtra( + RecognizerResultsIntent.EXTRA_VOICE_SEARCH_RESULT_STRINGS, + new ArrayList<>(Collections.singletonList(UrlConstants.VERSION_URL))); + String url = IntentHandler.getUrlFromVoiceSearchResult(intent); + Assert.assertNotNull(url); + Assert.assertFalse( + "Internal URL query should fall back to search: " + url, + url.startsWith(UrlConstants.CHROME_SCHEME)); + assertThat(url, startsWith("https://www.google.com/search?q=")); + } + + @Test + @MediumTest + @UiThreadTest public void testGetURLFromShareIntent_validURL() { Intent intent = new Intent(Intent.ACTION_SEND); intent.putExtra(Intent.EXTRA_TEXT, JUnitTestGURLs.EXAMPLE_URL.getSpec()); @@ -106,6 +144,21 @@ @Test @MediumTest @UiThreadTest + public void testGetURLFromShareIntent_internalUrl() { + Intent intent = new Intent(Intent.ACTION_SEND); + intent.putExtra(Intent.EXTRA_TEXT, UrlConstants.VERSION_URL); + intent.setType("text/plain"); + String url = IntentHandler.getUrlFromShareIntent(intent); + Assert.assertNotNull(url); + Assert.assertFalse( + "Internal URL share should fall back to search: " + url, + url.startsWith(UrlConstants.CHROME_SCHEME)); + assertThat(url, startsWith("https://www.google.com/search?q=")); + } + + @Test + @MediumTest + @UiThreadTest public void testGetURLFromShareIntent_plainText() { Intent intent = new Intent(Intent.ACTION_SEND); intent.putExtra(Intent.EXTRA_TEXT, "test");
Loading diff…
Original Bug Report
The reporter's bug is still restricted on the tracker. Chrome de-restricts security bugs ~30–90 days after the fix ships; a later run will backfill it here.
References
On This Page