x/net/http2: limits on header block size #12843
The spec provides a way to enforce limits on header block size. Without this feature, clients may cause a server to buffer arbitrarily large headers in memory before servicing the request. Through careful but simple crafting of HPACK encoded cookie headers, a malicious client is able to achieve an over 4000x amplification from bytes on the wire to server memory used with quadratic string garbage generation.
I would expect the http2 server to advertise a reasonable SETTINGS_MAX_HEADER_LIST_SIZE by default (possibly lifting the MaxHeaderBytes field from the http.Server) and enforce it. Potentially, although maybe deserving a separate tracking issue, the cookie header should not use string concatenation as it would still remain a target for massive garbage generation with the existing defaults.
The text was updated successfully, but these errors were encountered:
There are already tests which cover the behavior. This is simply moving where it happens. I'm not adding new tests to cover the very bad behavior because once the rest of the bug is fixed, it won't be possible to observe anyway. But even for smallish inputs, this is faster. Part of golang/go#12843 Change-Id: I7d69f2409e2adb4a01d101a915e09cf887b03f21 Reviewed-on: https://go-review.googlesource.com/15601 Reviewed-by: Andrew Gerrand <email@example.com>
These were proposed in the RFC over three years ago, then proposed to be added to Go in https://codereview.appspot.com/7678043/ 2 years and 7 months ago, and the spec hasn't been updated or retracted the whole time. Time to export them. Of note, HTTP/2 uses code 431 (Request Header Fields Too Large). Updates #12843 Change-Id: I78c2fed5fab9540a98e845ace73f21c430a48809 Reviewed-on: https://go-review.googlesource.com/15732 Reviewed-by: Ian Lance Taylor <firstname.lastname@example.org> Run-TryBot: Brad Fitzpatrick <email@example.com> TryBot-Result: Gobot Gobot <firstname.lastname@example.org>
In the first attempt to enforce the SETTINGS_MAX_HEADER_LIST_SIZE (https://go-review.googlesource.com/15751), the enforcement happened in the hpack decoder and the hpack decoder returned errors on Write and Close if the limit was violated. This was incorrect because the decoder is used over the life of the connection and all subsequent requests and could therefore get out of sync. Instead, this moves the counting of the limit up to the http2 package in the serverConn type, and replaces the hpack counting mechanism with a simple on/off switch. When SetEmitEnabled is set false, the header field emit callbacks will be suppressed and the hpack Decoder will do less work (less CPU and garbage) if possible, but will still return nil from Write and Close on valid input, and will still stay in sync it the stream. The http2 Server then returns a 431 error if emits were disabled while processing the HEADER or any CONTINUATION frames. Fixes golang/go#12843 Change-Id: I3b41aaefc6c6ee6218225f8dc62bba6ae5fe8f2d Reviewed-on: https://go-review.googlesource.com/15733 Reviewed-by: Andrew Gerrand <email@example.com>