CVE-2026-95292
Overview
Background
- Site familiarity
- Chrome’s Safe Browsing signal that decides whether a navigation target is “familiar” to the user, which governs whether the renderer process is granted the V8 optimizing tiers.
- DSE (Default Search Engine)
- the user’s configured search provider, whose search-results URLs are treated as inherently familiar via a fast-path that skips the normal deferral and history check.
- `ExtractSearchTermsFromURL`
- a
TemplateURLRefmethod used to recognize a DSE search URL that compares only host, port and path, never the URL scheme. - `SchemeIsCryptographic`
- a
GURLpredicate that returns true only for cryptographic schemes such ashttps, used by the fix to gate the DSE fast-path.
Root Cause Analysis
The vulnerable path is in SiteFamiliarityFetcher::Start in site_familiarity_fetcher.cc, where a navigation is short-circuited to “familiar” whenever kSkipSiteFamiliarityDeferralForDefaultSearchEngine is enabled and IsDefaultSearchEngineUrl(fetch_url_, profile_) returns true. Because IsDefaultSearchEngineUrl relies on TemplateURLRef::ExtractSearchTermsFromURL, which matches only host, port and path and ignores the scheme, an http:// URL with the DSE’s host and path is misidentified as the DSE. The violated invariant is that the “familiar” fast-path must apply only to the genuine, secure DSE origin, not to any scheme sharing its host and path. An on-path (network) attacker can therefore serve http://<dse-host>/<dse-path> and inherit the DSE’s familiar verdict, obtaining a renderer with V8 optimizing tiers enabled that would otherwise be withheld from an unfamiliar site.
The fix adds fetch_url_.SchemeIsCryptographic() as an additional precondition, so the fast-path is taken only for cryptographic-scheme URLs and insecure HTTP navigations fall back to normal deferral and the history-based familiarity check.
SchemeIsCryptographic() before granting the fast-path.Attack Path
- Position on the network
An on-path attacker intercepts the victim’s plaintext HTTP traffic, able to serve content for arbitrary
http://hosts. - Serve a DSE look-alike over HTTP
The attacker responds to
http://<dse-host>/<dse-path>so the navigation’s host, port and path match the configured default search engine while the scheme is insecure. - Inherit the familiar verdict
IsDefaultSearchEngineUrlmatches viaExtractSearchTermsFromURL(scheme-blind), soSiteFamiliarityFetcher::Starttakes the fast-path and marks the attacker’s page familiar, skipping deferral and the history check. - Obtain an optimized renderer The familiar verdict grants the renderer the V8 optimizing tiers that an unfamiliar site would not receive.
- Leverage optimized V8 as a broader attack surface (inferred) With the optimizing tiers enabled, the attacker-controlled page runs in a renderer whose V8 attack surface is larger, easing further exploitation.
Impact Assessment
kSkipSiteFamiliarityDeferralForDefaultSearchEngine feature being enabled. The advisory classifies this as incorrect authorization in Safe Browsing and does not state exploited-in-the-wild status; any escalation from the optimized renderer to memory corruption or code execution is (inferred) rather than demonstrated by the patch.Files Changed
chrome/browser/site_protection/site_familiarity_fetcher.ccchrome/browser/site_protection/site_familiarity_process_selection_deferring_condition_unittest.cc
Audit Directions
- Scheme-blind identity matchingAudit other callers of
ExtractSearchTermsFromURLandIsDefaultSearchEngineUrl(and similar host/path comparisons) that make security decisions without also checking the scheme or origin. - Trust fast-paths gated on partial URL fieldsReview any code that skips deferral, familiarity, or Safe Browsing checks based on a URL matching a trusted target, confirming the match includes scheme and full origin, not just host/port/path.
- Feature-flag-gated authorization shortcutsExamine other
base::FeatureList-guarded shortcuts that bypass normal security checks (e.g.,kSkipSiteFamiliarityDeferralForDefaultSearchEngine) for missing cryptographic-scheme or origin preconditions.
Patch
From 3611fb3173dc8ee282575797b8f0269b5a442e7b Mon Sep 17 00:00:00 2001
From: Javier Castro <jacastro@chromium.org>
Date: Tue, 18 Aug 2026 09:04:14 -0700
Subject: [PATCH] Require cryptographic scheme for DSE fast-path in SiteFamiliarityFetcher
TemplateURLRef::ExtractSearchTermsFromURL only compares host, port and
path, but does not compare scheme. Restrict the fast-path to
cryptographic schemes so an on-path attacker serving
http://<dse-host>/<dse-path> cannot inherit the DSE's "familiar" verdict
and obtain a renderer with the V8 optimizing tiers enabled.
Fixed: 513781838
TAG=agy
CONV=22e0f5f6-8a43-49d2-9165-df7d153ab58d
Change-Id: I1ed81e3dd3ae49945dae2becc0f373533ee1bac8
Bug: 513781838
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/8263180
Reviewed-by: Tiffany Song <tiffanysong@google.com>
Commit-Queue: Javier Castro <jacastro@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1681438}
---
diff --git a/chrome/browser/site_protection/site_familiarity_fetcher.cc b/chrome/browser/site_protection/site_familiarity_fetcher.cc
index 214eb28b..bc04c7e 100644
--- a/chrome/browser/site_protection/site_familiarity_fetcher.cc
+++ b/chrome/browser/site_protection/site_familiarity_fetcher.cc
@@ -114,6 +114,12 @@
if (base::FeatureList::IsEnabled(
kSkipSiteFamiliarityDeferralForDefaultSearchEngine) &&
+ // TemplateURLRef::ExtractSearchTermsFromURL only compares host, port and
+ // path; it never compares scheme. Restrict the fast-path to cryptographic
+ // schemes so an on-path attacker serving http://<dse-host>/<dse-path>
+ // cannot inherit the DSE's "familiar" verdict and obtain a renderer with
+ // the V8 optimizing tiers enabled.
+ fetch_url_.SchemeIsCryptographic() &&
IsDefaultSearchEngineUrl(fetch_url_, profile_)) {
// Assume the default search engine search results are familiar to the user.
CRSBLOG << "SiteFamiliarityFetcher::Start [URL]: " << fetch_url_
diff --git a/chrome/browser/site_protection/site_familiarity_process_selection_deferring_condition_unittest.cc b/chrome/browser/site_protection/site_familiarity_process_selection_deferring_condition_unittest.cc
index f02f0a3..fd5aae3 100644
--- a/chrome/browser/site_protection/site_familiarity_process_selection_deferring_condition_unittest.cc
+++ b/chrome/browser/site_protection/site_familiarity_process_selection_deferring_condition_unittest.cc
@@ -1036,6 +1036,31 @@
CheckSiteFamiliar(navigation_handle);
}
+// Test that an insecure HTTP navigation matching the DSE search URL is deferred
+// and is unfamiliar, rather than taking the DSE fast-path.
+TEST_F(SiteFamiliarityDefaultSearchEngineSkipFamiliarityCheckTest,
+ InsecureHttpSearchUrl) {
+ GURL kHttpSearchUrl("http://www.example.com/search?q=test2");
+ SetSiteEngagementScore(kHttpSearchUrl,
+ kMinSiteEngagementScoreForFamiliarity - 1);
+ content::MockNavigationHandle navigation_handle(kHttpSearchUrl, main_rfh());
+ base::HistogramTester histogram_tester;
+ MockConditionCallback callback;
+ SiteFamiliarityProcessSelectionDeferringCondition condition(
+ navigation_handle);
+
+ EXPECT_EQ(content::ProcessSelectionDeferringCondition::Result::kDefer,
+ condition.OnWillSelectFinalProcess(callback.Get()));
+
+ // Complete history fetch.
+ raw_ptr<ManualCallbackEmptyHistoryService> mock_history_service =
+ static_cast<ManualCallbackEmptyHistoryService*>(history_service());
+ mock_history_service->RunNextCallback();
+ CheckSiteUnfamiliar(navigation_handle);
+ histogram_tester.ExpectTotalCount(
+ kSiteFamiliarityDeferNavigationDurationHistogram, 1);
+}
+
// Test that a navigation to a non-search page on the DSE's origin is deferred
// and is unfamiliar.
TEST_F(SiteFamiliarityDefaultSearchEngineSkipFamiliarityCheckTest,
Regression Test / PoC
diff --git a/chrome/browser/site_protection/site_familiarity_process_selection_deferring_condition_unittest.cc b/chrome/browser/site_protection/site_familiarity_process_selection_deferring_condition_unittest.cc
index f02f0a3..fd5aae3 100644
--- a/chrome/browser/site_protection/site_familiarity_process_selection_deferring_condition_unittest.cc
+++ b/chrome/browser/site_protection/site_familiarity_process_selection_deferring_condition_unittest.cc
@@ -1036,6 +1036,31 @@
CheckSiteFamiliar(navigation_handle);
}
+// Test that an insecure HTTP navigation matching the DSE search URL is deferred
+// and is unfamiliar, rather than taking the DSE fast-path.
+TEST_F(SiteFamiliarityDefaultSearchEngineSkipFamiliarityCheckTest,
+ InsecureHttpSearchUrl) {
+ GURL kHttpSearchUrl("http://www.example.com/search?q=test2");
+ SetSiteEngagementScore(kHttpSearchUrl,
+ kMinSiteEngagementScoreForFamiliarity - 1);
+ content::MockNavigationHandle navigation_handle(kHttpSearchUrl, main_rfh());
+ base::HistogramTester histogram_tester;
+ MockConditionCallback callback;
+ SiteFamiliarityProcessSelectionDeferringCondition condition(
+ navigation_handle);
+
+ EXPECT_EQ(content::ProcessSelectionDeferringCondition::Result::kDefer,
+ condition.OnWillSelectFinalProcess(callback.Get()));
+
+ // Complete history fetch.
+ raw_ptr<ManualCallbackEmptyHistoryService> mock_history_service =
+ static_cast<ManualCallbackEmptyHistoryService*>(history_service());
+ mock_history_service->RunNextCallback();
+ CheckSiteUnfamiliar(navigation_handle);
+ histogram_tester.ExpectTotalCount(
+ kSiteFamiliarityDeferNavigationDurationHistogram, 1);
+}
+
// Test that a navigation to a non-search page on the DSE's origin is deferred
// and is unfamiliar.
TEST_F(SiteFamiliarityDefaultSearchEngineSkipFamiliarityCheckTest,