Medium chrome Logic Error 📄 Reporter bug report 🔧 Commit mapped

Overview

Medium
Severity
CVSS
No
Exploited ITW
Fixed
Fix Status
ImpactIncorrect security UI in PictureInPicture
DescriptionIncorrect security UI in PictureInPicture
ComponentPictureInPicture
Bug ClassLogic Error
Tracker474948986
Fix commit58a8c057b2b3 (chromium/src) +55/-5
CISA KEVNot listed
CreditedBarath Stalin K
Disclosed2026-03-10

Changed Functions

FunctionChangeNotes
GetFadeAnimatorForTesting
chrome/browser/ui/views/frame/picture_in_picture_browser_frame_view.cc
modified
FakeLinuxUiGetter
chrome/browser/ui/views/frame/picture_in_picture_browser_frame_view_interactive_uitest.cc
modified
TEST_F
chrome/browser/ui/views/overlay/video_overlay_window_views_unittest.cc
modified

Files Changed

  • chrome/browser/ui/views/frame/picture_in_picture_browser_frame_view.cc
  • chrome/browser/ui/views/frame/picture_in_picture_browser_frame_view.h
  • chrome/browser/ui/views/frame/picture_in_picture_browser_frame_view_interactive_uitest.cc
  • chrome/browser/ui/views/overlay/video_overlay_window_views.cc
  • chrome/browser/ui/views/overlay/video_overlay_window_views_unittest.cc
From 58a8c057b2b3b113e41ef8d8fb1228eb05d5a10c Mon Sep 17 00:00:00 2001
From: Benjamin Keen <bkeen@google.com>
Date: Tue, 20 Jan 2026 14:54:43 -0800
Subject: [PATCH] Set Pip window title directionality mode to DIRECTIONALITY_AS_URL

This change addresses a security UI spoofing vulnerability in both
Document and Video Picture-in-Picture (PiP) windows where Right-to-Left
Override (RTLO) characters in a malicious domain could cause the
displayed origin to appear as a trusted domain.

The fix ensures that the `views::Label` used for the PiP window title
always renders text in a Left-to-Right (LTR) direction. This is achieved
by setting the label directionality mode to `DIRECTIONALITY_AS_URL`, as
suggested in
https://chromium.googlesource.com/chromium/src/+/HEAD/docs/security/url_display_guidelines/url_display_guidelines.md#rtl

Bug: 474948986
Change-Id: I56298ea3f267dfb5be8509addb30bbd0b34f1163
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7488911
Reviewed-by: Fr <beaufort.francois@gmail.com>
Commit-Queue: Benjamin Keen <bkeen@google.com>
Cr-Commit-Position: refs/heads/main@{#1571906}
---

diff --git a/chrome/browser/ui/views/frame/picture_in_picture_browser_frame_view.cc b/chrome/browser/ui/views/frame/picture_in_picture_browser_frame_view.cc
index cf08191..41457ef5 100644
--- a/chrome/browser/ui/views/frame/picture_in_picture_browser_frame_view.cc
+++ b/chrome/browser/ui/views/frame/picture_in_picture_browser_frame_view.cc
@@ -48,6 +48,7 @@
 #include "ui/gfx/animation/animation.h"
 #include "ui/gfx/animation/animation_container.h"
 #include "ui/gfx/geometry/insets.h"
+#include "ui/gfx/text_constants.h"
 #include "ui/views/accessibility/view_accessibility.h"
 #include "ui/views/animation/animation_builder.h"
 #include "ui/views/animation/compositor_animation_runner.h"
@@ -595,9 +596,12 @@
 
   // Creates the window title.
   top_bar_container_view_->AddChildView(
-      views::Builder<views::Label>()
+      views::Builder<views::Label>(
+          std::make_unique<views::Label>(
+              location_bar_model_->GetURLForDisplay(),
+              views::style::CONTEXT_LABEL, views::style::STYLE_PRIMARY,
+              gfx::DirectionalityMode::DIRECTIONALITY_AS_URL))
           .CopyAddressTo(&window_title_)
-          .SetText(location_bar_model_->GetURLForDisplay())
           .SetHorizontalAlignment(gfx::ALIGN_LEFT)
           .SetElideBehavior(elide_behavior)
           .SetProperty(
@@ -1553,6 +1557,12 @@
   return window_title_;
 }
 
+void PictureInPictureBrowserFrameView::SetWindowTitleForTesting(  // IN-TEST
+    const std::u16string& title) {
+  CHECK(window_title_);
+  window_title_->SetText(title);
+}
+
 PictureInPictureWidgetFadeAnimator*
 PictureInPictureBrowserFrameView::GetFadeAnimatorForTesting() {
   return fade_animator_.get();
diff --git a/chrome/browser/ui/views/frame/picture_in_picture_browser_frame_view.h b/chrome/browser/ui/views/frame/picture_in_picture_browser_frame_view.h
index b307ae5..33aad98 100644
--- a/chrome/browser/ui/views/frame/picture_in_picture_browser_frame_view.h
+++ b/chrome/browser/ui/views/frame/picture_in_picture_browser_frame_view.h
@@ -184,6 +184,7 @@
   views::View* GetBackToTabButtonForTesting();
   views::View* GetCloseButtonForTesting();
   views::Label* GetWindowTitleForTesting();
+  void SetWindowTitleForTesting(const std::u16string& title);
   PictureInPictureWidgetFadeAnimator* GetFadeAnimatorForTesting();
 
   // These values are persisted to logs. Entries should not be renumbered and
diff --git a/chrome/browser/ui/views/frame/picture_in_picture_browser_frame_view_interactive_uitest.cc b/chrome/browser/ui/views/frame/picture_in_picture_browser_frame_view_interactive_uitest.cc
index 9b149cd..ac82d0d 100644
--- a/chrome/browser/ui/views/frame/picture_in_picture_browser_frame_view_interactive_uitest.cc
+++ b/chrome/browser/ui/views/frame/picture_in_picture_browser_frame_view_interactive_uitest.cc
@@ -4,6 +4,7 @@
 
 #include <optional>
 
+#include "base/i18n/rtl.h"
 #include "base/memory/raw_ptr.h"
 #include "base/run_loop.h"
 #include "base/scoped_observation.h"
@@ -1085,6 +1086,26 @@
                     /*include_app_name=*/false));
 }
 
+IN_PROC_BROWSER_TEST_F(PictureInPictureBrowserFrameViewTest,
+                       WindowTitleHasCorrectDirectionality) {
+  ASSERT_NO_FATAL_FAILURE(SetUpDocumentPIP());
+  views::Label* window_title = pip_frame_view()->GetWindowTitleForTesting();
+  ASSERT_NE(nullptr, window_title);
+
+  // The directionality should be LTR to prevent spoofing.
+  EXPECT_EQ(base::i18n::LEFT_TO_RIGHT,
+            window_title->GetTextDirectionForTesting());
+
+  // Set the window title to a RTL string.
+  const char16_t kRtl[] = u"אבג";
+  pip_frame_view()->SetWindowTitleForTesting(kRtl);
+  EXPECT_EQ(kRtl, window_title->GetText());
+
+  // The directionality should still be LTR.
+  EXPECT_EQ(base::i18n::LEFT_TO_RIGHT,
+            window_title->GetTextDirectionForTesting());
+}
+
 #if BUILDFLAG(IS_LINUX)
 
 class FakeLinuxUiGetter : public ui::LinuxUiGetter {
diff --git a/chrome/browser/ui/views/overlay/video_overlay_window_views.cc b/chrome/browser/ui/views/overlay/video_overlay_window_views.cc
index 8ccc5385..315bbdb 100644
--- a/chrome/browser/ui/views/overlay/video_overlay_window_views.cc
+++ b/chrome/browser/ui/views/overlay/video_overlay_window_views.cc
@@ -64,6 +64,7 @@
 #include "ui/gfx/favicon_size.h"
 #include "ui/gfx/geometry/resize_utils.h"
 #include "ui/gfx/geometry/skia_conversions.h"
+#include "ui/gfx/text_constants.h"
 #include "ui/views/controls/image_view.h"
 #include "ui/views/controls/label.h"
 #include "ui/views/widget/widget_delegate.h"
@@ -1107,9 +1108,9 @@
   auto favicon_view = std::make_unique<views::ImageView>();
   favicon_view->SetSize(kFaviconSize);
 
-  auto origin = std::make_unique<views::Label>(std::u16string(),
-                                               views::style::CONTEXT_LABEL,
-                                               views::style::STYLE_BODY_4);
+  auto origin = std::make_unique<views::Label>(
+      std::u16string(), views::style::CONTEXT_LABEL, views::style::STYLE_BODY_4,
+      gfx::DirectionalityMode::DIRECTIONALITY_AS_URL);
   origin->SetEnabledColor(ui::kColorSysOnSurface);
   origin->SetBackgroundColor(SK_ColorTRANSPARENT);
   origin->SetHorizontalAlignment(gfx::ALIGN_LEFT);
diff --git a/chrome/browser/ui/views/overlay/video_overlay_window_views_unittest.cc b/chrome/browser/ui/views/overlay/video_overlay_window_views_unittest.cc
index 6933ba2..0abc584 100644
--- a/chrome/browser/ui/views/overlay/video_overlay_window_views_unittest.cc
+++ b/chrome/browser/ui/views/overlay/video_overlay_window_views_unittest.cc
@@ -8,6 +8,7 @@
 #include <memory>
 #include <utility>
 
+#include "base/i18n/rtl.h"
 #include "base/memory/raw_ptr.h"
 #include "base/test/mock_callback.h"
 #include "base/test/scoped_feature_list.h"
@@ -1062,6 +1063,22 @@
   EXPECT_EQ(origin->GetText(), u"google.com");
 }
 
+TEST_F(VideoOverlayWindowViewsTest, OriginLabelHasCorrectDirectionality) {
+  views::Label* origin = overlay_window().origin_for_testing();
+  ASSERT_NE(nullptr, origin);
+
+  // The directionality should be LTR to prevent spoofing.
+  EXPECT_EQ(base::i18n::LEFT_TO_RIGHT, origin->GetTextDirectionForTesting());
+
+  // Set the source title to a RTL string.
+  const char16_t kRtl[] = u"אבג";
+  overlay_window().SetSourceTitle(kRtl);
+  EXPECT_EQ(kRtl, origin->GetText());
+
+  // The directionality should still be LTR to prevent spoofing.
+  EXPECT_EQ(base::i18n::LEFT_TO_RIGHT, origin->GetTextDirectionForTesting());
+}
+
 TEST_F(VideoOverlayWindowViewsTest,
        ControlsNeverHideWhileProgressBarIsDragged) {
   overlay_window().ShowInactive();
Loading diff…

Regression Test / PoC

shipped with the fix
diff --git a/chrome/browser/ui/views/frame/picture_in_picture_browser_frame_view_interactive_uitest.cc b/chrome/browser/ui/views/frame/picture_in_picture_browser_frame_view_interactive_uitest.cc
index 9b149cd..ac82d0d 100644
--- a/chrome/browser/ui/views/frame/picture_in_picture_browser_frame_view_interactive_uitest.cc
+++ b/chrome/browser/ui/views/frame/picture_in_picture_browser_frame_view_interactive_uitest.cc
@@ -4,6 +4,7 @@
 
 #include <optional>
 
+#include "base/i18n/rtl.h"
 #include "base/memory/raw_ptr.h"
 #include "base/run_loop.h"
 #include "base/scoped_observation.h"
@@ -1085,6 +1086,26 @@
                     /*include_app_name=*/false));
 }
 
+IN_PROC_BROWSER_TEST_F(PictureInPictureBrowserFrameViewTest,
+                       WindowTitleHasCorrectDirectionality) {
+  ASSERT_NO_FATAL_FAILURE(SetUpDocumentPIP());
+  views::Label* window_title = pip_frame_view()->GetWindowTitleForTesting();
+  ASSERT_NE(nullptr, window_title);
+
+  // The directionality should be LTR to prevent spoofing.
+  EXPECT_EQ(base::i18n::LEFT_TO_RIGHT,
+            window_title->GetTextDirectionForTesting());
+
+  // Set the window title to a RTL string.
+  const char16_t kRtl[] = u"אבג";
+  pip_frame_view()->SetWindowTitleForTesting(kRtl);
+  EXPECT_EQ(kRtl, window_title->GetText());
+
+  // The directionality should still be LTR.
+  EXPECT_EQ(base::i18n::LEFT_TO_RIGHT,
+            window_title->GetTextDirectionForTesting());
+}
+
 #if BUILDFLAG(IS_LINUX)
 
 class FakeLinuxUiGetter : public ui::LinuxUiGetter {
diff --git a/chrome/browser/ui/views/overlay/video_overlay_window_views_unittest.cc b/chrome/browser/ui/views/overlay/video_overlay_window_views_unittest.cc
index 6933ba2..0abc584 100644
--- a/chrome/browser/ui/views/overlay/video_overlay_window_views_unittest.cc
+++ b/chrome/browser/ui/views/overlay/video_overlay_window_views_unittest.cc
@@ -8,6 +8,7 @@
 #include <memory>
 #include <utility>
 
+#include "base/i18n/rtl.h"
 #include "base/memory/raw_ptr.h"
 #include "base/test/mock_callback.h"
 #include "base/test/scoped_feature_list.h"
@@ -1062,6 +1063,22 @@
   EXPECT_EQ(origin->GetText(), u"google.com");
 }
 
+TEST_F(VideoOverlayWindowViewsTest, OriginLabelHasCorrectDirectionality) {
+  views::Label* origin = overlay_window().origin_for_testing();
+  ASSERT_NE(nullptr, origin);
+
+  // The directionality should be LTR to prevent spoofing.
+  EXPECT_EQ(base::i18n::LEFT_TO_RIGHT, origin->GetTextDirectionForTesting());
+
+  // Set the source title to a RTL string.
+  const char16_t kRtl[] = u"אבג";
+  overlay_window().SetSourceTitle(kRtl);
+  EXPECT_EQ(kRtl, origin->GetText());
+
+  // The directionality should still be LTR to prevent spoofing.
+  EXPECT_EQ(base::i18n::LEFT_TO_RIGHT, origin->GetTextDirectionForTesting());
+}
+
 TEST_F(VideoOverlayWindowViewsTest,
        ControlsNeverHideWhileProgressBarIsDragged) {
   overlay_window().ShowInactive();
Loading diff…

Original Bug Report

reported by se...@gmail.com

Chrome Windows - PIP Window Displays Incorrect Origin When Domain Uses RTL Characters


Report description

Chrome Windows - PIP Window Displays Incorrect Origin When Domain Uses RTL Characters


Bug location

Where do you want to report your vulnerability?

Chrome VRP – Report security issues affecting the Chrome browser. See program rules


The problem

Please describe the technical details of the vulnerability

Summary

When a website uses Right-to-Left Override (RTLO) characters in its subdomain, the browser’s Picture-in-Picture (PiP) window displays an incorrect and misleading origin. Instead of showing the attacker-controlled root domain (eTLD+1), the PiP UI renders a spoofed trusted domain, allowing origin impersonation.

Steps to Reproduce

  1. Register or host a domain containing RTLO characters in the subdomain. POC URL:http://xn–mgb.accounts.login.apple.com.xn–mgb.https.google.com.summa.sbs/test.html
  2. Click the PIP button
  3. Observe the origin shown in the PiP window.
  4. Notice that the displayed origin shows a spoofed trusted domain (apple.com.I) instead of the real eTLD+1 (summa.sbs)

Expected Behavior The PiP window should always display the actual eTLD+1 of the media’s origin and sanitize or neutralize RTL characters to prevent misleading rendering.

Actual Behavior The PiP UI renders RTL characters in a way that causes the origin to appear as a different, trusted domain, hiding the attacker-controlled root domain.

Proof of Concept Displayed in PiP: apple.com.I

Actual media origin: summa.sbs

Impact analysis

An attacker can abuse RTL characters in a domain to make the Picture-in-Picture (PiP) window display a trusted brand name (for example, apple.com) while the actual content is served from an attacker-controlled domain (summa.sbs). Since PiP is a trusted, persistent UI element, users are likely to rely on the displayed origin for trust decisions. This enables convincing phishing, social-engineering, and malware delivery scenarios, as users may interact with or trust content believing it originates from a legitimate site. The absence of any alternative way to verify the true origin further increases the risk of exploitation.

Refer: https://issues.chromium.org/issues/40065117 https://issues.chromium.org/issues/40066780


The cause

What version of Chrome have you found the security issue in?

Version 143.0.7499.193 (Official Build) (64-bit)

No, it is not related to a crash.

Choose the type of vulnerability

Security UI Spoofing

How would you like to be publicly acknowledged for your report?

Barath Stalin K (https://www.linkedin.com/in/barathstalin/)

View on issue tracker