reject requests with an invalid request method

This commit is contained in:
Marten Seemann
2016-12-22 14:23:32 +07:00
parent feec325083
commit 1854279bb5
2 changed files with 36 additions and 0 deletions

View File

@@ -4,6 +4,7 @@ import (
"errors" "errors"
"fmt" "fmt"
"net/http" "net/http"
"strings"
"sync" "sync"
"golang.org/x/net/lex/httplex" "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) 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)) hostname := authorityAddr("https", hostnameFromRequest(req))
client, err := r.getClient(hostname) client, err := r.getClient(hostname)
if err != nil { if err != nil {
@@ -100,3 +106,25 @@ func closeRequestBody(req *http.Request) {
req.Body.Close() 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*<any CHAR except CTLs or separators>
*/
return len(method) > 0 && strings.IndexFunc(method, isNotToken) == -1
}
// copied from net/http/http.go
func isNotToken(r rune) bool {
return !httplex.IsTokenRune(r)
}

View File

@@ -105,5 +105,13 @@ var _ = Describe("RoundTripper", func() {
_, err := rt.RoundTrip(req1) _, err := rt.RoundTrip(req1)
Expect(err.Error()).To(ContainSubstring("quic: invalid http header field value")) 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())
})
}) })
}) })