From 1854279bb560031d70216b99db3c585cb38fa6b0 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Thu, 22 Dec 2016 14:23:32 +0700 Subject: [PATCH] reject requests with an invalid request method --- h2quic/roundtrip.go | 28 ++++++++++++++++++++++++++++ h2quic/roundtrip_test.go | 8 ++++++++ 2 files changed, 36 insertions(+) diff --git a/h2quic/roundtrip.go b/h2quic/roundtrip.go index c8ddbd34..99bd6e0f 100644 --- a/h2quic/roundtrip.go +++ b/h2quic/roundtrip.go @@ -4,6 +4,7 @@ import ( "errors" "fmt" "net/http" + "strings" "sync" "golang.org/x/net/lex/httplex" @@ -63,6 +64,11 @@ func (r *QuicRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) return nil, fmt.Errorf("quic: unsupported protocol scheme: %s", req.URL.Scheme) } + if req.Method != "" && !validMethod(req.Method) { + closeRequestBody(req) + return nil, fmt.Errorf("quic: invalid method %q", req.Method) + } + hostname := authorityAddr("https", hostnameFromRequest(req)) client, err := r.getClient(hostname) if err != nil { @@ -100,3 +106,25 @@ func closeRequestBody(req *http.Request) { req.Body.Close() } } + +func validMethod(method string) bool { + /* + Method = "OPTIONS" ; Section 9.2 + | "GET" ; Section 9.3 + | "HEAD" ; Section 9.4 + | "POST" ; Section 9.5 + | "PUT" ; Section 9.6 + | "DELETE" ; Section 9.7 + | "TRACE" ; Section 9.8 + | "CONNECT" ; Section 9.9 + | extension-method + extension-method = token + token = 1* + */ + return len(method) > 0 && strings.IndexFunc(method, isNotToken) == -1 +} + +// copied from net/http/http.go +func isNotToken(r rune) bool { + return !httplex.IsTokenRune(r) +} diff --git a/h2quic/roundtrip_test.go b/h2quic/roundtrip_test.go index 7d038d5f..a8031091 100644 --- a/h2quic/roundtrip_test.go +++ b/h2quic/roundtrip_test.go @@ -105,5 +105,13 @@ var _ = Describe("RoundTripper", func() { _, err := rt.RoundTrip(req1) Expect(err.Error()).To(ContainSubstring("quic: invalid http header field value")) }) + + It("rejects requests with an invalid request method", func() { + req1.Method = "foobär" + req1.Body = &mockBody{} + _, err := rt.RoundTrip(req1) + Expect(err).To(MatchError("quic: invalid method \"foobär\"")) + Expect(req1.Body.(*mockBody).closed).To(BeTrue()) + }) }) })