Overview

Low
Severity
CVSS
No
Exploited ITW
Fixed
Fix Status
ImpactIncorrect security UI in Permissions
DescriptionIncorrect security UI in Permissions
ComponentPermissions
Bug ClassLogic Error
Tracker483899628
Fix commit848a7a9f1fee (chromium/src) +45/-4
CISA KEVNot listed
Crediteddaffainfo
Disclosed2026-04-07

Changed Functions

FunctionChangeNotes
TEST_F
chrome/browser/ui/content_settings/content_setting_bubble_model_unittest.cc
modified

Files Changed

  • chrome/browser/ui/content_settings/content_setting_bubble_model.cc
  • chrome/browser/ui/content_settings/content_setting_bubble_model_unittest.cc
From 848a7a9f1feeba1debc2abfc9b9b1b38ec2b28d1 Mon Sep 17 00:00:00 2001
From: Nathan Parker <nparker@chromium.org>
Date: Thu, 19 Feb 2026 08:18:27 -0800
Subject: [PATCH] Fix URL spoofing on "Pop-ups blocked" dialog in Chrome.

Switched to FormatUrl() which removes the username:password@ component.

Example of new formatting, with hover: http://screen/M4wV4PuQ4vu2zDr

Bug: 483899628
Change-Id: Iff473a1718f7f4662abddbeff29223973c7de845
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7577181
Reviewed-by: Ravjit Uppal <ravjit@chromium.org>
Commit-Queue: Nathan Parker <nparker@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1587161}
---

diff --git a/chrome/browser/ui/content_settings/content_setting_bubble_model.cc b/chrome/browser/ui/content_settings/content_setting_bubble_model.cc
index 306b3d8..45fc4ca6 100644
--- a/chrome/browser/ui/content_settings/content_setting_bubble_model.cc
+++ b/chrome/browser/ui/content_settings/content_setting_bubble_model.cc
@@ -68,6 +68,7 @@
 #include "components/subresource_filter/core/browser/subresource_filter_constants.h"
 #include "components/subresource_filter/core/browser/subresource_filter_features.h"
 #include "components/url_formatter/elide_url.h"
+#include "components/url_formatter/url_formatter.h"
 #include "components/vector_icons/vector_icons.h"
 #include "content/public/browser/page.h"
 #include "content/public/browser/permission_controller.h"
@@ -171,10 +172,12 @@
                                                       const GURL& url) {
   // Empty URLs should get a placeholder.
   // TODO(csharrison): See if we can DCHECK that the URL will be valid here.
-  std::u16string title = url.spec().empty()
-                             ? l10n_util::GetStringUTF16(IDS_TAB_LOADING_TITLE)
-                             : base::UTF8ToUTF16(url.spec());
-
+  std::u16string title =
+      url.spec().empty()
+          ? l10n_util::GetStringUTF16(IDS_TAB_LOADING_TITLE)
+          : url_formatter::FormatUrl(
+                url, url_formatter::kFormatUrlOmitUsernamePassword,
+                base::UnescapeRule::NONE, nullptr, nullptr, nullptr);
   // Format the title to include the unicode single dot bullet code-point
   // \u2022 and two spaces.
   title = l10n_util::GetStringFUTF16(IDS_LIST_BULLET, title);
diff --git a/chrome/browser/ui/content_settings/content_setting_bubble_model_unittest.cc b/chrome/browser/ui/content_settings/content_setting_bubble_model_unittest.cc
index 10f443bb..ae12051 100644
--- a/chrome/browser/ui/content_settings/content_setting_bubble_model_unittest.cc
+++ b/chrome/browser/ui/content_settings/content_setting_bubble_model_unittest.cc
@@ -1391,6 +1391,44 @@
   }
 }
 
+TEST_F(ContentSettingBubbleModelTest, PopupBubbleModelListItemsSpoofing) {
+  const GURL url("https://www.example.test/");
+  WebContentsTester::For(web_contents())->NavigateAndCommit(url);
+  blocked_content::PopupBlockerTabHelper::CreateForWebContents(web_contents());
+
+  // Malicious URL
+  GURL spoof_url("http://google.com:VeryLongString@evil.com");
+
+  BlockedWindowParams params(spoof_url, url::Origin(), nullptr,
+                             content::Referrer(), std::string(),
+                             WindowOpenDisposition::NEW_POPUP,
+                             blink::mojom::WindowFeatures(), false, true);
+
+  NavigateParams navigate_params =
+      params.CreateNavigateParams(process(), web_contents());
+  blocked_content::MaybeBlockPopup(
+      web_contents(), &url,
+      std::make_unique<ChromePopupNavigationDelegate>(
+          std::move(navigate_params)),
+      nullptr, params.features(),
+      HostContentSettingsMapFactory::GetForProfile(profile()));
+
+  std::unique_ptr<ContentSettingBubbleModel> content_setting_bubble_model(
+      ContentSettingBubbleModel::CreateContentSettingBubbleModel(
+          nullptr, web_contents(), ContentSettingsType::POPUPS));
+
+  const auto& list_items =
+      content_setting_bubble_model->bubble_content().list_items;
+  ASSERT_EQ(1U, list_items.size());
+
+  // Check the title
+  std::u16string title = list_items[0].title;
+  // It should NOT contain "google.com" if it's formatted correctly for
+  // security.
+  EXPECT_EQ(std::u16string::npos, title.find(u"google.com"));
+  EXPECT_NE(std::u16string::npos, title.find(u"evil.com"));
+}
+
 TEST_F(ContentSettingBubbleModelTest, ValidUrl) {
   WebContentsTester::For(web_contents())
       ->NavigateAndCommit(GURL("https://www.example.com"));
Loading diff…

Regression Test / PoC

shipped with the fix
diff --git a/chrome/browser/ui/content_settings/content_setting_bubble_model_unittest.cc b/chrome/browser/ui/content_settings/content_setting_bubble_model_unittest.cc
index 10f443bb..ae12051 100644
--- a/chrome/browser/ui/content_settings/content_setting_bubble_model_unittest.cc
+++ b/chrome/browser/ui/content_settings/content_setting_bubble_model_unittest.cc
@@ -1391,6 +1391,44 @@
   }
 }
 
+TEST_F(ContentSettingBubbleModelTest, PopupBubbleModelListItemsSpoofing) {
+  const GURL url("https://www.example.test/");
+  WebContentsTester::For(web_contents())->NavigateAndCommit(url);
+  blocked_content::PopupBlockerTabHelper::CreateForWebContents(web_contents());
+
+  // Malicious URL
+  GURL spoof_url("http://google.com:VeryLongString@evil.com");
+
+  BlockedWindowParams params(spoof_url, url::Origin(), nullptr,
+                             content::Referrer(), std::string(),
+                             WindowOpenDisposition::NEW_POPUP,
+                             blink::mojom::WindowFeatures(), false, true);
+
+  NavigateParams navigate_params =
+      params.CreateNavigateParams(process(), web_contents());
+  blocked_content::MaybeBlockPopup(
+      web_contents(), &url,
+      std::make_unique<ChromePopupNavigationDelegate>(
+          std::move(navigate_params)),
+      nullptr, params.features(),
+      HostContentSettingsMapFactory::GetForProfile(profile()));
+
+  std::unique_ptr<ContentSettingBubbleModel> content_setting_bubble_model(
+      ContentSettingBubbleModel::CreateContentSettingBubbleModel(
+          nullptr, web_contents(), ContentSettingsType::POPUPS));
+
+  const auto& list_items =
+      content_setting_bubble_model->bubble_content().list_items;
+  ASSERT_EQ(1U, list_items.size());
+
+  // Check the title
+  std::u16string title = list_items[0].title;
+  // It should NOT contain "google.com" if it's formatted correctly for
+  // security.
+  EXPECT_EQ(std::u16string::npos, title.find(u"google.com"));
+  EXPECT_NE(std::u16string::npos, title.find(u"evil.com"));
+}
+
 TEST_F(ContentSettingBubbleModelTest, ValidUrl) {
   WebContentsTester::For(web_contents())
       ->NavigateAndCommit(GURL("https://www.example.com"));
Loading diff…

Original Bug Report

reported by mu...@gmail.com

URL Spoofing on Block or allow pop-ups in Chrome

Steps to reproduce the problem

  1. Save this 2 HTML files (orig.html and fake.html) and analyze the link in the popup message, it looks the same
  2. Allow the popup
  3. The victim redirected to evil.com instead of google.com

Problem Description

When using window.open, Chrome shows a popup listing temporarily blocked URLs and waits for the user’s approval. If a suspicious URL is detected, the user can choose to keep it blocked. However, in this popup Chrome displays only the URL’s prefix and suffix. By inserting a malicious URL in the middle using @, an attacker can disguise it. If the user allows the popup, instead of opening a safe website, Chrome will open the malicious URL.

Summary

URL Spoofing on Block or allow pop-ups in Chrome

Additional Data

Category: Security
Chrome Channel: Not sure
Regression: N/A \

View on issue tracker