Chrome · Media › Media
CVE-2026-110141
Info Disclosure in Media (Media)
Overview
High
Severity
—
CVSS
No
Exploited ITW
Fixed
Fix Status
Changed Functions
| Function | Change | Notes |
|---|---|---|
TEST_Fthird_party/blink/renderer/platform/media/multi_buffer_data_source_unittest.cc |
modified | |
TEST_Fthird_party/blink/renderer/platform/media/resource_multi_buffer_data_provider_unittest.cc |
modified |
Files Changed
third_party/blink/renderer/platform/media/resource_multi_buffer_data_provider_unittest.ccthird_party/blink/renderer/platform/media/multi_buffer_data_source_unittest.ccthird_party/blink/renderer/platform/media/resource_multi_buffer_data_provider.cc
Patch
From 718a8fc1586aeb3d9554ad5e40617da50ec1bc5b Mon Sep 17 00:00:00 2001
From: Dale Curtis <dalecurtis@chromium.org>
Date: Thu, 08 Oct 2026 14:29:27 -0700
Subject: [PATCH] [Media] Fail opaque 416 responses in ResourceMultiBufferDataProvider
Route opaque 416 (Range Not Satisfiable) responses in
ResourceMultiBufferDataProvider::DidReceiveResponse() through the same
failure path as opaque 206 responses with a mismatched Content-Range,
rather than treating them as end-of-file.
Fixed: 568895734
Change-Id: Id7e703581dcf9d647cc0042914be9599d011fcff
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/8540648
Auto-Submit: Dale Curtis <dalecurtis@chromium.org>
Reviewed-by: Eugene Zemtsov <eugene@chromium.org>
Commit-Queue: Eugene Zemtsov <eugene@chromium.org>
Commit-Queue: Dale Curtis <dalecurtis@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1714947}
---
diff --git a/third_party/blink/renderer/platform/media/resource_multi_buffer_data_provider.cc b/third_party/blink/renderer/platform/media/resource_multi_buffer_data_provider.cc
index 930b294..7d1d1395 100644
--- a/third_party/blink/renderer/platform/media/resource_multi_buffer_data_provider.cc
+++ b/third_party/blink/renderer/platform/media/resource_multi_buffer_data_provider.cc
@@ -297,7 +297,8 @@
bool end_of_file = false;
bool do_fail = false;
// We get the response type here because aborting the loader may change it.
- const auto response_type = response.GetType();
+ const bool is_cors_cross_origin =
+ network::cors::IsCorsCrossOriginResponseType(response.GetType());
bytes_to_discard_ = 0;
// We make a strong assumption that when we reach here we have either
@@ -327,10 +328,13 @@
// to return.
destination_url_data->set_length(content_length);
bytes_to_discard_ = byte_pos();
- } else if (response.HttpStatusCode() == kHttpRangeNotSatisfiable) {
+ } else if (response.HttpStatusCode() == kHttpRangeNotSatisfiable &&
+ !is_cors_cross_origin) {
// Unsatisfiable range
// Really, we should never request a range that doesn't exist, but
- // if we do, let's handle it in a sane way.
+ // if we do, let's handle it in a sane way. Opaque responses are
+ // excluded so a service-worker-replayed 416 takes the same failure
+ // path as a 206 with a mismatched Content-Range.
// Note, we can't just call OnDataProviderEvent() here, because
// url_data_ hasn't been updated to the final destination yet.
end_of_file = true;
@@ -352,8 +356,7 @@
}
// This is vital for security!
- destination_url_data->set_is_cors_cross_origin(
- network::cors::IsCorsCrossOriginResponseType(response_type));
+ destination_url_data->set_is_cors_cross_origin(is_cors_cross_origin);
// Only used for metrics.
{
diff --git a/third_party/blink/renderer/platform/media/multi_buffer_data_source_unittest.cc b/third_party/blink/renderer/platform/media/multi_buffer_data_source_unittest.cc
index b7883a3..9defe81 100644
--- a/third_party/blink/renderer/platform/media/multi_buffer_data_source_unittest.cc
+++ b/third_party/blink/renderer/platform/media/multi_buffer_data_source_unittest.cc
@@ -580,6 +580,16 @@
Stop();
}
+TEST_F(MultiBufferDataSourceTest, Range_NotSatisfiableOpaque) {
+ Initialize(kHttpUrl, false);
+ WebURLResponse response = response_generator_->GenerateResponse(416);
+ response.SetType(network::mojom::blink::FetchResponseType::kOpaque);
+ Respond(response);
+ EXPECT_TRUE(data_source_->WouldTaintOrigin());
+ EXPECT_FALSE(loading());
+ Stop();
+}
+
// Special carve-out for Apache versions that choose to return a 200 for
// Range:0- ("because it's more efficient" than a 206)
TEST_F(MultiBufferDataSourceTest, Range_SupportedButReturned200) {
diff --git a/third_party/blink/renderer/platform/media/resource_multi_buffer_data_provider_unittest.cc b/third_party/blink/renderer/platform/media/resource_multi_buffer_data_provider_unittest.cc
index e7212ff..40d44b6 100644
--- a/third_party/blink/renderer/platform/media/resource_multi_buffer_data_provider_unittest.cc
+++ b/third_party/blink/renderer/platform/media/resource_multi_buffer_data_provider_unittest.cc
@@ -426,6 +426,20 @@
loader_->DidReceiveResponse(response);
}
+TEST_F(ResourceMultiBufferDataProviderTest, OpaqueRangeNotSatisfiableFails) {
+ Initialize(kHttpUrl, 0);
+ Start();
+
+ EXPECT_CALL(*this, RedirectCallback(scoped_refptr<UrlData>(nullptr)));
+
+ WebURLResponse response(url_);
+ response.SetHttpStatusCode(416);
+ response.SetType(network::mojom::FetchResponseType::kOpaque);
+ loader_->DidReceiveResponse(response);
+ EXPECT_TRUE(url_data_->is_cors_cross_origin());
+ EXPECT_TRUE(url_data_->multibuffer()->map().empty());
+}
+
TEST_F(ResourceMultiBufferDataProviderTest, TestRedirects) {
// Test redirect.
Initialize(kHttpUrl, 0);
Loading diff…
Regression Test / PoC
shipped with the fix
diff --git a/third_party/blink/renderer/platform/media/multi_buffer_data_source_unittest.cc b/third_party/blink/renderer/platform/media/multi_buffer_data_source_unittest.cc
index b7883a3..9defe81 100644
--- a/third_party/blink/renderer/platform/media/multi_buffer_data_source_unittest.cc
+++ b/third_party/blink/renderer/platform/media/multi_buffer_data_source_unittest.cc
@@ -580,6 +580,16 @@
Stop();
}
+TEST_F(MultiBufferDataSourceTest, Range_NotSatisfiableOpaque) {
+ Initialize(kHttpUrl, false);
+ WebURLResponse response = response_generator_->GenerateResponse(416);
+ response.SetType(network::mojom::blink::FetchResponseType::kOpaque);
+ Respond(response);
+ EXPECT_TRUE(data_source_->WouldTaintOrigin());
+ EXPECT_FALSE(loading());
+ Stop();
+}
+
// Special carve-out for Apache versions that choose to return a 200 for
// Range:0- ("because it's more efficient" than a 206)
TEST_F(MultiBufferDataSourceTest, Range_SupportedButReturned200) {
diff --git a/third_party/blink/renderer/platform/media/resource_multi_buffer_data_provider_unittest.cc b/third_party/blink/renderer/platform/media/resource_multi_buffer_data_provider_unittest.cc
index e7212ff..40d44b6 100644
--- a/third_party/blink/renderer/platform/media/resource_multi_buffer_data_provider_unittest.cc
+++ b/third_party/blink/renderer/platform/media/resource_multi_buffer_data_provider_unittest.cc
@@ -426,6 +426,20 @@
loader_->DidReceiveResponse(response);
}
+TEST_F(ResourceMultiBufferDataProviderTest, OpaqueRangeNotSatisfiableFails) {
+ Initialize(kHttpUrl, 0);
+ Start();
+
+ EXPECT_CALL(*this, RedirectCallback(scoped_refptr<UrlData>(nullptr)));
+
+ WebURLResponse response(url_);
+ response.SetHttpStatusCode(416);
+ response.SetType(network::mojom::FetchResponseType::kOpaque);
+ loader_->DidReceiveResponse(response);
+ EXPECT_TRUE(url_data_->is_cors_cross_origin());
+ EXPECT_TRUE(url_data_->multibuffer()->map().empty());
+}
+
TEST_F(ResourceMultiBufferDataProviderTest, TestRedirects) {
// Test redirect.
Initialize(kHttpUrl, 0);
Loading diff…
Original Bug Report
The reporter's bug is still restricted on the tracker. Chrome de-restricts security bugs ~30–90 days after the fix ships; a later run will backfill it here.
References
On This Page