← Back to Feed CACHED · 2026-05-17 09:42:19 · cache_key CVE-2025-29912
CVE-2016-1546 · CWE-399 · Disclosed 2016-07-06

The Apache HTTP Server 2

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

This is a jammed side lane, not a bridge collapse

CVE-2016-1546 is an availability-only flaw in Apache HTTP Server's early mod_http2 implementation. In vulnerable builds, a client can abuse HTTP/2 flow-control windows so Apache keeps stream worker threads tied up for too long, eventually starving the worker pool. The affected upstream versions are 2.4.17 and 2.4.18 only, and only when mod_http2 is enabled and HTTP/2 is actually exposed with h2 or h2c.

The raw vendor/NVD baseline of 5.9 / MEDIUM is a little generous for enterprise patch triage in 2025. Yes, it is unauthenticated and remote, but the attack surface is sharply narrowed by an old two-version window, an optional module, and an HTTP/2-specific configuration requirement; there is also no confidentiality or integrity impact and no strong evidence of broad in-the-wild abuse. For a 10,000-host estate, this is backlog cleanup unless you still have externally exposed Apache 2.4.17/2.4.18 with HTTP/2 turned on.

"Remote, unauthenticated DoS is real, but only on a tiny, opt-in slice of old Apache HTTP/2 deployments."
02 · The Attack Path

4 steps from start to impact.

STEP 01

Find an actually exposed mod_http2 target

The attacker needs an Apache server running 2.4.17 or 2.4.18 with mod_http2 loaded and HTTP/2 negotiated on a reachable listener. In practice this means a legacy server that explicitly enabled Protocols h2 or h2c, because the bug lives in the HTTP/2 worker model rather than generic Apache request handling.
Conditions required:
  • Target is Apache HTTP Server 2.4.17 or 2.4.18
  • mod_http2 is loaded
  • HTTP/2 is enabled and reachable from the attacker
Where this breaks in practice:
  • Affected window is only two upstream releases
  • mod_http2 was optional and relatively new at the time
  • Banner data alone does not prove mod_http2 is enabled or vulnerable
Detection/coverage: Most vulnerability scanners can flag version exposure, but many will miss the decisive runtime conditions: http2_module loaded plus h2/h2c enabled.
STEP 02

Open an HTTP/2 session with a custom client

Using a custom HTTP/2 client such as an nghttp2-based tool or a purpose-built script, the attacker establishes one or a small number of HTTP/2 connections and requests a response large enough to keep stream state active. This is not classic volumetric DDoS; it is a protocol-behavior abuse attack.
Conditions required:
  • Attacker can negotiate HTTP/2 to the target
  • Attacker can issue crafted stream requests and flow-control updates
Where this breaks in practice:
  • A browser is not enough; the attacker typically needs tooling that can manipulate HTTP/2 flow control precisely
  • Front-end proxies or CDNs that terminate HTTP/2 can break the attack path
Detection/coverage: Network tools may show valid HTTP/2 traffic, but not all IDS/WAF stacks inspect WINDOW_UPDATE behavior deeply enough to classify this as malicious.
STEP 03

Pin H2 worker threads with slow window updates

The attacker shrinks or drip-feeds HTTP/2 flow-control windows so Apache holds worker resources open while trying to serve the response. Imperva's HTTP/2 research describes this as an HTTP/2 Slow Read / Slow GET pattern that can keep threads alive as long as WINDOW_UPDATE frames continue arriving.
Conditions required:
  • Requested content is large enough to keep the response active
  • Server allocates H2 worker threads per affected stream
Where this breaks in practice:
  • Attack effectiveness depends on response shape and worker pool sizing
  • Aggressive upstream timeouts or HTTP/2-aware connection controls can blunt the impact
Detection/coverage: Host telemetry is better than perimeter telemetry here: look for many long-lived HTTP/2 streams, low send progress, and H2 workers staying busy with little throughput.
STEP 04

Starve stream processing and degrade service

Once enough H2 worker threads are occupied, new connections may still be accepted, but streams stop getting serviced normally. The practical result is service degradation or outage for HTTP/2 request processing, not code execution and not tenant escape.
Conditions required:
  • Enough workers are pinned to exhaust or bottleneck stream processing
Where this breaks in practice:
  • Impact is availability-only
  • Blast radius is limited to the affected Apache instance or pool behind the listener
Detection/coverage: Application monitoring usually catches this faster than signature controls: spikes in busy workers, request stalls, and HTTP/2 error/timeout anomalies.
03 · Intelligence Metadata

The supporting signals.

In-the-wild statusNo KEV listing and I found no authoritative public reporting of active exploitation campaigns tied to this CVE. Current evidence supports a known DoS technique, not a broadly weaponized campaign.
Proof-of-concept availabilityNo mainstream public exploit repo stands out for this exact CVE, but the attack method is well described in the Imperva HTTP/2 research and later academic work like PRETT2. A competent operator could recreate it with nghttp2 or a custom client.
EPSS0.41505 from the intel you provided. That is high for a CVE scorecard, but here it likely overstates operational urgency because reachability depends on a very specific legacy Apache + mod_http2 + config combination.
KEV statusNot listed in CISA's Known Exploited Vulnerabilities Catalog. No KEV add date applies.
CVSS vector reality checkCVSS:3.0/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:H is directionally fair on impact: network-reachable, no auth, availability-only. The important real-world discount is that AC:H understates the deployment friction created by the optional HTTP/2 module and narrow version band.
Affected versionsUpstream Apache says this affects 2.4.17 and 2.4.18 only, specifically the HTTP/2 support path in mod_http2.
Fixed versionsUpstream fixed it in Apache HTTP Server 2.4.20. Debian tracker also records unstable fixed at 2.4.20-1; Ubuntu notes xenial was not affected because HTTP/2 support was disabled there.
Exposure and scanning realityInternet-wide scanners can find Apache and often HTTP/2 support, but they usually cannot prove this exact condition remotely: vulnerable 2.4.17/2.4.18 *and* mod_http2 loaded *and* HTTP/2 exposed *and* not fixed via backport. This is why asset inventory beats external scanning for prioritization.
Disclosure timelineApache records: reported 2016-02-02, public 2016-04-11, update 2.4.20 released 2016-04-11. NVD/CVE publication is 2016-07-06.
Researcher / reporting orgApache credits Noam Mazor for the report. Imperva later documented the practical Slow Read / Slow GET attack pattern against Apache HTTP/2.
04 · The Call

noisgate verdict.

Final Verdict
DOWNGRADED to LOW (3.4/10)

The decisive factor is reachability friction: the bug only exists on a two-release upstream window and only when the optional mod_http2 module is enabled and exposed. That sharply shrinks the real population versus generic 'Apache remote DoS' framing, while the impact remains availability-only with no evidence of broad live abuse.

HIGH Affected upstream versions and fix version
HIGH Requirement for `mod_http2` and HTTP/2 exposure
MEDIUM Assessment that exploitation prevalence is low despite the elevated EPSS signal

Why this verdict

  • Downward adjustment: optional feature gate — exploitation requires mod_http2, not plain Apache. In many real estates, that single prerequisite wipes out most of the nominally affected population.
  • Downward adjustment: tiny version window — only 2.4.17 and 2.4.18 upstream are affected. This is not a sprawling 'all 2.4.x' bug.
  • Downward adjustment: post-fingerprint precision — an attacker must find servers that are old *and* HTTP/2-enabled *and* directly reachable. That is materially narrower than a generic internet-wide web bug.
  • Still not IGNORE — if the server is actually exposed, the attack is unauthenticated and remote and can cause real service degradation with modest attacker bandwidth.

Why not higher?

It is not higher because the blast radius is limited to availability, and the exploit chain is gated by a specific legacy configuration rather than normal Apache exposure. No strong primary-source evidence shows broad in-the-wild abuse, and modern estates often terminate HTTP/2 upstream or have long since moved past these releases.

Why not lower?

It is not lower because the attack does not require credentials, user interaction, or prior compromise. If you still run a directly exposed Apache 2.4.17/2.4.18 instance with HTTP/2 enabled, a remote adversary can realistically cause an outage on that node.

05 · Compensating Control

What to do — in priority order.

  1. Disable HTTP/2 on stragglers — If a legacy server cannot be upgraded immediately, remove h2 / h2c from Protocols or unload mod_http2. For a LOW verdict, noisgate assigns no formal SLA here; do it in the next routine web maintenance cycle, and sooner if the host is internet-facing.
  2. Terminate HTTP/2 upstream — Put the service behind a load balancer, CDN, or reverse proxy that terminates HTTP/2 and talks HTTP/1.1 to the old Apache backend. This breaks the vulnerable protocol path without changing application behavior; for LOW, treat this as backlog hygiene rather than an emergency change.
  3. Tune connection and request timeouts — Shorter keepalive behavior, request timeouts, and HTTP/2-aware limits reduce how long a slow-reader can pin resources. This is a compensating control, not a guaranteed fix, and it should be applied during normal hardening work for any host you cannot retire yet.
  4. Watch for H2 worker starvation — Instrument Apache status, reverse-proxy metrics, and host monitoring to alert on long-lived HTTP/2 streams with poor throughput and rising busy workers. For a LOW finding, fold this into standard observability improvements instead of spinning up a special response project.
What doesn't work
  • A generic signature WAF rule is weak here because the traffic can look syntactically valid; the abuse is in HTTP/2 flow-control behavior, not an obvious payload.
  • TLS alone does nothing. HTTP/2 over TLS (h2) is still the vulnerable path.
  • Just adding more worker threads is not a fix; it only raises the cost for the attacker and can still leave you vulnerable to resource starvation.
06 · Verification

Crowdsourced verification payload.

Run this on the target Linux/Unix Apache host as a local auditor. Invoke it with bash check_cve_2016_1546.sh or bash check_cve_2016_1546.sh /usr/sbin/apachectl; it needs only enough privilege to execute apachectl/httpd config inspection commands, not full root in most deployments.

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

set -u

APACHECTL="${1:-}"

find_apachectl() {
  local candidates=(
    "$APACHECTL"
    /usr/sbin/apachectl
    /usr/sbin/httpd
    /usr/local/apache2/bin/apachectl
    /usr/local/bin/apachectl
    apachectl
    httpd
  )
  local c
  for c in "${candidates[@]}"; do
    [ -n "$c" ] || continue
    if command -v "$c" >/dev/null 2>&1; then
      command -v "$c"
      return 0
    elif [ -x "$c" ]; then
      echo "$c"
      return 0
    fi
  done
  return 1
}

ver_ge() {
  # returns 0 if $1 >= $2
  [ "$(printf '%s\n%s\n' "$1" "$2" | sort -V | tail -n1)" = "$1" ]
}

APACHE_BIN="$(find_apachectl)" || {
  echo "UNKNOWN - could not locate apachectl/httpd"
  exit 2
}

VSTR="$($APACHE_BIN -v 2>/dev/null | awk -F'Apache/' '/Server version/ {print $2}' | awk '{print $1}')"
if [ -z "$VSTR" ]; then
  echo "UNKNOWN - could not determine Apache version via '$APACHE_BIN -v'"
  exit 2
fi

MAJMINPATCH="$VSTR"
MODULES="$($APACHE_BIN -M 2>/dev/null || true)"
RUNCFG="$($APACHE_BIN -t -D DUMP_RUN_CFG 2>/dev/null || true)"
FULLCFG="$($APACHE_BIN -t -D DUMP_VHOSTS 2>/dev/null || true)"

HTTP2_LOADED=0
if echo "$MODULES" | grep -Eq '(^|\s)http2_module(\s|$)'; then
  HTTP2_LOADED=1
fi

H2_ENABLED=0
if echo "$RUNCFG" | grep -Eiq '\bh2(c)?\b'; then
  H2_ENABLED=1
fi
# Fallback: parse common config locations if run_cfg did not expose protocol lines
if [ "$H2_ENABLED" -eq 0 ]; then
  for f in /etc/httpd/conf/httpd.conf /etc/apache2/apache2.conf /etc/apache2/sites-enabled/* /usr/local/apache2/conf/httpd.conf; do
    [ -r "$f" ] || continue
    if grep -Eiq '^[[:space:]]*Protocols[[:space:]].*\bh2(c)?\b' "$f" 2>/dev/null; then
      H2_ENABLED=1
      break
    fi
  done
fi

# Known-safe outcomes first
if ! echo "$MAJMINPATCH" | grep -Eq '^2\.4\.(17|18)$'; then
  if ver_ge "$MAJMINPATCH" "2.4.20"; then
    echo "PATCHED - Apache version $MAJMINPATCH is at or above upstream fix 2.4.20"
    exit 0
  fi
  # Older or vendor-backported builds are ambiguous
  if [ "$HTTP2_LOADED" -eq 0 ] || [ "$H2_ENABLED" -eq 0 ]; then
    echo "PATCHED - vulnerable HTTP/2 path not active (http2_module loaded=$HTTP2_LOADED, h2 enabled=$H2_ENABLED)"
    exit 0
  fi
  echo "UNKNOWN - Apache version $MAJMINPATCH is not an exact upstream vulnerable version, but runtime/backport status is unclear"
  exit 2
fi

# Exact upstream vulnerable versions
if [ "$HTTP2_LOADED" -eq 1 ] && [ "$H2_ENABLED" -eq 1 ]; then
  echo "VULNERABLE - Apache $MAJMINPATCH with mod_http2 loaded and HTTP/2 enabled"
  exit 1
fi

if [ "$HTTP2_LOADED" -eq 0 ] || [ "$H2_ENABLED" -eq 0 ]; then
  echo "PATCHED - Apache $MAJMINPATCH present, but vulnerable path not active (http2_module loaded=$HTTP2_LOADED, h2 enabled=$H2_ENABLED)"
  exit 0
fi

echo "UNKNOWN - unable to conclusively determine mod_http2/HTTP2 runtime state"
exit 2
07 · Bottom Line

If you remember one thing.

TL;DR
Monday morning, do not burn an emergency patch window on this unless you already know you still have externally exposed Apache 2.4.17/2.4.18 with HTTP/2 enabled. Query the fleet for those exact versions plus http2_module, disable HTTP/2 on any confirmed stragglers during the next normal change cycle, and retire or upgrade them as routine hygiene; for a LOW verdict, the noisgate mitigation SLA is no SLA (treat as backlog hygiene) and the noisgate remediation SLA is also no SLA (treat as backlog hygiene).

Sources

  1. Apache HTTP Server 2.4 vulnerabilities entry for CVE-2016-1546
  2. NVD CVE-2016-1546
  3. Apache mod_http2 documentation
  4. Debian security tracker CVE-2016-1546
  5. Ubuntu CVE-2016-1546 status
  6. CISA Known Exploited Vulnerabilities Catalog
  7. Imperva HTTP/2 in-depth analysis report
  8. PRETT2 academic paper referencing CVE-2016-1546
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.