Skip to main content
← All libraries
Network · C

How to fuzz nghttp2

nghttp2 powers nginx and curl HTTP/2 — HPACK decompression is a compact integer-overflow surface.

nghttp2 is the HTTP/2 library behind nginx, curl, and many CDN stacks. Its HPACK decoder expands compressed headers using a dynamic table with pointer-arithmetic indexing, and its flow-control window management involves 31-bit arithmetic that can underflow when handling RST_STREAM races.

Common bug classes

  • Heap buffer overflow in HPACK dynamic table index expansion
  • Integer overflow in HTTP/2 WINDOW_UPDATE increment validation
  • Out-of-bounds read in header field name/value length decode
  • Use-after-free in stream priority tree restructuring
  • Null dereference on CONTINUATION frame without preceding HEADERS

Recommended setup

Fuzzers

  • AFL++
  • libFuzzer

Sanitizers

  • ASan
  • UBSan

Harness scaffold

#include <stdint.h>
#include <stddef.h>
#include <nghttp2/nghttp2.h>

static int on_header(nghttp2_session *s, const nghttp2_frame *f,
                     const uint8_t *n, size_t nlen,
                     const uint8_t *v, size_t vlen,
                     uint8_t flags, void *ud) {
  (void)s;(void)f;(void)n;(void)nlen;(void)v;(void)vlen;(void)flags;(void)ud;
  return 0;
}

int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
  nghttp2_hd_inflater *inflater;
  if (nghttp2_hd_inflate_new(&inflater) != 0) return 0;
  nghttp2_nv nva[64]; size_t nvlen;
  int inflate_flags = 0;
  nghttp2_hd_inflate_hd2(inflater, nva, &nvlen, &inflate_flags,
                          data, size, 1);
  nghttp2_hd_inflate_del(inflater);
  return 0;
}

Save this as fuzz_target.cc, build with your compiler + sanitizer flags, and you have a working starting point.

Notable CVEs found by fuzzing

  • CVE-2023-44487
Start fuzzing nghttp2 on Fuzze.rs →

Push the harness above + a Dockerfile. First month 50% off.