]> Cypherpunks repositories - gostls13.git/commitdiff
net/http: reject faux HTTP/0.9 and HTTP/2+ requests
authorBrad Fitzpatrick <bradfitz@golang.org>
Mon, 27 Jun 2016 17:28:08 +0000 (10:28 -0700)
committerBrad Fitzpatrick <bradfitz@golang.org>
Mon, 27 Jun 2016 21:07:11 +0000 (21:07 +0000)
Fixes #16197

Change-Id: Icaabacbb22bc18c52b9e04b47385ac5325fcccd1
Reviewed-on: https://go-review.googlesource.com/24505
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
src/net/http/serve_test.go
src/net/http/server.go

index ca30e644c34bf13c97c81eb31811a9c827465d6a..62b558c2cf90b3dd0820f3e4173eb45e95f4b061 100644 (file)
@@ -3958,6 +3958,8 @@ func TestServerValidatesHostHeader(t *testing.T) {
                host  string
                want  int
        }{
+               {"HTTP/0.9", "", 400},
+
                {"HTTP/1.1", "", 400},
                {"HTTP/1.1", "Host: \r\n", 200},
                {"HTTP/1.1", "Host: 1.2.3.4\r\n", 200},
@@ -3983,6 +3985,11 @@ func TestServerValidatesHostHeader(t *testing.T) {
 
                // Make an exception for HTTP upgrade requests:
                {"PRI * HTTP/2.0", "", 200},
+
+               // But not other HTTP/2 stuff:
+               {"PRI / HTTP/2.0", "", 400},
+               {"GET / HTTP/2.0", "", 400},
+               {"GET / HTTP/3.0", "", 400},
        }
        for _, tt := range tests {
                conn := &testConn{closec: make(chan bool, 1)}
index 42b6304d4f784c6db0965501adbee4454a4c0da9..a1c48272fd6b7f22b88142f398c5a0d3678aebf1 100644 (file)
@@ -771,6 +771,10 @@ func (c *conn) readRequest(ctx context.Context) (w *response, err error) {
                return nil, err
        }
 
+       if !http1ServerSupportsRequest(req) {
+               return nil, badRequestError("unsupported protocol version")
+       }
+
        ctx, cancelCtx := context.WithCancel(ctx)
        req.ctx = ctx
 
@@ -828,6 +832,23 @@ func (c *conn) readRequest(ctx context.Context) (w *response, err error) {
        return w, nil
 }
 
+// http1ServerSupportsRequest reports whether Go's HTTP/1.x server
+// supports the given request.
+func http1ServerSupportsRequest(req *Request) bool {
+       if req.ProtoMajor == 1 {
+               return true
+       }
+       // Accept "PRI * HTTP/2.0" upgrade requests, so Handlers can
+       // wire up their own HTTP/2 upgrades.
+       if req.ProtoMajor == 2 && req.ProtoMinor == 0 &&
+               req.Method == "PRI" && req.RequestURI == "*" {
+               return true
+       }
+       // Reject HTTP/0.x, and all other HTTP/2+ requests (which
+       // aren't encoded in ASCII anyway).
+       return false
+}
+
 func (w *response) Header() Header {
        if w.cw.header == nil && w.wroteHeader && !w.cw.wroteHeader {
                // Accessing the header between logically writing it