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

net/http: discrepancy in CRLF termination in http messages #53186

Open
blessingcharles opened this issue Jun 1, 2022 · 1 comment
Open

net/http: discrepancy in CRLF termination in http messages #53186

blessingcharles opened this issue Jun 1, 2022 · 1 comment
Labels
NeedsInvestigation
Milestone

Comments

@blessingcharles
Copy link

@blessingcharles blessingcharles commented Jun 1, 2022

What version of Go are you using (go version)?

      1.18.2

Does this issue reproduce with the latest release?

yes

What did you do?

  1. While fuzzing for analyzing the discrepancies in the parsing behavior of various servers , the termination chunk of 0\n\r\n was accepted and most servers like nodejs and actix replied witj 400 request . According to RFC the termination chunk must be 0CRLFCRLF ie 0\r\n\r\n but golang accept 0\n\r\n . RFC chunked termination

  2. Every header , requestline and body delimiting end should be CRLF according to RFC ABNF grammar but golang accepts LF alone as a valid request .RFC 7230

POC
echo -ne "GET / HTTP/1.1\nHost: localhost\nTransfer-encoding: chunked\n\n2\naa\r\n0\n\r\n" | nc localhost 8004 

What did you expect to see?

  1. Correctly parse the CRLF termination according to RFC standards and other servers

What operating system and processor architecture are you using (go env)?

Environment

FROM golang
USER root
WORKDIR /go/src/app
COPY server.go /go/src/app/server.go
RUN go mod init
RUN go build .
CMD ["./app"]

Code used

package main

import (
	"fmt"
	"io/ioutil"
	"net/http"
	"log"
)

func main() {
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		
		b, err := ioutil.ReadAll(r.Body)
		if err != nil {
			w.Write([]byte(fmt.Sprintf("Got error while reading body: %v", err)))
			return
		}
		fmt.Printf("Body length: %d Body: %q", len(b), b)
		w.Write([]byte(fmt.Sprintf("Body length: %d Body: %q", len(b), b)))
	})

	fmt.Printf("Server Starting at port 80") 
	if err := http.ListenAndServe(":80", nil) ; err != nil {
		log.Fatal(err)
	}
}
@mdlayher mdlayher changed the title affected/package: net/http discrepancy in CRLF termination in http messages net/http discrepancy in CRLF termination in http messages Jun 1, 2022
@mdlayher mdlayher changed the title net/http discrepancy in CRLF termination in http messages net/http: discrepancy in CRLF termination in http messages Jun 1, 2022
@neild
Copy link
Contributor

@neild neild commented Jun 1, 2022

RFC 7230 section 3.5 explicitly allows for accepting a bare LF:

Although the line terminator for the start-line and header fields is
the sequence CRLF, a recipient MAY recognize a single LF as a line
terminator and ignore any preceding CR.

Perhaps we should be stricter, but the current behavior is within the parameters permitted by RFC 7230.

@dmitshur dmitshur added the NeedsInvestigation label Jun 3, 2022
@dmitshur dmitshur added this to the Backlog milestone Jun 3, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
NeedsInvestigation
Projects
None yet
Development

No branches or pull requests

3 participants