Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Discrepancies in parsing http messages #158

Closed
blessingcharles opened this issue Jun 1, 2022 · 0 comments · Fixed by #181
Closed

Discrepancies in parsing http messages #158

blessingcharles opened this issue Jun 1, 2022 · 0 comments · Fixed by #181

Comments

@blessingcharles
Copy link

blessingcharles commented Jun 1, 2022

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant