Discrepancies in parsing http messages
blessingcharles opened this issue · comments
th3h04x commented
Version
nodejs :17.8.0
Platform
linux nodejs docker
Subsystem
node http
What steps will reproduce the bug?
Dockerfile
FROM node
# Create app directory
WORKDIR /usr/src/app
# Bundle app source
COPY . .
EXPOSE 80
CMD [ "node", "app.js" ]
Code to reproduce
const http = require("http");
const fs = require("fs")
// https://nodejs.org/en/docs/guides/anatomy-of-an-http-transaction/
let request_count = 0 ;
console.log("server started at 80");
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();
console.log("\n----------------------------\n")
console.log(request.headers);
console.log("Body : " , body , " length : " , body.length.toString())
console.log(response.statusCode)
request_count += 1
content = `\n---Count : ${request_count}---- Status : ${response.statusCode} --------\n${JSON.stringify(request.headers)}\nBody:[${body.toString()}]\n`
fs.writeFile('output.txt', content, { flag: 'a+' }, err => {})
response.on("error", (err) => {
response.end("error while sending response: " + err);
});
response.end(
"Body length: " + body.length.toString() + " Body: " + body
);
});
}).listen(80);
POC
echo -ne "GET / HTTP/1.1\r\nHost: localhost\r\nTransfer-encoding: chunked\r\n\r\n2 erfrferferf\r\naa\r\n0 rrrr\r\n\r\n" | nc localhost 8003
How often does it reproduce? Is there a required condition?
Reproducible in all environments
What is the expected behavior?
- According to RFC grammar , For chunked body each chunk size should be terminated by CRLF , or can have chunked extension preceding with ";" . RFC chunked transfer coding .
RFC ABNF Grammar
chunk = chunk-size [ chunk-ext ] CRLF
chunk-data CRLF
chunk-size = 1*HEXDIG
last-chunk = 1*("0") [ chunk-ext ] CRLF
chunk-data = 1*OCTET ; a sequence of chunk-size octets
chunk-ext = *( ";" chunk-ext-name [ "=" chunk-ext-val ] )
- All requestline , request headers and terminating headers-field must be terminated with CRLF . RFC grammar
What do you see instead?
- For chunked body , each chunksize can be preceded with space and then any random ascii characters are allowed , even though semicolon is not provided for chunked extendsion , which violates RFC grammar
echo -ne "GET / HTTP/1.1\nHost: localhost\nTransfer-encoding: chunked\r\n\r\n2 fereg\r\naa\r\n0 rvrtvgrwtv\r\n\r\n"
- Requestline , Requestheaders and terminating headers in nodejs instead of CRLF , LF was treated as terminator .
echo -ne "GET / HTTP/1.1\nHost: localhost\nTransfer-encoding: chunked\n\n2\r\naa\r\n0\r\n\r\n" | nc localhost 8003
Additional information
No response