Skip to content

Commit 89f602b

Browse files
odeke-emgopherbot
authored andcommitted
http2: validate client/outgoing trailers
This change is a counterpart to the HTTP/1.1 trailers validation CL 572615. This change will ensure that we validate trailers that were set on the HTTP client before they are transformed to HTTP/2 equivalents. Updates golang/go#64766 Change-Id: Id1afd7f7e9af820ea969ef226bbb16e4de6d57a5 Reviewed-on: https://go-review.googlesource.com/c/net/+/572655 Auto-Submit: Damien Neil <[email protected]> TryBot-Result: Gopher Robot <[email protected]> Reviewed-by: Damien Neil <[email protected]> Run-TryBot: Emmanuel Odeke <[email protected]> LUCI-TryBot-Result: Go LUCI <[email protected]> Reviewed-by: David Chase <[email protected]>
1 parent 6e2c99c commit 89f602b

File tree

2 files changed

+34
-12
lines changed

2 files changed

+34
-12
lines changed

http2/transport.go

+22-11
Original file line numberDiff line numberDiff line change
@@ -2019,6 +2019,22 @@ func (cs *clientStream) awaitFlowControl(maxBytes int) (taken int32, err error)
20192019
}
20202020
}
20212021

2022+
func validateHeaders(hdrs http.Header) string {
2023+
for k, vv := range hdrs {
2024+
if !httpguts.ValidHeaderFieldName(k) {
2025+
return fmt.Sprintf("name %q", k)
2026+
}
2027+
for _, v := range vv {
2028+
if !httpguts.ValidHeaderFieldValue(v) {
2029+
// Don't include the value in the error,
2030+
// because it may be sensitive.
2031+
return fmt.Sprintf("value for header %q", k)
2032+
}
2033+
}
2034+
}
2035+
return ""
2036+
}
2037+
20222038
var errNilRequestURL = errors.New("http2: Request.URI is nil")
20232039

20242040
// requires cc.wmu be held.
@@ -2056,19 +2072,14 @@ func (cc *ClientConn) encodeHeaders(req *http.Request, addGzipHeader bool, trail
20562072
}
20572073
}
20582074

2059-
// Check for any invalid headers and return an error before we
2075+
// Check for any invalid headers+trailers and return an error before we
20602076
// potentially pollute our hpack state. (We want to be able to
20612077
// continue to reuse the hpack encoder for future requests)
2062-
for k, vv := range req.Header {
2063-
if !httpguts.ValidHeaderFieldName(k) {
2064-
return nil, fmt.Errorf("invalid HTTP header name %q", k)
2065-
}
2066-
for _, v := range vv {
2067-
if !httpguts.ValidHeaderFieldValue(v) {
2068-
// Don't include the value in the error, because it may be sensitive.
2069-
return nil, fmt.Errorf("invalid HTTP header value for header %q", k)
2070-
}
2071-
}
2078+
if err := validateHeaders(req.Header); err != "" {
2079+
return nil, fmt.Errorf("invalid HTTP header %s", err)
2080+
}
2081+
if err := validateHeaders(req.Trailer); err != "" {
2082+
return nil, fmt.Errorf("invalid HTTP trailer %s", err)
20722083
}
20732084

20742085
enumerateHeaders := func(f func(name, value string)) {

http2/transport_test.go

+12-1
Original file line numberDiff line numberDiff line change
@@ -2290,7 +2290,8 @@ func TestTransportRejectsContentLengthWithSign(t *testing.T) {
22902290
}
22912291

22922292
// golang.org/issue/14048
2293-
func TestTransportFailsOnInvalidHeaders(t *testing.T) {
2293+
// golang.org/issue/64766
2294+
func TestTransportFailsOnInvalidHeadersAndTrailers(t *testing.T) {
22942295
st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
22952296
var got []string
22962297
for k := range r.Header {
@@ -2303,6 +2304,7 @@ func TestTransportFailsOnInvalidHeaders(t *testing.T) {
23032304

23042305
tests := [...]struct {
23052306
h http.Header
2307+
t http.Header
23062308
wantErr string
23072309
}{
23082310
0: {
@@ -2321,6 +2323,14 @@ func TestTransportFailsOnInvalidHeaders(t *testing.T) {
23212323
h: http.Header{"foo": {"foo\x01bar"}},
23222324
wantErr: `invalid HTTP header value for header "foo"`,
23232325
},
2326+
4: {
2327+
t: http.Header{"foo": {"foo\x01bar"}},
2328+
wantErr: `invalid HTTP trailer value for header "foo"`,
2329+
},
2330+
5: {
2331+
t: http.Header{"x-\r\nda": {"foo\x01bar"}},
2332+
wantErr: `invalid HTTP trailer name "x-\r\nda"`,
2333+
},
23242334
}
23252335

23262336
tr := &Transport{TLSClientConfig: tlsConfigInsecure}
@@ -2329,6 +2339,7 @@ func TestTransportFailsOnInvalidHeaders(t *testing.T) {
23292339
for i, tt := range tests {
23302340
req, _ := http.NewRequest("GET", st.ts.URL, nil)
23312341
req.Header = tt.h
2342+
req.Trailer = tt.t
23322343
res, err := tr.RoundTrip(req)
23332344
var bad bool
23342345
if tt.wantErr == "" {

0 commit comments

Comments
 (0)