From d7126ad027cfc0be169b65f7f34121725ea85f84 Mon Sep 17 00:00:00 2001 From: "trop[bot]" <37223003+trop[bot]@users.noreply.github.com> Date: Tue, 28 Apr 2026 11:52:40 -0400 Subject: [PATCH] fix: validate header name and value in webRequest.onBeforeSendHeaders (#51366) * fix: validate header name and value in webRequest.onBeforeSendHeaders Chromium's net::HttpRequestHeaders::SetHeader() uses CHECK() to enforce valid header names and values, which causes a fatal crash if the caller passes invalid strings. When users modify requestHeaders in the onBeforeSendHeaders callback with invalid header names (e.g. containing spaces) or invalid header values (e.g. containing CRLF), the gin::Converter::FromV8() calls SetHeader() directly, triggering the CHECK and crashing the process. This change adds pre-validation using net::HttpUtil::IsValidHeaderName() and net::HttpUtil::IsValidHeaderValue() before calling SetHeader(), silently skipping invalid headers instead of crashing. Co-authored-by: loufulton * Update shell/common/gin_converters/net_converter.cc Co-authored-by: Charles Kerr Co-authored-by: loufultoncz-coder * Update spec/api-web-request-spec.ts Co-authored-by: Charles Kerr Co-authored-by: loufultoncz-coder * fix: lint Co-authored-by: loufulton --------- Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com> Co-authored-by: loufulton --- shell/common/gin_converters/net_converter.cc | 4 +++- spec/api-web-request-spec.ts | 21 ++++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/shell/common/gin_converters/net_converter.cc b/shell/common/gin_converters/net_converter.cc index 476223a228..f8d805f993 100644 --- a/shell/common/gin_converters/net_converter.cc +++ b/shell/common/gin_converters/net_converter.cc @@ -253,8 +253,10 @@ bool Converter::FromV8(v8::Isolate* isolate, if (!ConvertFromV8(isolate, val, &dict)) return false; for (const auto it : dict) { - if (it.second.is_string()) + if (it.second.is_string() && net::HttpUtil::IsValidHeaderName(it.first) && + net::HttpUtil::IsValidHeaderValue(it.second.GetString())) { out->SetHeader(it.first, std::move(it.second).TakeString()); + } } return true; } diff --git a/spec/api-web-request-spec.ts b/spec/api-web-request-spec.ts index 13146d581c..96052b44e0 100644 --- a/spec/api-web-request-spec.ts +++ b/spec/api-web-request-spec.ts @@ -411,6 +411,27 @@ describe('webRequest module', () => { expect(called).to.be.true(); }); + it('does not crash on invalid header name or value', async () => { + ses.webRequest.onBeforeSendHeaders((details, callback) => { + const requestHeaders = details.requestHeaders; + requestHeaders['Invalid Header'] = 'valid-value'; + requestHeaders['Valid-Header'] = 'invalid\r\nvalue'; + requestHeaders['X-Good'] = 'good-value'; + callback({ requestHeaders }); + }); + const sentHeaders = new Promise((resolve) => { + ses.webRequest.onSendHeaders(resolve); + }); + + const { data } = await ajax(defaultURL); + const details = await sentHeaders; + + expect(details.requestHeaders['Invalid Header']).to.be.undefined(); + expect(details.requestHeaders['Valid-Header']).to.be.undefined(); + expect(details.requestHeaders['X-Good']).to.equal('good-value'); + expect(data).to.equal('/'); + }); + it('resets the whole headers', async () => { const requestHeaders = { Test: 'header'