Medium chrome Logic Error 📄 Reporter bug report 🔧 Commit mapped

Overview

Medium
Severity
CVSS
No
Exploited ITW
Fixed
Fix Status
ImpactInappropriate implementation in Media
DescriptionInappropriate implementation in Media
ComponentMedia
Bug ClassLogic Error
Tracker420734141
Fix commit74e314f5f71c (chromium/src) +78/-0
CISA KEVNot listed
CreditedAmeen Basha M K
Disclosed2025-09-30

Changed Functions

FunctionChangeNotes
Extension
chrome/browser/media/webrtc/display_media_access_handler.h
modified
DisplayMediaAccessHandler
chrome/browser/media/webrtc/display_media_access_handler.h
modified
TEST_F
chrome/browser/media/webrtc/display_media_access_handler_unittest.cc
modified

Files Changed

  • chrome/browser/media/webrtc/display_media_access_handler.cc
  • chrome/browser/media/webrtc/display_media_access_handler.h
  • chrome/browser/media/webrtc/display_media_access_handler_unittest.cc
  • testing/variations/fieldtrial_testing_config.json
From 74e314f5f71cc35cc723bbfe940c09d2559a764a Mon Sep 17 00:00:00 2001
From: Tove Petersson <tovep@chromium.org>
Date: Tue, 02 Sep 2025 06:02:50 -0700
Subject: [PATCH] Reject getDisplayMedia calls from domains longer than 255 characters

This change is gated by the DisplayMediaRejectLongDomains feature-flag.

Bug: 420734141
Change-Id: I6e117c4a4ae27786e2096a0da8bb0cb2e8cf6ae7
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6905222
Reviewed-by: Elad Alon <eladalon@chromium.org>
Commit-Queue: Tove Petersson <tovep@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1509516}
---

diff --git a/chrome/browser/media/webrtc/display_media_access_handler.cc b/chrome/browser/media/webrtc/display_media_access_handler.cc
index 860c3f27..3cf02f53 100644
--- a/chrome/browser/media/webrtc/display_media_access_handler.cc
+++ b/chrome/browser/media/webrtc/display_media_access_handler.cc
@@ -63,6 +63,10 @@
 #include "chrome/browser/glic/host/guest_util.h"
 #endif
 
+BASE_FEATURE(kDisplayMediaRejectLongDomains,
+             "DisplayMediaRejectLongDomains",
+             base::FEATURE_DISABLED_BY_DEFAULT);
+
 namespace {
 using ::blink::mojom::MediaStreamRequestResult;
 using ::content::DesktopMediaID;
@@ -491,6 +495,17 @@
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
   DCHECK(web_contents);
 
+  // Reject captures for domains with more than 255 characters.
+  //
+  // Note, this check does not fully account for international characters, but
+  // since the puny-encodings of international domains are limited to 255 bytes,
+  // it is unlikely that valid domains are excluded by this check.
+  if (base::FeatureList::IsEnabled(kDisplayMediaRejectLongDomains) &&
+      GetApplicationTitle(web_contents).size() > 255u) {
+    RejectRequest(web_contents, MediaStreamRequestResult::INVALID_STATE);
+    return;
+  }
+
   WebContents* ui_web_contents = web_contents;
 
 #if defined(TOOLKIT_VIEWS)
diff --git a/chrome/browser/media/webrtc/display_media_access_handler.h b/chrome/browser/media/webrtc/display_media_access_handler.h
index 9d8a877..d7a7151 100644
--- a/chrome/browser/media/webrtc/display_media_access_handler.h
+++ b/chrome/browser/media/webrtc/display_media_access_handler.h
@@ -25,6 +25,8 @@
 class Extension;
 }
 
+BASE_DECLARE_FEATURE(kDisplayMediaRejectLongDomains);
+
 // MediaAccessHandler for getDisplayMedia API, see
 // https://w3c.github.io/mediacapture-screen-share.
 class DisplayMediaAccessHandler : public CaptureAccessHandlerBase,
diff --git a/chrome/browser/media/webrtc/display_media_access_handler_unittest.cc b/chrome/browser/media/webrtc/display_media_access_handler_unittest.cc
index 4e834c2..e86da0b5 100644
--- a/chrome/browser/media/webrtc/display_media_access_handler_unittest.cc
+++ b/chrome/browser/media/webrtc/display_media_access_handler_unittest.cc
@@ -9,6 +9,7 @@
 #include <string>
 #include <utility>
 
+#include "base/feature_list.h"
 #include "base/functional/bind.h"
 #include "base/memory/raw_ptr.h"
 #include "base/run_loop.h"
@@ -334,6 +335,48 @@
   EXPECT_EQ(0u, blink::CountDevices(devices));
 }
 
+TEST_F(DisplayMediaAccessHandlerTest, MaxLengthDomainAccepted) {
+  base::test::ScopedFeatureList feature_list;
+  feature_list.InitAndEnableFeature(kDisplayMediaRejectLongDomains);
+
+  std::unique_ptr<content::NavigationSimulator> navigation =
+      content::NavigationSimulator::CreateBrowserInitiated(
+          GURL("https://" + std::string(255, 'a')), web_contents());
+  navigation->Commit();
+
+  blink::mojom::MediaStreamRequestResult result;
+  blink::mojom::StreamDevices devices;
+  ProcessRequest(content::DesktopMediaID(content::DesktopMediaID::TYPE_WINDOW,
+                                         content::DesktopMediaID::kFakeId),
+                 &result, devices, false /* request_audio */);
+
+  EXPECT_THAT(
+      result,
+      testing::AnyOf(
+#if BUILDFLAG(IS_MAC)
+          // TODO(crbug.com/40802122): Fix screen-capture permissions on mac.
+          blink::mojom::MediaStreamRequestResult::PERMISSION_DENIED_BY_SYSTEM,
+#endif
+          blink::mojom::MediaStreamRequestResult::OK));
+}
+
+TEST_F(DisplayMediaAccessHandlerTest, OverMaxLengthDomainRejected) {
+  base::test::ScopedFeatureList feature_list;
+  feature_list.InitAndEnableFeature(kDisplayMediaRejectLongDomains);
+
+  std::unique_ptr<content::NavigationSimulator> navigation =
+      content::NavigationSimulator::CreateBrowserInitiated(
+          GURL("https://" + std::string(256, 'a')), web_contents());
+  navigation->Commit();
+
+  blink::mojom::MediaStreamRequestResult result;
+  blink::mojom::StreamDevices devices;
+  ProcessRequest(content::DesktopMediaID(content::DesktopMediaID::TYPE_WINDOW,
+                                         content::DesktopMediaID::kFakeId),
+                 &result, devices, false /* request_audio */);
+  EXPECT_EQ(blink::mojom::MediaStreamRequestResult::INVALID_STATE, result);
+}
+
 #if BUILDFLAG(IS_CHROMEOS)
 TEST_F(DisplayMediaAccessHandlerTest, DlpRestricted) {
   const content::DesktopMediaID media_id(content::DesktopMediaID::TYPE_SCREEN,
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json
index d1acfd9..55485ba1 100644
--- a/testing/variations/fieldtrial_testing_config.json
+++ b/testing/variations/fieldtrial_testing_config.json
@@ -9248,6 +9248,24 @@
             ]
         }
     ],
+    "DisplayMediaRejectLongDomains": [
+        {
+            "platforms": [
+                "chromeos",
+                "linux",
+                "mac",
+                "windows"
+            ],
+            "experiments": [
+                {
+                    "name": "Enabled",
+                    "enable_features": [
+                        "DisplayMediaRejectLongDomains"
+                    ]
+                }
+            ]
+        }
+    ],
     "DlpRegionalizedEndpoints": [
         {
             "platforms": [
Loading diff…

Regression Test / PoC

shipped with the fix
diff --git a/chrome/browser/media/webrtc/display_media_access_handler_unittest.cc b/chrome/browser/media/webrtc/display_media_access_handler_unittest.cc
index 4e834c2..e86da0b5 100644
--- a/chrome/browser/media/webrtc/display_media_access_handler_unittest.cc
+++ b/chrome/browser/media/webrtc/display_media_access_handler_unittest.cc
@@ -9,6 +9,7 @@
 #include <string>
 #include <utility>
 
+#include "base/feature_list.h"
 #include "base/functional/bind.h"
 #include "base/memory/raw_ptr.h"
 #include "base/run_loop.h"
@@ -334,6 +335,48 @@
   EXPECT_EQ(0u, blink::CountDevices(devices));
 }
 
+TEST_F(DisplayMediaAccessHandlerTest, MaxLengthDomainAccepted) {
+  base::test::ScopedFeatureList feature_list;
+  feature_list.InitAndEnableFeature(kDisplayMediaRejectLongDomains);
+
+  std::unique_ptr<content::NavigationSimulator> navigation =
+      content::NavigationSimulator::CreateBrowserInitiated(
+          GURL("https://" + std::string(255, 'a')), web_contents());
+  navigation->Commit();
+
+  blink::mojom::MediaStreamRequestResult result;
+  blink::mojom::StreamDevices devices;
+  ProcessRequest(content::DesktopMediaID(content::DesktopMediaID::TYPE_WINDOW,
+                                         content::DesktopMediaID::kFakeId),
+                 &result, devices, false /* request_audio */);
+
+  EXPECT_THAT(
+      result,
+      testing::AnyOf(
+#if BUILDFLAG(IS_MAC)
+          // TODO(crbug.com/40802122): Fix screen-capture permissions on mac.
+          blink::mojom::MediaStreamRequestResult::PERMISSION_DENIED_BY_SYSTEM,
+#endif
+          blink::mojom::MediaStreamRequestResult::OK));
+}
+
+TEST_F(DisplayMediaAccessHandlerTest, OverMaxLengthDomainRejected) {
+  base::test::ScopedFeatureList feature_list;
+  feature_list.InitAndEnableFeature(kDisplayMediaRejectLongDomains);
+
+  std::unique_ptr<content::NavigationSimulator> navigation =
+      content::NavigationSimulator::CreateBrowserInitiated(
+          GURL("https://" + std::string(256, 'a')), web_contents());
+  navigation->Commit();
+
+  blink::mojom::MediaStreamRequestResult result;
+  blink::mojom::StreamDevices devices;
+  ProcessRequest(content::DesktopMediaID(content::DesktopMediaID::TYPE_WINDOW,
+                                         content::DesktopMediaID::kFakeId),
+                 &result, devices, false /* request_audio */);
+  EXPECT_EQ(blink::mojom::MediaStreamRequestResult::INVALID_STATE, result);
+}
+
 #if BUILDFLAG(IS_CHROMEOS)
 TEST_F(DisplayMediaAccessHandlerTest, DlpRestricted) {
   const content::DesktopMediaID media_id(content::DesktopMediaID::TYPE_SCREEN,
Loading diff…

Original Bug Report

reported by am...@gmail.com

Screen Share Dialog - Domain Spoof (Similar to permission prompt)

Steps to reproduce the problem

  1. Open the vulnerable page in long domain name (possible above 75)
  2. click the button to start screenshare
  3. you can see the domain name is truncated and diff domain is showed

To reproduce this issue locally we can follow the below steps

  1. Add a below entry in hosts file 127.0.0.1 google.drivelogin.accounts.login.safeoauth.truested.newsafelogin.google.com.finallargedomain.com
  2. place the attached files in one folder and start the server by running python3 filename.py
  3. Now visit https://googledrivelogin.accounts.logins.safeoauth.truested.newsafelogins.google.com.finallargedomain.com:4443/poc.html in latest chrome
  4. You can see the popup shows google.com at the end instead of finallargedomain.com

Problem Description

Note: I have already reported this case but was closed as obsolete without further investigation, i have added details here, kindly check the poc video and this comment https://issues.chromium.org/issues/420574505#comment4

Firefox Ref of similar attack in permission prompt: https://bugzilla.mozilla.org/show_bug.cgi?id=1920423

I have seen the similar case in chrome too but i wasnt able to get that bug reference

HI Team, Chrome latest on windows is vulnerable for screenshare domain name spoof which allows the attacker to trick the victim to share the screen to malicious site thinking it of as google.com

Tested on windows 11 pro, chrome canary 138.0.7204.4 (Official Build) canary (64-bit)

Summary

Screen Share Dialog - Domain Spoof (Similar to permission prompt)

Custom Questions

Reporter credit:

Ameen Basha M K

Additional Data

Category: Security
Chrome Channel: Canary
Regression: N/A

View on issue tracker