CVE-2025-11212
Overview
Changed Functions
| Function | Change | Notes |
|---|---|---|
Extensionchrome/browser/media/webrtc/display_media_access_handler.h |
modified | |
DisplayMediaAccessHandlerchrome/browser/media/webrtc/display_media_access_handler.h |
modified | |
TEST_Fchrome/browser/media/webrtc/display_media_access_handler_unittest.cc |
modified |
Files Changed
chrome/browser/media/webrtc/display_media_access_handler.ccchrome/browser/media/webrtc/display_media_access_handler.hchrome/browser/media/webrtc/display_media_access_handler_unittest.cctesting/variations/fieldtrial_testing_config.json
Patch
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": [
Regression Test / PoC
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,
Original Bug Report
Screen Share Dialog - Domain Spoof (Similar to permission prompt)
Steps to reproduce the problem
- Open the vulnerable page in long domain name (possible above 75)
- click the button to start screenshare
- you can see the domain name is truncated and diff domain is showed
To reproduce this issue locally we can follow the below steps
- Add a below entry in hosts file 127.0.0.1 google.drivelogin.accounts.login.safeoauth.truested.newsafelogin.google.com.finallargedomain.com
- place the attached files in one folder and start the server by running python3 filename.py
- Now visit https://googledrivelogin.accounts.logins.safeoauth.truested.newsafelogins.google.com.finallargedomain.com:4443/poc.html in latest chrome
- 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