# CVE-2024-2398: HTTP/2 push headers memory-leak

libcurl leaks each PUSH_PROMISE header string when aborting HTTP/2 server push over 1000 headers, letting a malicious server exhaust client memory.

- Payout: hidden
- Severity: medium
- Program: Internet Bug Bounty
- Found by (vendor credit): w0x42 on hackerone
- Found by: w0x42
- Disclosed: 2024-04-22
- CVE: CVE-2024-2398
- Write-up quality: 6/10
- Original: https://hackerone.com/reports/2442613
- Library page: https://bugbountylibrary.com/r/h1%3A2442613
- Tags: area:oss domain:oss impact:dos kind:bounty platform:hackerone sev:medium tech:curl technique:source-review vuln:dos vuln:memory-corruption

**Target:** libcurl HTTP/2 server push handling (http2.c on_header)
**Root cause:** When PUSH_PROMISE headers exceed the 1000 limit, on_header frees stream->push_headers array but not the individual name:value strings allocated via aprintf; same on Curl_saferealloc failure. Error fails silently.
**Steps:**
1. Compile nghttp2 with patch and compile http2_push_promise test client
2. Run `nghttpd -p/=/foo.bar --no-tls 8181` (each -p sends 200 PUSH_PROMISE frames with 1280 headers)
3. Run `valgrind --leak-check=full http2_push_promise` against the server
4. Observe ~8MB definitely lost in on_header allocations
**How found:** Code reading of on_header: noticed aprintf-allocated header strings stored in push_headers array, then the abort path frees only the array, not its elements; confirmed with valgrind.
**Exploitation:** Malicious HTTP/2 server sends many PUSH_PROMISE frames each with >1000 headers; libcurl aborts push but leaks megabytes per response, repeatedly consuming client memory until exhaustion/DoS.
**Insight:** Audit error/abort paths of container-of-pointers structures: freeing the array but not each element leaks; valgrind on a crafted server response surfaces it. Silent error returns hide the leak from applications.
