CVE-2026-9950
Overview
Files Changed
ios/chrome/browser/search_engines/model/search_engine_tab_helper.mm
Patch
From c1bb5bb34b479e31a052389d8b532a1984963d91 Mon Sep 17 00:00:00 2001 From: Andrew Paseltiner <[email protected]> Date: Fri, 24 Apr 2026 10:28:44 -0700 Subject: [PATCH] [iOS] Add scheme validation for auto-generated search engines SearchEngineTabHelper::AddTemplateURLBySearchableURL lacked scheme validation, allowing malicious renderers to register javascript: URLs as search engines. This could lead to UXSS. This appears to be an oversight, as other methods in the same file, such as AddTemplateURLByOSDD and GenerateKeywordFromNavigationItem, already correctly restrict schemes to HTTP/HTTPS. This CL adds a check to ensure the URL scheme is HTTP or HTTPS in AddTemplateURLBySearchableURL. Fixed: 503862359 Change-Id: I54f6b4fa558d17d92b38dad41c7416eb481ee18e Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7781599 Reviewed-by: Jérôme Lebel <[email protected]> Commit-Queue: Andrew Paseltiner <[email protected]> Cr-Commit-Position: refs/heads/main@{#1620308} --- diff --git a/ios/chrome/browser/search_engines/model/search_engine_tab_helper.mm b/ios/chrome/browser/search_engines/model/search_engine_tab_helper.mm index cbda250..23db603 100644 --- a/ios/chrome/browser/search_engines/model/search_engine_tab_helper.mm +++ b/ios/chrome/browser/search_engines/model/search_engine_tab_helper.mm @@ -180,7 +180,7 @@ // https://cs.chromium.org/chromium/src/chrome/browser/ui/search_engines/search_engine_tab_helper.cc void SearchEngineTabHelper::AddTemplateURLBySearchableURL( const GURL& searchable_url) { - if (!searchable_url.is_valid()) { + if (!searchable_url.is_valid() || !searchable_url.SchemeIsHTTPOrHTTPS()) { return; }
Original Bug Report
Potential UXSS via Missing Scheme Validation in iOS SearchEngineTabHelper
Flapjack, an experimental security project, has identified the following potential security issue. If you’re a feature owner CC-ed on this bug, please do your best to review these reports without the Chrome Security team. Please see go/chrome-ai-generated-security-bugs-faq for more information.
Overview: The SearchEngineTabHelper on iOS lacks scheme validation when adding auto-generated search engines. A compromised renderer can register a malicious javascript: URL as a search engine. If a user subsequently searches using the generated keyword, the JavaScript payload executes in the context of the active tab, leading to Universal Cross-Site Scripting (UXSS).
Affected files:
ios/chrome/browser/search_engines/model/search_engine_tab_helper.mm
Estimated timestamp from git blame: 2018-11-07
Description
A potential missing scheme validation vulnerability exists in SearchEngineTabHelper::AddTemplateURLBySearchableURL on iOS. This function registers auto-generated search engines based on IPC messages from the renderer. While it checks if the provided searchable_url is valid using is_valid(), it fails to ensure the scheme is restricted to safe protocols like HTTP or HTTPS. Because javascript: URLs are considered structurally valid by the GURL parser, they can bypass this check.
If a compromised renderer process directly sends a forged SearchEngineMessage bypassing the normal JS content script sanitization, it can inject a javascript: URL into the TemplateURL service. Once registered, if the user types the associated keyword into the Omnibox and selects the suggestion, the javascript: payload is executed in the context of the currently active tab. This provides a sandbox escape leading to Universal Cross-Site Scripting (UXSS) across arbitrary web origins.
Potential Attack Steps
Note: These are suggested steps based on static code analysis. Our tooling agent cannot execute code to dynamically verify a working proof-of-concept.
- Renderer Compromise: An attacker exploits a vulnerability in the iOS WebKit renderer process (
com.apple.WebKit.WebContent). - Forged IPC Message: From the compromised renderer, the attacker sends a forged
SearchEngineMessageIPC directly to the browser process via internal WebKit messaging. This bypasses the nativesearch_engine.tscontent script (which would normally sanitize the URL into a non-executable format) and targets thekIsolatedWorldmessage handler. - Malicious Payload: The message uses the
searchableUrlcommand with a payload like{"command": "searchableUrl", "url": "javascript:alert(document.domain)//{searchTerms}"}. - Browser Processing:
SearchEngineJavaScriptFeature::ScriptMessageReceivedextracts the URL and passes it toSearchEngineTabHelper. Upon the next navigation completion,AddTemplateURLBySearchableURLaccepts the URL becausesearchable_url.is_valid()returnstrue. - Database Registration:
TemplateURLService::CanAddAutogeneratedKeywordpermits the addition becausejavascript:URLs lack a host component (url.GetHost().empty()evaluates totrue). The search engine is then persisted in the user’s local database. - User Execution: The user later types the auto-generated keyword followed by a space and a query into the Omnibox.
- UXSS Trigger:
SearchProvider::Startresolves the match, directly substituting{searchTerms}while preserving thejavascript:scheme. When the suggestion is selected,LocationBarCoordinator::loadGURLFromLocationBarrecognizes the scheme and explicitly callsLoadJavaScriptURL(...), executing the attacker’s script in the context of the active tab.
Recommended Fix
In ios/chrome/browser/search_engines/model/search_engine_tab_helper.mm, update AddTemplateURLBySearchableURL to explicitly require HTTP or HTTPS schemes:
if (!searchable_url.is_valid() || !searchable_url.SchemeIsHTTPOrHTTPS()) {
return;
}
Evaluated with Chrome root at commit: c1eba8ce379f5d218a2948fafbb5dd72cfa30529
Results so far have been promising, but there can be wrong deductions. If this proves to be a false positive, please close as WAI; data from false positives will be used to improve accuracy over time. And please feel free to reach out to me directly if you have concerns or feedback on the project.
Raised in root component due to access or custom field issues on 1974931