You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Harden HTTP/2 receive path against unbounded resource growth (#3474)
* Harden HTTP/2 receive path against unbounded resource growth
The HTTP/2 (h2) parser advertised several receive-side limits that were
never enforced, letting one hostile peer grow process memory without
bound:
- SETTINGS_MAX_CONCURRENT_STREAMS defaulted to unlimited and was never
checked on the server; every odd stream id was accepted, so a peer
could pin an unbounded number of streams per connection. The default
is now a bounded 1024 and the server rejects streams beyond it with
RST_STREAM(REFUSED_STREAM).
- SETTINGS_MAX_HEADER_LIST_SIZE defaulted to unlimited and was never
enforced on receive; decoded headers amplified by 1-byte HPACK
indexed references ("HPACK bomb") and never-completed
HEADERS/CONTINUATION fragments accumulated without bound. Both are
now capped at a 1MB default.
- The HPACK dynamic table size update was validated against the
protocol default instead of the size this endpoint advertised, so a
decoder configured with a smaller table could be forced to grow it
beyond the capacity it was sized for. Updates above the advertised
beyond the capacity it was sized for. Updates above the advertisedondi beyond the capacity it was sized for. Updates above the advertisg P beyETT beyond the capacity it was sized for. Updates above the advertisy wit beyond the capacity it was sized for. Updates above the advertisek_ beyond the capacity it was sized for. Updates above the advertisis de beyond the capacity it was sized for. Updates above the advertisedse beyond the capacity it wasfo beyond the capacity it was sized for. Updates above the adver continuing
to parse whatever the peer keeps sending.
Tests: new casesTests: new casesTests: new casesTests: new casesTests: nest cover each enforcement; the full
brpc_hpack_unittest, brpc_http_rpc_protocol_unittest,
brpc_h2_unsent_message_unittest and brpc_grpc_protocol_unittest suites
pass.
* Reset h2 header-list budget per header block and cap initial HEADERS fragment
Two follow-up fixes from code review of the HTTP/2 receive-path
hardening:
- The decoded header-list size counter was never reset when a new
HEADERS block began, so trailers on the same stream inherited the
budget of the initial header list and could be rejected even though
they form a separate list (RFC 7540 section 10.5.1 applies per
header block). Reset the counter at the start of OnHeaders; it stays
cumulative across the CONTINUATION frames that complete the same
block.
- The _remaining_header_fragment size cap was only checked when
CONTINUATION frames were processed, but a single oversized HEADERS
frame appends its unconsumed tail into the fragment too. Apply the
same cap in OnHeaders via a shared HeaderFragmentTooLarge() helper
and fail with ENHANCE_YOUR_CALM.
Tests: brpc_http_rpc_protocol_unittest gains two cases
(h2_header_list_budget_resets_per_block and
h2_oversized_single_headers_bloh2_oversized_single_headers_bloh2_oversized_single_headers_bloh2_oversized_single_headers_b_message_unittest and brpc_grpc_protocol_unittest suites
pass.
0 commit comments