diff options
| author | Roberto Clapis <roberto@golang.org> | 2021-04-07 14:36:40 +0200 |
|---|---|---|
| committer | Filippo Valsorda <filippo@golang.org> | 2021-05-10 23:42:56 +0000 |
| commit | 5c489514bc5e61ad9b5b07bd7d8ec65d66a0512a (patch) | |
| tree | 2b936bb8bf6f8957348dcb17e424d9559c737372 /src/net/http/httputil/reverseproxy.go | |
| parent | dc50683bf7ebdfde726d710131ba05fe97e10a07 (diff) | |
| download | go-5c489514bc5e61ad9b5b07bd7d8ec65d66a0512a.tar.xz | |
net/http: switch HTTP1 to ASCII equivalents of string functions
The current implementation uses UTF-aware functions
like strings.EqualFold and strings.ToLower.
This could, in some cases, cause http smuggling.
Change-Id: I0e76a993470a1e1b1b472f4b2859ea0a2b22ada0
Reviewed-on: https://go-review.googlesource.com/c/go/+/308009
Run-TryBot: Filippo Valsorda <filippo@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Trust: Roberto Clapis <roberto@golang.org>
Reviewed-by: Filippo Valsorda <filippo@golang.org>
Diffstat (limited to 'src/net/http/httputil/reverseproxy.go')
| -rw-r--r-- | src/net/http/httputil/reverseproxy.go | 12 |
1 files changed, 10 insertions, 2 deletions
diff --git a/src/net/http/httputil/reverseproxy.go b/src/net/http/httputil/reverseproxy.go index db42ac6ba5..1432ee26d3 100644 --- a/src/net/http/httputil/reverseproxy.go +++ b/src/net/http/httputil/reverseproxy.go @@ -13,6 +13,7 @@ import ( "log" "net" "net/http" + "net/http/internal/ascii" "net/textproto" "net/url" "strings" @@ -242,6 +243,10 @@ func (p *ReverseProxy) ServeHTTP(rw http.ResponseWriter, req *http.Request) { outreq.Close = false reqUpType := upgradeType(outreq.Header) + if !ascii.IsPrint(reqUpType) { + p.getErrorHandler()(rw, req, fmt.Errorf("client tried to switch to invalid protocol %q", reqUpType)) + return + } removeConnectionHeaders(outreq.Header) // Remove hop-by-hop headers to the backend. Especially @@ -538,13 +543,16 @@ func upgradeType(h http.Header) string { if !httpguts.HeaderValuesContainsToken(h["Connection"], "Upgrade") { return "" } - return strings.ToLower(h.Get("Upgrade")) + return h.Get("Upgrade") } func (p *ReverseProxy) handleUpgradeResponse(rw http.ResponseWriter, req *http.Request, res *http.Response) { reqUpType := upgradeType(req.Header) resUpType := upgradeType(res.Header) - if reqUpType != resUpType { + if !ascii.IsPrint(resUpType) { // We know reqUpType is ASCII, it's checked by the caller. + p.getErrorHandler()(rw, req, fmt.Errorf("backend tried to switch to invalid protocol %q", resUpType)) + } + if !ascii.EqualFold(reqUpType, resUpType) { p.getErrorHandler()(rw, req, fmt.Errorf("backend tried to switch protocol %q when %q was requested", resUpType, reqUpType)) return } |
