Overview

High
Severity
CVSS
No
Exploited ITW
Fixed
Fix Status
ImpactInsufficient validation of untrusted input in iOS
DescriptionInsufficient validation of untrusted input in iOS
ComponentChromium
Bug ClassLogic Error
Tracker503862359
Fix commitc1bb5bb34b47 (chromium/src) +1/-1
CISA KEVNot listed
CreditedGoogle
Disclosed2026-05-27

Files Changed

  • ios/chrome/browser/search_engines/model/search_engine_tab_helper.mm
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;
   }
 
Loading diff…

Original Bug Report

reported by [email protected]

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.

  1. Renderer Compromise: An attacker exploits a vulnerability in the iOS WebKit renderer process (com.apple.WebKit.WebContent).
  2. Forged IPC Message: From the compromised renderer, the attacker sends a forged SearchEngineMessage IPC directly to the browser process via internal WebKit messaging. This bypasses the native search_engine.ts content script (which would normally sanitize the URL into a non-executable format) and targets the kIsolatedWorld message handler.
  3. Malicious Payload: The message uses the searchableUrl command with a payload like {"command": "searchableUrl", "url": "javascript:alert(document.domain)//{searchTerms}"}.
  4. Browser Processing: SearchEngineJavaScriptFeature::ScriptMessageReceived extracts the URL and passes it to SearchEngineTabHelper. Upon the next navigation completion, AddTemplateURLBySearchableURL accepts the URL because searchable_url.is_valid() returns true.
  5. Database Registration: TemplateURLService::CanAddAutogeneratedKeyword permits the addition because javascript: URLs lack a host component (url.GetHost().empty() evaluates to true). The search engine is then persisted in the user’s local database.
  6. User Execution: The user later types the auto-generated keyword followed by a space and a query into the Omnibox.
  7. UXSS Trigger: SearchProvider::Start resolves the match, directly substituting {searchTerms} while preserving the javascript: scheme. When the suggestion is selected, LocationBarCoordinator::loadGURLFromLocationBar recognizes the scheme and explicitly calls LoadJavaScriptURL(...), executing the attacker’s script in the context of the active tab.

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

View on issue tracker