nodejs / llhttp

Port of http_parser to llparse

Home Page:http://llhttp.org

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Discrepancies in parsing http messages

blessingcharles opened this issue · comments

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?

  1. 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 ] )
  1. All requestline , request headers and terminating headers-field must be terminated with CRLF . RFC grammar

What do you see instead?

  1. 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"
  1. 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