Skip to content

Reject overflowing HPACK integers#9401

Merged
yschimke merged 1 commit intosquare:masterfrom
oreparaz:hpack-readint-overflow
Apr 5, 2026
Merged

Reject overflowing HPACK integers#9401
yschimke merged 1 commit intosquare:masterfrom
oreparaz:hpack-readint-overflow

Conversation

@oreparaz
Copy link
Copy Markdown
Contributor

@oreparaz oreparaz commented Apr 4, 2026

Summary. Reject malformed HPACK integers before they overflow in Hpack.Reader.readInt().

Problem. readInt() decodes HPACK continuation bytes into a signed 32-bit Int without bounding the number of continuation bytes or checking for overflow. An overlong HPACK integer can therefore wrap into a negative or unrelated small positive value, and malformed input is only rejected later by downstream parsing logic.

Impact. An HTTP/2 peer can use those malformed HPACK integers to cause connection-level DoS or to make OkHttp accept invalid HPACK state transitions that a compliant decoder should reject.

Fix. This change hardens readInt() by:

  • decoding into Long
  • rejecting more than 5 continuation bytes after the prefix
  • rejecting any increment that would exceed Int.MAX_VALUE
  • surfacing malformed values as IOException("HPACK integer overflow")

Valid HPACK integers are unchanged, including the existing max 31-bit case.

Tests. Added regression coverage in HpackTest for malformed HPACK integers that previously overflowed or wrapped:

  • direct integer overflow
  • too many continuation bytes
  • overflow in HPACK string lengths
  • overflow that previously wrapped into a small dynamic table size

Also updated the existing “insidious” HPACK tests to assert the new fail-fast behavior.

Decode HPACK integers in Long and reject values that would overflow Int.

This prevents malformed header indexes, dynamic table size updates, and string lengths from wrapping into negative or attacker-chosen small positive values.
@yschimke
Copy link
Copy Markdown
Collaborator

yschimke commented Apr 4, 2026

It doesn't sound like this materially changes the logic or avoids security issues, but does more closely follow the spec

https://datatracker.ietf.org/doc/html/rfc7541#section-5.1

This integer representation allows for values of indefinite size. It
is also possible for an encoder to send a large number of zero
values, which can waste octets and could be used to overflow integer
values. Integer encodings that exceed implementation limits -- in
value or octet length -- MUST be treated as decoding errors.
Different limits can be set for each of the different uses of
integers, based on implementation constraints.

@oreparaz
Copy link
Copy Markdown
Contributor Author

oreparaz commented Apr 4, 2026

@yschimke: Agreed, this is primarily a spec-compliance / parser-hardening change, which seems more aligned with RFC 7541 §5.1. The material difference is that malformed overlong HPACK integers now fail in readInt() instead of overflowing and being handled later by downstream logic.

@yschimke yschimke merged commit b938a8c into square:master Apr 5, 2026
24 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants