Bug 1663836 - Treat invalid HTTP response header names over HTTP2 as malformed r=necko-reviewers,dragana

Relevant section in the spec: https://datatracker.ietf.org/doc/html/rfc7540#section-10.3

Differential Revision: https://phabricator.services.mozilla.com/D120969
This commit is contained in:
Manuel Bucher 2021-08-12 09:34:20 +00:00
Родитель 3665e7973c
Коммит 6cdb3ae33a
3 изменённых файлов: 32 добавлений и 0 удалений

Просмотреть файл

@ -510,6 +510,18 @@ nsresult Http2Decompressor::OutputHeader(const nsACString& name,
return NS_OK;
}
// Bug 1663836: reject invalid HTTP response header names - RFC7540 Sec 10.3
const char* cFirst = name.BeginReading();
if (cFirst != nullptr && *cFirst == ':') {
++cFirst;
}
if (!nsHttp::IsValidToken(cFirst, name.EndReading())) {
nsCString toLog(name);
LOG(("HTTP Decompressor invalid response header found. [%s]\n",
toLog.get()));
return NS_ERROR_ILLEGAL_VALUE;
}
// Look for upper case characters in the name.
for (const char* cPtr = name.BeginReading(); cPtr && cPtr < name.EndReading();
++cPtr) {

Просмотреть файл

@ -563,6 +563,16 @@ function test_http2_header() {
chan.asyncOpen(listener);
}
// Test to make sure headers with invalid characters in the name are rejected
function test_http2_invalid_response_header() {
var listener = new Http2CheckListener();
listener.shouldSucceed = false;
var chan = makeChan(
"https://localhost:" + serverPort + "/invalid_response_header"
);
chan.asyncOpen(listener);
}
// Test to make sure cookies are split into separate fields before compression
function test_http2_cookie_crumbling() {
var chan = makeChan("https://localhost:" + serverPort + "/cookie_crumbling");
@ -1304,6 +1314,7 @@ var tests = [
test_http2_doubleheader,
test_http2_xhr,
test_http2_header,
test_http2_invalid_response_header,
test_http2_cookie_crumbling,
test_http2_multiplex,
test_http2_big,

Просмотреть файл

@ -1678,6 +1678,15 @@ function handleRequest(req, res) {
return;
}
// response headers with invalid characters in the name
else if (u.pathname === "/invalid_response_header") {
res.setHeader("With Spaces", "Hello");
res.setHeader("Without-Spaces", "World");
res.writeHead(200);
res.end("");
return;
}
res.setHeader("Content-Type", "text/html");
if (req.httpVersionMajor != 2) {
res.setHeader("Connection", "close");