mirror of
https://github.com/electron/electron.git
synced 2026-05-02 03:00:22 -04:00
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<net::HttpRequestHeaders>::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 <loufulton.cz@gmail.com> * Update shell/common/gin_converters/net_converter.cc Co-authored-by: Charles Kerr <charles@charleskerr.com> Co-authored-by: loufultoncz-coder <loufulton.cz@gmail.com> * Update spec/api-web-request-spec.ts Co-authored-by: Charles Kerr <charles@charleskerr.com> Co-authored-by: loufultoncz-coder <loufulton.cz@gmail.com> * fix: lint Co-authored-by: loufulton <loufulton.cz@gmail.com> --------- Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com> Co-authored-by: loufulton <loufulton.cz@gmail.com>
This commit is contained in:
@@ -253,8 +253,10 @@ bool Converter<net::HttpRequestHeaders>::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;
|
||||
}
|
||||
|
||||
@@ -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<Electron.OnSendHeadersListenerDetails>((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'
|
||||
|
||||
Reference in New Issue
Block a user