Chrome · DeviceBoundSessionCredentials
CVE-2026-79000
Logic Error in DeviceBoundSessionCredentials
Overview
Low
Severity
—
CVSS
No
Exploited ITW
Fixed
Fix Status
Changed Functions
| Function | Change | Notes |
|---|---|---|
ifnet/url_request/url_request_http_job.cc |
modified |
Files Changed
net/url_request/url_request_http_job.ccnet/url_request/url_request_http_job_unittest.cc
Patch
From 64729847f3d132c2fe56c897efc976ef1fe0b6f6 Mon Sep 17 00:00:00 2001 From: Alex Ilin <[email protected]> Date: Fri, 24 Jul 2026 11:37:21 -0700 Subject: [PATCH] [DSBC] Ignore DBSC headers on certificate errors Prevents URLRequestHttpJob from processing DBSC headers when the connection has certificate errors. Bypassing the TLS warning interstitial does not elevate the connection to a secure context for persistent state changes. Fixed: 502514083 TAG=agy CONV=3f4d55cc-e2fe-4c1f-8566-d7a4e73b6427 Change-Id: I84aaa8bceeb611ecaa97ca9a86c62ba26a6a6964 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/8118566 Reviewed-by: Adam Rice <[email protected]> Commit-Queue: Alex Ilin <[email protected]> Cr-Commit-Position: refs/heads/main@{#1668041} --- diff --git a/net/url_request/url_request_http_job.cc b/net/url_request/url_request_http_job.cc index ec9cb75..545d45b2 100644 --- a/net/url_request/url_request_http_job.cc +++ b/net/url_request/url_request_http_job.cc @@ -1162,6 +1162,13 @@ #if BUILDFLAG(ENABLE_DEVICE_BOUND_SESSIONS) void URLRequestHttpJob::ProcessDeviceBoundSessionsHeader() { + DCHECK(response_info_); + const SSLInfo& ssl_info = response_info_->ssl_info; + // Do not process DBSC headers on connections with certificate errors. + if (!ssl_info.is_valid() || IsCertStatusError(ssl_info.cert_status)) { + return; + } + device_bound_sessions::SessionService* service = request_->context()->device_bound_session_service(); if (!service) { diff --git a/net/url_request/url_request_http_job_unittest.cc b/net/url_request/url_request_http_job_unittest.cc index b55e0e65..173edd9 100644 --- a/net/url_request/url_request_http_job_unittest.cc +++ b/net/url_request/url_request_http_job_unittest.cc @@ -35,6 +35,7 @@ #include "net/base/proxy_string_util.h" #include "net/base/request_priority.h" #include "net/base/test_proxy_delegate.h" +#include "net/cert/cert_status_flags.h" #include "net/cert/ct_policy_status.h" #include "net/cookies/canonical_cookie_test_helpers.h" #include "net/cookies/cookie_monster.h" @@ -1540,6 +1541,8 @@ MockRead("Test Content")}; net::SSLSocketDataProvider ssl_socket_data_provider(net::ASYNC, net::OK); + ssl_socket_data_provider.ssl_info.cert = + ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem"); socket_factory_.AddSSLSocketDataProvider(&ssl_socket_data_provider); StaticSocketDataProvider socket_data(reads, writes); socket_factory_.AddSocketDataProvider(&socket_data); @@ -1568,6 +1571,8 @@ MockRead("Test Content")}; net::SSLSocketDataProvider ssl_socket_data_provider(net::ASYNC, net::OK); + ssl_socket_data_provider.ssl_info.cert = + ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem"); socket_factory_.AddSSLSocketDataProvider(&ssl_socket_data_provider); StaticSocketDataProvider socket_data(reads, writes); socket_factory_.AddSocketDataProvider(&socket_data); @@ -1636,6 +1641,8 @@ MockRead("Test Content")}; net::SSLSocketDataProvider ssl_socket_data_provider(net::ASYNC, net::OK); + ssl_socket_data_provider.ssl_info.cert = + ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem"); socket_factory_.AddSSLSocketDataProvider(&ssl_socket_data_provider); StaticSocketDataProvider socket_data(reads, writes); socket_factory_.AddSocketDataProvider(&socket_data); @@ -1673,6 +1680,8 @@ MockRead("Test Content")}; net::SSLSocketDataProvider ssl_socket_data_provider(net::ASYNC, net::OK); + ssl_socket_data_provider.ssl_info.cert = + ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem"); socket_factory_.AddSSLSocketDataProvider(&ssl_socket_data_provider); StaticSocketDataProvider socket_data(reads, writes); socket_factory_.AddSocketDataProvider(&socket_data); @@ -1744,6 +1753,8 @@ MockRead("Test Content")}; net::SSLSocketDataProvider ssl_socket_data_provider(net::ASYNC, net::OK); + ssl_socket_data_provider.ssl_info.cert = + ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem"); socket_factory_.AddSSLSocketDataProvider(&ssl_socket_data_provider); StaticSocketDataProvider socket_data(reads, writes); socket_factory_.AddSocketDataProvider(&socket_data); @@ -1801,6 +1812,8 @@ MockRead("Test Content")}; net::SSLSocketDataProvider ssl_socket_data_provider(net::ASYNC, net::OK); + ssl_socket_data_provider.ssl_info.cert = + ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem"); socket_factory_.AddSSLSocketDataProvider(&ssl_socket_data_provider); StaticSocketDataProvider socket_data(reads, writes); socket_factory_.AddSocketDataProvider(&socket_data); @@ -1868,6 +1881,8 @@ MockRead(ASYNC, 0)}; net::SSLSocketDataProvider ssl_socket_data_provider(net::ASYNC, net::OK); + ssl_socket_data_provider.ssl_info.cert = + ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem"); socket_factory_.AddSSLSocketDataProvider(&ssl_socket_data_provider); StaticSocketDataProvider socket_data(reads, writes); socket_factory_.AddSocketDataProvider(&socket_data); @@ -1938,6 +1953,8 @@ MockRead("Test Content")}; net::SSLSocketDataProvider ssl_socket_data_provider(net::ASYNC, net::OK); + ssl_socket_data_provider.ssl_info.cert = + ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem"); socket_factory_.AddSSLSocketDataProvider(&ssl_socket_data_provider); StaticSocketDataProvider socket_data(reads, writes); socket_factory_.AddSocketDataProvider(&socket_data); @@ -1981,6 +1998,8 @@ MockRead("Test Content")}; net::SSLSocketDataProvider ssl_socket_data_provider(net::ASYNC, net::OK); + ssl_socket_data_provider.ssl_info.cert = + ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem"); socket_factory_.AddSSLSocketDataProvider(&ssl_socket_data_provider); StaticSocketDataProvider socket_data(reads, writes); socket_factory_.AddSocketDataProvider(&socket_data); @@ -2004,6 +2023,50 @@ EXPECT_THAT(delegate_.request_status(), IsOk()); } +// Verifies that Secure-Session-Registration headers are ignored when the +// response is served over a connection with certificate errors. +TEST_F(URLRequestHttpJobWithMockSocketsDeviceBoundSessionServiceTest, + RegistrationHeaderIgnoredOnCertError) { + const MockWrite writes[] = { + MockWrite("GET / HTTP/1.1\r\n" + "Host: www.example.com\r\n" + "Connection: keep-alive\r\n" + "User-Agent: \r\n" + "Accept-Encoding: gzip, deflate\r\n" + "Accept-Language: en-us,fr\r\n\r\n")}; + + const MockRead reads[] = { + MockRead("HTTP/1.1 200 OK\r\n" + "Accept-Ranges: bytes\r\n" + "Secure-Session-Registration: (ES256);path=\"new\";" + "challenge=\"test\"\r\n" + "Content-Length: 12\r\n\r\n"), + MockRead("Test Content")}; + + net::SSLSocketDataProvider ssl_socket_data_provider(net::ASYNC, net::OK); + ssl_socket_data_provider.ssl_info.cert = + ImportCertFromFile(GetTestCertsDirectory(), "expired_cert.pem"); + // Set cert status error. + ssl_socket_data_provider.ssl_info.cert_status = CERT_STATUS_DATE_INVALID; + socket_factory_.AddSSLSocketDataProvider(&ssl_socket_data_provider); + StaticSocketDataProvider socket_data(reads, writes); + socket_factory_.AddSocketDataProvider(&socket_data); + + EXPECT_CALL(GetMockService(), ShouldDefer) + .WillRepeatedly(Return(std::nullopt)); + + // Verify that ProcessDeviceBoundSessionsHeader() did NOT invoke the + // SessionService because of the certificate error. + EXPECT_CALL(GetMockService(), HandleResponseHeaders).Times(0); + + request_->Start(); + delegate_.RunUntilComplete(); + EXPECT_THAT(delegate_.request_status(), IsOk()); + + // Verify that the connection was flagged with a certificate error. + EXPECT_TRUE(IsCertStatusError(request_->ssl_info().cert_status)); +} + #endif // BUILDFLAG(ENABLE_DEVICE_BOUND_SESSIONS) namespace {
Loading diff…
Regression Test / PoC
shipped with the fix
diff --git a/net/url_request/url_request_http_job_unittest.cc b/net/url_request/url_request_http_job_unittest.cc
index b55e0e65..173edd9 100644
--- a/net/url_request/url_request_http_job_unittest.cc
+++ b/net/url_request/url_request_http_job_unittest.cc
@@ -35,6 +35,7 @@
#include "net/base/proxy_string_util.h"
#include "net/base/request_priority.h"
#include "net/base/test_proxy_delegate.h"
+#include "net/cert/cert_status_flags.h"
#include "net/cert/ct_policy_status.h"
#include "net/cookies/canonical_cookie_test_helpers.h"
#include "net/cookies/cookie_monster.h"
@@ -1540,6 +1541,8 @@
MockRead("Test Content")};
net::SSLSocketDataProvider ssl_socket_data_provider(net::ASYNC, net::OK);
+ ssl_socket_data_provider.ssl_info.cert =
+ ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
socket_factory_.AddSSLSocketDataProvider(&ssl_socket_data_provider);
StaticSocketDataProvider socket_data(reads, writes);
socket_factory_.AddSocketDataProvider(&socket_data);
@@ -1568,6 +1571,8 @@
MockRead("Test Content")};
net::SSLSocketDataProvider ssl_socket_data_provider(net::ASYNC, net::OK);
+ ssl_socket_data_provider.ssl_info.cert =
+ ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
socket_factory_.AddSSLSocketDataProvider(&ssl_socket_data_provider);
StaticSocketDataProvider socket_data(reads, writes);
socket_factory_.AddSocketDataProvider(&socket_data);
@@ -1636,6 +1641,8 @@
MockRead("Test Content")};
net::SSLSocketDataProvider ssl_socket_data_provider(net::ASYNC, net::OK);
+ ssl_socket_data_provider.ssl_info.cert =
+ ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
socket_factory_.AddSSLSocketDataProvider(&ssl_socket_data_provider);
StaticSocketDataProvider socket_data(reads, writes);
socket_factory_.AddSocketDataProvider(&socket_data);
@@ -1673,6 +1680,8 @@
MockRead("Test Content")};
net::SSLSocketDataProvider ssl_socket_data_provider(net::ASYNC, net::OK);
+ ssl_socket_data_provider.ssl_info.cert =
+ ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
socket_factory_.AddSSLSocketDataProvider(&ssl_socket_data_provider);
StaticSocketDataProvider socket_data(reads, writes);
socket_factory_.AddSocketDataProvider(&socket_data);
@@ -1744,6 +1753,8 @@
MockRead("Test Content")};
net::SSLSocketDataProvider ssl_socket_data_provider(net::ASYNC, net::OK);
+ ssl_socket_data_provider.ssl_info.cert =
+ ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
socket_factory_.AddSSLSocketDataProvider(&ssl_socket_data_provider);
StaticSocketDataProvider socket_data(reads, writes);
socket_factory_.AddSocketDataProvider(&socket_data);
@@ -1801,6 +1812,8 @@
MockRead("Test Content")};
net::SSLSocketDataProvider ssl_socket_data_provider(net::ASYNC, net::OK);
+ ssl_socket_data_provider.ssl_info.cert =
+ ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
socket_factory_.AddSSLSocketDataProvider(&ssl_socket_data_provider);
StaticSocketDataProvider socket_data(reads, writes);
socket_factory_.AddSocketDataProvider(&socket_data);
@@ -1868,6 +1881,8 @@
MockRead(ASYNC, 0)};
net::SSLSocketDataProvider ssl_socket_data_provider(net::ASYNC, net::OK);
+ ssl_socket_data_provider.ssl_info.cert =
+ ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
socket_factory_.AddSSLSocketDataProvider(&ssl_socket_data_provider);
StaticSocketDataProvider socket_data(reads, writes);
socket_factory_.AddSocketDataProvider(&socket_data);
@@ -1938,6 +1953,8 @@
MockRead("Test Content")};
net::SSLSocketDataProvider ssl_socket_data_provider(net::ASYNC, net::OK);
+ ssl_socket_data_provider.ssl_info.cert =
+ ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
socket_factory_.AddSSLSocketDataProvider(&ssl_socket_data_provider);
StaticSocketDataProvider socket_data(reads, writes);
socket_factory_.AddSocketDataProvider(&socket_data);
@@ -1981,6 +1998,8 @@
MockRead("Test Content")};
net::SSLSocketDataProvider ssl_socket_data_provider(net::ASYNC, net::OK);
+ ssl_socket_data_provider.ssl_info.cert =
+ ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
socket_factory_.AddSSLSocketDataProvider(&ssl_socket_data_provider);
StaticSocketDataProvider socket_data(reads, writes);
socket_factory_.AddSocketDataProvider(&socket_data);
@@ -2004,6 +2023,50 @@
EXPECT_THAT(delegate_.request_status(), IsOk());
}
+// Verifies that Secure-Session-Registration headers are ignored when the
+// response is served over a connection with certificate errors.
+TEST_F(URLRequestHttpJobWithMockSocketsDeviceBoundSessionServiceTest,
+ RegistrationHeaderIgnoredOnCertError) {
+ const MockWrite writes[] = {
+ MockWrite("GET / HTTP/1.1\r\n"
+ "Host: www.example.com\r\n"
+ "Connection: keep-alive\r\n"
+ "User-Agent: \r\n"
+ "Accept-Encoding: gzip, deflate\r\n"
+ "Accept-Language: en-us,fr\r\n\r\n")};
+
+ const MockRead reads[] = {
+ MockRead("HTTP/1.1 200 OK\r\n"
+ "Accept-Ranges: bytes\r\n"
+ "Secure-Session-Registration: (ES256);path=\"new\";"
+ "challenge=\"test\"\r\n"
+ "Content-Length: 12\r\n\r\n"),
+ MockRead("Test Content")};
+
+ net::SSLSocketDataProvider ssl_socket_data_provider(net::ASYNC, net::OK);
+ ssl_socket_data_provider.ssl_info.cert =
+ ImportCertFromFile(GetTestCertsDirectory(), "expired_cert.pem");
+ // Set cert status error.
+ ssl_socket_data_provider.ssl_info.cert_status = CERT_STATUS_DATE_INVALID;
+ socket_factory_.AddSSLSocketDataProvider(&ssl_socket_data_provider);
+ StaticSocketDataProvider socket_data(reads, writes);
+ socket_factory_.AddSocketDataProvider(&socket_data);
+
+ EXPECT_CALL(GetMockService(), ShouldDefer)
+ .WillRepeatedly(Return(std::nullopt));
+
+ // Verify that ProcessDeviceBoundSessionsHeader() did NOT invoke the
+ // SessionService because of the certificate error.
+ EXPECT_CALL(GetMockService(), HandleResponseHeaders).Times(0);
+
+ request_->Start();
+ delegate_.RunUntilComplete();
+ EXPECT_THAT(delegate_.request_status(), IsOk());
+
+ // Verify that the connection was flagged with a certificate error.
+ EXPECT_TRUE(IsCertStatusError(request_->ssl_info().cert_status));
+}
+
#endif // BUILDFLAG(ENABLE_DEVICE_BOUND_SESSIONS)
namespace {
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