← Back to Feed CACHED · 2026-05-17 09:42:19 · cache_key CVE-2025-29912
CVE-2026-49975 · CWE-400 · Disclosed 2026-06-02

Apache mod_http2 cookie crumb accounting lets HTTP/2 requests exhaust server memory

ASSESSED — NOISGATE V0.5
Vendor
Reassessed
Verdict:
01 · The Real Story

This is a tiny air hose jammed into a fire-suppression tank until the whole room runs out of pressure

CVE-2026-49975 tracks Apache HTTP Server's mod_http2 handling of split cookie headers under HTTP/2. A remote client can seed HPACK's dynamic table with a tiny cookie entry, replay thousands of indexed references, and force Apache to repeatedly rebuild merged cookie strings while keeping the stream alive with a zero flow-control window. The bug affects Apache deployments with mod_http2 enabled and HTTP/2 exposed; the public repro was validated against Apache 2.4.67, and Apache's fix landed as mod_http2 2.0.41 on 2026-05-27.

There is no vendor CVSS baseline here, so this is = ASSESSED AT HIGH. The important reality check: this is *not* an RCE or data-theft bug, but it *is* unauthenticated, internet-reachable on any public Apache HTTP/2 edge, works against default behavior, and already has public PoC material. That combination pushes it above routine DoS backlog noise, while the availability-only impact keeps it out of CRITICAL.

"ASSESSED AT HIGH: one unauthenticated HTTP/2 client can pin Apache memory fast enough to knock over public services"
02 · The Attack Path

5 steps from start to impact.

STEP 01

Reach an HTTP/2-enabled Apache edge

The attacker only needs network reachability to an Apache listener that negotiates h2 or accepts h2c. mod_http2 must be loaded and the site must actually allow HTTP/2 via Protocols; no credentials, prior foothold, or user interaction are required.
Conditions required:
  • Apache HTTP Server with mod_http2 loaded
  • HTTP/2 enabled on the target vhost or listener
  • Attacker can open TCP/TLS sessions to the service
Where this breaks in practice:
  • Many internal Apache servers never expose HTTP/2 directly to the internet
  • A CDN, ADC, or reverse proxy that terminates HTTP/2 upstream can shrink reachable population
  • Some enterprises disable mod_http2 on legacy or admin-only vhosts
Detection/coverage: External scanners can usually confirm h2 negotiation, but they do not prove the vulnerable cookie-accounting path or module version.
STEP 02

Seed the HPACK table with the PoC

Using the public Calif PoC hpack_httpd_cookie_bomb.py, the attacker inserts a small cookie header into the HPACK dynamic table once, then references it by index. This makes the on-wire payload extremely cheap while forcing Apache to materialize many logical headers server-side.
Conditions required:
  • HTTP/2 header compression is active
  • Server accepts header blocks and cookie crumbs as normal
Where this breaks in practice:
  • HTTP/2-aware edge devices that enforce a hard header-count cap can stop this early
  • Implementations that do not split or merge cookies the Apache way are not this CVE
Detection/coverage: Most web scanners miss this because it needs protocol-aware HPACK manipulation, not simple malformed requests.
STEP 03

Bypass field-count protections through cookie merging

Apache's vulnerable behavior is that split cookie crumbs are merged without counting them properly against LimitRequestFields. The attacker can therefore submit thousands of cookie references and drive repeated string rebuilds, creating roughly 4000:1 allocation amplification in the public repro.
Conditions required:
  • Vulnerable mod_http2 build prior to 2.0.41
  • Cookie header accounting not fixed
Where this breaks in practice:
  • Patched mod_http2 2.0.41+ closes the accounting bypass
  • Very small per-request limits can reduce per-stream blast radius, though not eliminate the class
Detection/coverage: Config review can identify vulnerable combinations better than runtime signature scanning; Apache commit 47d3100 is the key fix reference.
STEP 04

Pin the allocations with a stalled response

The attacker advertises SETTINGS_INITIAL_WINDOW_SIZE=0, preventing the server from draining its response and freeing stream state. By trickling WINDOW_UPDATE frames, the client keeps resetting idle logic and holds the inflated memory in place far longer than a normal request lifecycle would allow.
Conditions required:
  • Client controls HTTP/2 flow-control window
  • Server keeps the stalled stream alive
Where this breaks in practice:
  • Aggressive connection timeout and stream lifetime enforcement can reduce hold time
  • Front-end proxies that fully terminate HTTP/2 may absorb the behavior before Apache sees it
Detection/coverage: HTTP/2 telemetry, if you have it, should show anomalous zero-window sessions, high stream counts, and long-lived low-throughput connections.
STEP 05

Exhaust worker memory and degrade availability

Once enough streams or connections are pinned, Apache workers consume memory until the host swaps, workers OOM, or the service stops responding. In the published repro, a single client drove roughly 32 GB of memory consumption in about 18 seconds against Apache 2.4.67.
Conditions required:
  • Sufficient memory headroom to be consumed
  • No earlier connection-kill, cgroup, or upstream edge enforcement
Where this breaks in practice:
  • Tight cgroup or container memory caps can kill a worker before the whole node collapses
  • Horizontal scaling and front-door rate controls can blunt but not remove the impact
Detection/coverage: Infrastructure monitoring catches the symptom quickly: RSS spikes, swap growth, OOM kills, 5xx rates, and worker churn.
03 · Intelligence Metadata

The supporting signals.

In-the-wild statusNo CISA KEV listing and no authoritative public evidence of mass exploitation found as of 2026-06-02; however, the public writeup explicitly released working exploit material.
PoC availabilityYes. Calif published a companion repo with Apache-specific repro content including hpack_httpd_cookie_bomb.py and a tested harness against Apache 2.4.67: PoC repo.
Reporter / researcherCalif credits Quang Luong for discovering the exploit, with Jun Rong and Duc Phan confirming it on other servers.
Disclosure timelineCalif says Apache was notified on 2026-05-27 and Stefan Eissing fixed it the same day; the public blog and PoC dropped on 2026-06-02.
Affected scopeApache HTTP Server instances with mod_http2 enabled and HTTP/2 exposed. The public repro states it was built against docker.io/library/httpd:latest, observed as Apache 2.4.67.
Fixed versionApache fix landed as mod_http2 2.0.41. Calif noted that on 2026-06-02 it was available from standalone mod_http2 releases and trunk, but *not yet in a 2.4.x httpd release* at that time.
Related vendor statusThe same cross-vendor attack pattern also affected nginx, which added max_headers in 1.29.8 the day after disclosure to them. Calif reported IIS, Envoy, and Pingora as notified with fix status unknown at publication.
Exposure / scanning dataCalif reports a Shodan query found 880,000+ sites supporting HTTP/2 and running one of the affected server families, though many are shielded by CDNs. That is not Apache-only exposure, but it confirms a large reachable population for the attack class.
EPSSNo FIRST EPSS score for this CVE was located during review. *Inference:* the CVE appears too new / not yet fully represented in public EPSS data.
Assessed CVSS vector*Inference:* CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H — unauthenticated remote network attack with pure availability impact.
04 · The Call

noisgate verdict.

Final Verdict
= UNCHANGED to HIGH (8.1/10)

The decisive factor is unauthenticated remote reachability on internet-facing Apache HTTP/2 edges combined with a public, low-complexity PoC. What keeps this out of CRITICAL is that the blast radius is service availability, not code execution or tenant escape.

HIGH Apache `mod_http2` is affected and fixed in `2.0.41`
HIGH Attack complexity is low once HTTP/2 is exposed
MEDIUM Enterprise-wide exposure fraction, because many Apache estates sit behind HTTP/2-terminating edges

Why this verdict

  • Starting point: 7.5 availability-heavy network CVSS. This is an unauthenticated remote DoS with no user interaction and a clean path from the internet to the bug on any exposed Apache HTTP/2 listener.
  • Upward pressure: public exploit chain and default behavior. Calif published a working Apache repro on 2026-06-02, and the writeup says the vulnerable behavior exists in default HTTP/2 configurations rather than niche custom modules.
  • Upward pressure: single-client efficiency is ugly. The published Apache repro shows roughly 32 GB in ~18 seconds and around 4000:1 amplification, which is enough to topple undersized edges fast.
  • Downward pressure: attacker must hit an Apache endpoint that actually terminates HTTP/2. If your CDN, WAF, or reverse proxy terminates h2 before Apache, the reachable population drops materially.
  • Downward pressure: impact is availability-only. There is no evidence here of code execution, auth bypass, or cross-tenant data compromise; the business pain is outage, not takeover.
  • Net result: = ASSESSED AT HIGH. Internet-reachable, exploit-ready, default-path DoS belongs above backlog hygiene, but the lack of confidentiality/integrity impact keeps it below CRITICAL.

Why not higher?

This is not a pre-auth RCE, not a privilege-escalation chain, and not a data-exposure issue. Even though the memory amplification is severe, the end state is service degradation or outage, so the blast radius is materially narrower than bugs that hand over the host or application tier.

Why not lower?

Scoring this lower would ignore the combination that matters operationally: public PoC, no auth, network reachability, and default HTTP/2 behavior. A bug that can let one cheap client pin tens of gigabytes on a public edge is not routine nuisance DoS.

05 · Compensating Control

What to do — in priority order.

  1. Disable HTTP/2 on exposed Apache vhosts — If you cannot prove mod_http2 2.0.41+ or a vendor backport, remove h2/h2c from Protocols as the primary containment step. For a HIGH verdict, deploy this compensating control within 30 days; if the site is internet-facing and high-business-impact, do it far sooner.
  2. Enforce HTTP/2 header-count limits upstream — Put a CDN, ADC, WAF, or reverse proxy in front of Apache that can terminate HTTP/2 and enforce a hard header-count cap, including cookie crumbs. This is the best architectural mitigation when Apache itself cannot be updated immediately; deploy within 30 days.
  3. Cap per-worker memory — Use cgroups, container limits, or equivalent process memory caps so a bombed worker dies before the whole node is dragged into swap. This does not fix exploitability, but it reduces node-wide blast radius; deploy within 30 days.
  4. Tighten connection and stream lifetime limits — Reduce idle timeouts, keepalive duration, and stream lifetime where your application tolerates it so zero-window stalls do not persist indefinitely. This is a risk reducer, not a cure; implement within 30 days.
  5. Alert on anomalous HTTP/2 behavior — Instrument for zero-window sessions, long-lived low-throughput h2 connections, abnormal header counts, RSS spikes, and worker churn. This gives you a fighting chance to identify active abuse before it becomes a broad outage; deploy within 30 days.
What doesn't work
  • LimitRequestFields alone does not solve this on vulnerable Apache builds; the fix specifically changed cookie accounting so crumbs can no longer bypass that limit.
  • Only limiting *decoded header size* is not enough; Calif's writeup shows the amplification comes from per-entry bookkeeping and repeated merge allocation, not just oversized logical headers.
  • TLS by itself does nothing. If Apache is the HTTP/2 termination point, encrypted transport still delivers the exploit straight to the vulnerable parser.
06 · Verification

Crowdsourced verification payload.

Run this on the Apache host itself as a local auditor or via your config-management runner. Invoke it as bash check_cve_2026_49975.sh /usr/sbin/apachectl or just bash check_cve_2026_49975.sh; it needs read access to Apache config and module files, and sudo helps on locked-down installs.

noisgate-verify.sh
BASHREAD-ONLYSAFE
#!/usr/bin/env bash
# check_cve_2026_49975.sh
# Detect likely exposure to CVE-2026-49975 on Apache HTTP Server.
# Exit codes: 0 PATCHED, 1 VULNERABLE, 2 UNKNOWN

set -u

APACHECTL="${1:-}"
if [[ -z "$APACHECTL" ]]; then
  for c in apachectl apache2ctl httpd; do
    if command -v "$c" >/dev/null 2>&1; then
      APACHECTL="$(command -v "$c")"
      break
    fi
  done
fi

if [[ -z "$APACHECTL" ]]; then
  echo "UNKNOWN: could not find apachectl/apache2ctl/httpd"
  exit 2
fi

TMPM="$(mktemp)"
TMPC="$(mktemp)"
trap 'rm -f "$TMPM" "$TMPC"' EXIT

if ! "$APACHECTL" -M >"$TMPM" 2>/dev/null; then
  echo "UNKNOWN: unable to enumerate loaded modules with $APACHECTL -M"
  exit 2
fi

if ! grep -qiE 'http2_module|mod_http2' "$TMPM"; then
  echo "PATCHED: mod_http2 not loaded"
  exit 0
fi

if ! "$APACHECTL" -t -D DUMP_RUN_CFG >"$TMPC" 2>/dev/null; then
  # continue; many builds still allow -t config tests but not dump details
  :
fi

HTTP2_ENABLED=0
if grep -RsiE '^\s*Protocols\b.*\b(h2|h2c)\b' /etc/httpd /etc/apache2 /usr/local/etc/apache2 2>/dev/null | grep -q .; then
  HTTP2_ENABLED=1
elif grep -siE '\bProtocols\b.*\b(h2|h2c)\b' "$TMPC" >/dev/null 2>&1; then
  HTTP2_ENABLED=1
fi

if [[ "$HTTP2_ENABLED" -eq 0 ]]; then
  echo "PATCHED: mod_http2 is present but HTTP/2 does not appear enabled in active config"
  exit 0
fi

MODPATH=""
for p in \
  /usr/lib64/httpd/modules/mod_http2.so \
  /usr/lib/httpd/modules/mod_http2.so \
  /usr/lib/apache2/modules/mod_http2.so \
  /usr/local/apache2/modules/mod_http2.so; do
  if [[ -f "$p" ]]; then
    MODPATH="$p"
    break
  fi
done

if [[ -z "$MODPATH" ]]; then
  MODPATH="$(find /usr/lib* /usr/local -type f -name mod_http2.so 2>/dev/null | head -n1)"
fi

if [[ -z "$MODPATH" || ! -r "$MODPATH" ]]; then
  echo "UNKNOWN: HTTP/2 enabled and mod_http2 loaded, but mod_http2.so path/version could not be determined"
  exit 2
fi

VER="$(strings "$MODPATH" 2>/dev/null | grep -Eo '2\.[0-9]+\.[0-9]+' | sort -Vu | tail -n1)"
if [[ -z "$VER" ]]; then
  PKGVER="$(rpm -qf "$MODPATH" 2>/dev/null || dpkg -S "$MODPATH" 2>/dev/null || true)"
  echo "UNKNOWN: could not extract mod_http2 version from $MODPATH ($PKGVER)"
  exit 2
fi

ver_lt() {
  # returns 0 if $1 < $2
  [[ "$(printf '%s\n%s\n' "$1" "$2" | sort -V | head -n1)" != "$2" ]]
}

if ver_lt "$VER" "2.0.41"; then
  echo "VULNERABLE: mod_http2 version $VER with HTTP/2 enabled (fixed in 2.0.41)"
  exit 1
fi

echo "PATCHED: mod_http2 version $VER and HTTP/2 enabled"
exit 0
07 · Bottom Line

If you remember one thing.

TL;DR
Monday morning, pull an inventory of every Apache listener terminating HTTP/2 and separate internet-facing edges from internal-only nodes. For this HIGH assessment, the noisgate mitigation SLA is ≤30 days: either disable HTTP/2 on exposed Apache vhosts or put them behind an upstream component that enforces hard HTTP/2 header-count limits; then complete the actual fix by the noisgate remediation SLA of ≤180 days by moving to a vendor-supported build that includes Apache's mod_http2 2.0.41 fix or equivalent backport. If a site is public and business-critical, do not wait for the outer edge of those deadlines.

Sources

  1. Calif writeup: HTTP/2 Bomb and CVE assignment
  2. Calif companion repository
  3. Calif Apache-specific PoC and repro
  4. Apache fix commit for mod_http2 2.0.41
  5. mod_h2 release v2.0.41
  6. Apache mod_http2 documentation
  7. nginx related hardening commit (`max_headers`)
  8. FIRST EPSS reference
Peer Review

What defenders are saying.

Submit a review attribution: handle + country only
0 flags selected · stored anonymously
Validation Results

Crowdsourced verification outputs.

Results submitted by users who ran the verification payload against their environment.