diff options
| author | Damien Neil <dneil@google.com> | 2021-07-07 16:34:34 -0700 |
|---|---|---|
| committer | Filippo Valsorda <filippo@golang.org> | 2021-07-30 14:01:30 +0000 |
| commit | b7a85e0003cedb1b48a1fd3ae5b746ec6330102e (patch) | |
| tree | fe86fc80397496bbb065a7a1ae55799111b240b2 /src/net/http/httputil/reverseproxy.go | |
| parent | 70fd4e47d73b92fe90e44ac785e2f98f9df0ab67 (diff) | |
| download | go-b7a85e0003cedb1b48a1fd3ae5b746ec6330102e.tar.xz | |
net/http/httputil: close incoming ReverseProxy request body
Reading from an incoming request body after the request handler aborts
with a panic can cause a panic, becuse http.Server does not (contrary
to its documentation) close the request body in this case.
Always close the incoming request body in ReverseProxy.ServeHTTP to
ensure that any in-flight outgoing requests using the body do not
read from it.
Updates #46866
Fixes CVE-2021-36221
Change-Id: I310df269200ad8732c5d9f1a2b00de68725831df
Reviewed-on: https://go-review.googlesource.com/c/go/+/333191
Trust: Damien Neil <dneil@google.com>
Reviewed-by: Brad Fitzpatrick <bradfitz@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 | 9 |
1 files changed, 9 insertions, 0 deletions
diff --git a/src/net/http/httputil/reverseproxy.go b/src/net/http/httputil/reverseproxy.go index 5d39955d62..8b63368386 100644 --- a/src/net/http/httputil/reverseproxy.go +++ b/src/net/http/httputil/reverseproxy.go @@ -235,6 +235,15 @@ func (p *ReverseProxy) ServeHTTP(rw http.ResponseWriter, req *http.Request) { if req.ContentLength == 0 { outreq.Body = nil // Issue 16036: nil Body for http.Transport retries } + if outreq.Body != nil { + // Reading from the request body after returning from a handler is not + // allowed, and the RoundTrip goroutine that reads the Body can outlive + // this handler. This can lead to a crash if the handler panics (see + // Issue 46866). Although calling Close doesn't guarantee there isn't + // any Read in flight after the handle returns, in practice it's safe to + // read after closing it. + defer outreq.Body.Close() + } if outreq.Header == nil { outreq.Header = make(http.Header) // Issue 33142: historical behavior was to always allocate } |
