Low watch CVSS 4.2 chrome Logic Error 📄 Reporter bug report 🔧 Commit mapped

Overview

Low
Severity
4.2
CVSS
No
Exploited ITW
Fixed
Fix Status
ImpactScript injection in UI
DescriptionScript injection in UI
ComponentUI
Bug ClassLogic Error
Action tierwatch — logic/policy bug — security-relevant, no memory-unsafety
Computed by PatchGap's deterministic exploitability ruler from the fixing commit. patch-now = RCE-class & attacker-reachable in a default config, or exploited in the wild; watch = real security signal below that bar; noise = no security relevance.
Tracker498417031
Fix commitb920b51115d9 (chromium/src) +9/-2
CWECWE-94
CVSS vectorCVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:L/I:L/A:N
CISA KEVNot listed
CreditedGoogle
Reported2026-04-01 (per vendor advisory)
Fix landed2026-04-01 (public git)
Disclosed2026-05-05
Patch gap34 days — fix public in source before the advisory

Background

Home button
the toolbar control whose target URL is stored in the prefs::kHomePage preference and loaded in the current tab when clicked.
`javascript:` URL
a pseudo-scheme (url::kJavaScriptScheme) whose body is executed as script in the context of the page it is navigated to.
Drag-and-drop URL drop
dropping a link onto a UI target hands the target a ui::ClipboardUrlInfo list via event.data().GetURLs(...).
Self-XSS
tricking a user into injecting script into their own session, here by making a javascript: URL the persistent home page.

Root Cause Analysis

The drop handler that updates the home page read the first dropped URL, asserted only that it was valid (CHECK(url_infos.front().url.is_valid())), and wrote it directly into prefs::kHomePage. No scheme filtering was applied, so a javascript: URL dragged onto the home button was accepted and stored as the home page. On a later Home-button click the stored javascript: URL would execute as script in whatever document was then loaded, giving script injection.

The fix captures new_homepage and returns early when new_homepage.SchemeIs(url::kJavaScriptScheme), so the dangerous scheme is rejected before any preference is written; the validity CHECK is kept, just moved up.

The patch TIGHTENS the accepted-input set (a scheme is now disallowed that was previously allowed).

Key insight
The home-page drop path validated only URL well-formedness, not scheme, allowing a persisted javascript: home page; the fix adds an explicit kJavaScriptScheme rejection before prefs_->SetString(prefs::kHomePage, ...).

Attack Path

  1. Craft a `javascript:` link The attacker presents a page containing a draggable link whose href is a javascript: payload.
  2. Social-engineer a drop The user is induced to drag that link onto the toolbar home button, invoking the drop handler with the javascript: URL as url_infos.front().url.
  3. Persist as home page Pre-patch, the handler stores the javascript: URL into prefs::kHomePage and sets kHomePageIsNewTabPage to false, making it the standing home page.
  4. Trigger execution When the user later clicks Home, the stored javascript: URL runs as script in the active document’s context, achieving self-XSS.

Impact Assessment

The advisory rates this low severity (Script injection in UI). An attacker gains script execution that the user triggers against their own browser (self-XSS) only after persuading the user to drag a crafted link onto the home button, so exploitation requires meaningful user interaction. No sandbox escape or cross-origin compromise is demonstrated by the patch.

Files Changed

  • chrome/browser/ui/views/toolbar/home_button.cc

Audit Directions

  • URL sinks that validate only `is_valid()`
    Search UI code that persists or navigates to user-supplied URLs; a validity check is not a scheme check, so each needs an explicit allow/deny of javascript: (and data:/blob: where relevant).
  • Drag-and-drop URL acceptors
    Review other drop targets (home button, bookmarks, tabs, profile prefs) that accept GetURLs(...) output for consistent dangerous-scheme filtering.
  • Preference-backed navigations
    Audit preferences that later become navigation targets (home page, startup pages, new-tab overrides) for scheme sanitization at write time, not just at read time.
From b920b51115d9574401ecbee912839eabe622707e Mon Sep 17 00:00:00 2001
From: Mike West <[email protected]>
Date: Wed, 01 Apr 2026 07:35:10 -0700
Subject: [PATCH] Prevent setting `javascript:` home page URLs.

We allow `javascript:` URLs to be dragged into the bookmark bar, but
we probably shouldn't allow the same for the home button. This CL adds a
check to `HomeButton::UpdateHomePage()` to exclude those URLs.

Bug: 498417031
Change-Id: I4f895e99340327156e53af6a4dbd6fcbd2c936e3
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7717841
Reviewed-by: Elly FJ <[email protected]>
Commit-Queue: Mike West <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1608519}
---

diff --git a/chrome/browser/ui/views/toolbar/home_button.cc b/chrome/browser/ui/views/toolbar/home_button.cc
index 09e1f7a..ba1b420 100644
--- a/chrome/browser/ui/views/toolbar/home_button.cc
+++ b/chrome/browser/ui/views/toolbar/home_button.cc
@@ -184,11 +184,18 @@
   const std::vector<ui::ClipboardUrlInfo> url_infos =
       event.data().GetURLs(ui::FilenameToURLPolicy::CONVERT_FILENAMES);
   if (!url_infos.empty() && prefs_) {
+    GURL new_homepage = url_infos.front().url;
+    CHECK(new_homepage.is_valid());
+
+    // Disallow javascript: URLs to prevent self-XSS.
+    if (new_homepage.SchemeIs(url::kJavaScriptScheme)) {
+      return;
+    }
+
     GURL old_homepage(prefs_->GetString(prefs::kHomePage));
     bool old_is_ntp = prefs_->GetBoolean(prefs::kHomePageIsNewTabPage);
 
-    CHECK(url_infos.front().url.is_valid());
-    prefs_->SetString(prefs::kHomePage, url_infos.front().url.spec());
+    prefs_->SetString(prefs::kHomePage, new_homepage.spec());
     prefs_->SetBoolean(prefs::kHomePageIsNewTabPage, false);
 
     coordinator_.Show(old_homepage, old_is_ntp);
Loading diff…

Original Bug Report

reported by [email protected]

Persistent Cross-Device UXSS via Home Button Drag-and-Drop

Project Fortify, 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 security team.

Overview: The Home button’s drag-and-drop handler fails to filter javascript: URLs when setting the home page preference. This allows an attacker to persistently set a malicious javascript: payload as the user’s home page, which executes in the context of the active tab (UXSS) when the user navigates home.

Affected files:

  • chrome/browser/ui/views/toolbar/home_button.cc
  • chrome/browser/ui/views/frame/browser_root_view.cc
  • ui/views/widget/drop_helper.cc
  • content/browser/renderer_host/render_widget_host_impl.cc
  • third_party/blink/renderer/core/frame/local_frame.cc

Estimated timestamp from git blame: 2026-01-26

Summary

There is a potential Persistent Universal Cross-Site Scripting (UXSS) vulnerability in the HomeButton component (chrome/browser/ui/views/toolbar/home_button.cc). By dragging a javascript: URL onto the Home button, an attacker can set it as the user’s home page preference (prefs::kHomePage). Because this preference is synced across devices, the payload becomes persistent and multi-device. When the user later triggers the ‘Home’ action (via click or Alt+Home), the javascript: URL is executed in the context of the currently active tab, bypassing Content Security Policy (CSP).

Vulnerability Details

  1. Missing Scheme Filter in HomeButton: When a user drags a URL onto the Home button, the HomeButton::CanDrop method returns true for any valid URL data. This causes the Views DropHelper to stop its upward traversal, bypassing the safety filters in BrowserRootView::FilterURLsForDropability that explicitly block javascript: URLs to prevent self-XSS.
  2. Unsafe Preference Write: HomeButton::UpdateHomePage then writes the dropped URL to prefs::kHomePage using only a CHECK(is_valid()) validation. It fails to perform scheme filtering, allowing javascript: URLs to be saved.
  3. Cross-Device Sync: The kHomePage preference is a SYNCABLE_PREF. The malicious URL is synchronized to all other desktop Chrome instances where the user is signed in.
  4. Trigger and Execution: When the user clicks the Home button, Home() (chrome/browser/ui/browser_commands.cc) reads the home page URL and calls OpenURL with is_renderer_initiated = false.
  5. Debug URL Processing: NavigationControllerImpl sees the javascript: URL, identifies it as a renderer-debug URL (blink::IsRendererDebugURL), and routes it to HandleRendererDebugURL.
  6. UXSS: The URL is sent via Mojo to the renderer’s LocalFrame::LoadJavaScriptURL. The script executes in the MainWorld of the current page with CSPDisposition::DO_NOT_CHECK, resulting in UXSS on the active tab’s origin.

Potential Reproduction Steps

Please note: our tooling agent cannot run code, so these are suggested steps to verify the vulnerability.

  1. Enable ‘Show Home button’ in chrome://settings/appearance.
  2. Create and navigate to an attacker-controlled page with a draggable link containing a javascript: payload: <a href="javascript:alert('UXSS: ' + document.domain)" draggable="true">Drag me to the Home button</a>.
  3. Drag the link onto the Home button in the browser toolbar.
  4. Navigate to a sensitive website (e.g., https://example.com).
  5. Press Alt+Home or click the Home button.
  6. Observe that the JavaScript execution occurs in the context of the current site’s origin.

Suggested Fix

Modify HomeButton::CanDrop or HomeButton::UpdateHomePage to explicitly filter out javascript: URLs, similar to the existing protection in BrowserRootView::FilterURLsForDropability. For example:

void HomeButton::UpdateHomePage(...) {
  // ... existing code ...
  if (!url_infos.empty() && prefs_) {
    GURL new_homepage = url_infos.front().url;
    // Fix: Disallow javascript: URLs to prevent UXSS.
    if (new_homepage.SchemeIs(url::kJavaScriptScheme)) {
      return;
    }
    CHECK(new_homepage.is_valid());
    prefs_->SetString(prefs::kHomePage, new_homepage.spec());
    // ...

Evaluated with Chrome root at commit: ff3d2b74fa39431785bd60e51463b08fcc71ee33


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.

View on issue tracker