Skip to content

nghttp2: nothing bounds what a request's headers decode to, so one 16 KB frame makes 62 MB (HPACK bomb) #508

Closed

Description

@MDA2AV

What happens

Nothing bounds what a request's headers decode to on this stack.

  • nghttp2 calls back once per decoded field, and CallbackHeader copies each into the request's arena.
  • MaxRequestBytes (8 MiB, documented as "headers plus body") is only checked in CallbackData, against the body. Its doc also says nghttp2 enforces its own header-list limits, but no such limit bounds a block's decoded size here.

So the HPACK bomb from #507 works here too: once a field of about 4 KiB is in the dynamic table, each one-byte reference to it decodes to the whole field.

Reach

Any client, with no authentication, on the default options. A request that never ends stays in _pending, with its arena, until the connection closes (by reading).

Repro

Unit, over the strict test transport, on main 58620b5. One HEADERS frame of 16,014 B, after a request that puts a 4,064 B field in the dynamic table:

  • the handler sees 16,000 fields, 62 MB of them;
  • nothing is reset, and the connection serves on.

Fix

Count decoded bytes against MaxRequestBytes in CallbackHeader, and mark the request Overflowed, so it is reset with ENHANCE_YOUR_CALM as an oversized body is. Its fields stop being copied from there on.

Found by a review of #500.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions