← Back to Feed CACHED · 2026-07-20 08:30:36 · CACHE_KEY CVE-2026-59173
CVE-2026-59173 · CWE-400 · Disclosed 2026-07-18

Uncontrolled Resource Consumption vulnerability in Apache Traffic Server

ASSESSED — NOISGATE V0.5
Vendor
Reassessed
Verdict:
Do you agree?
01 · The Real Story

The bouncer is counting heads, but the door has already let the crowd in

Apache Traffic Server's HTTP/2 stack treats proxy.config.http2.max_active_streams_in as an *advisory* soft cap. A remote client can open new streams faster than the throttle can react, meaning the proxy accepts far more concurrent streams than the operator configured. Each stream carries state, so the attacker inflates memory until the ATS worker OOMs or the box swaps itself into unresponsiveness — classic CWE-400 uncontrolled resource consumption. Affected: Apache Traffic Server 9.x through 9.2.13 and 10.x through 10.1.2. Fixed in 9.2.14 and 10.1.3, where the limit is now hard-enforced by returning HTTP/2 REFUSED_STREAM once the ceiling is hit.

There is no vendor CVSS baseline published for this CVE, so this is a first assessment rather than a re-rating. In reality this is a network-reachable, unauthenticated DoS with no confidentiality or integrity impact — the textbook CVSS math for that shape lands in the 5.3–7.5 range depending on how strictly you interpret automatability. It is *not* an RCE, it is *not* KEV-listed, EPSS is 0.00225 (bottom decile), and ATS is a niche edge proxy with a small internet-facing footprint compared to nginx/HAProxy. Treat as MEDIUM: real risk to the fleet of operators running ATS as an internet-facing CDN edge, background noise for everyone else.

"Unauth DoS against a public-facing reverse proxy — real, but noisy, WAF-visible, and self-limiting. Patch on the 365-day track, mitigate now if you're internet-facing."
02 · The Attack Path

4 steps from start to impact.

STEP 01

Reach an HTTP/2 listener on ATS

Attacker needs TCP reachability to an ATS instance with HTTP/2 enabled (default on modern ATS reverse-proxy deployments). No authentication is required — HTTP/2 negotiation happens over TLS ALPN before any application-layer auth. Target selection is trivial via Shodan/Censys queries for Server: ATS/ banners.
Conditions required:
  • TCP/443 (or configured HTTPS port) reachable from attacker
  • HTTP/2 (h2 ALPN) enabled on the listener
  • Target is ATS 9.x ≤ 9.2.13 or 10.x ≤ 10.1.2
Where this breaks in practice:
  • Most ATS deployments sit behind a CDN or L4 load balancer that terminates TLS elsewhere
  • Enterprises rarely run ATS externally — dominant users are CDN operators (Yahoo/Verizon/Comcast/LinkedIn) with rate-limiting upstream
Detection/coverage: Shodan/Censys can identify ATS by ALPN + Server header. Internal exposure is discoverable via nmap -sV --script http-server-header.
STEP 02

Open a burst of HTTP/2 streams via a scripted client

Attacker uses a custom HTTP/2 client (e.g., h2load, nghttp2, curl --http2, or a Go golang.org/x/net/http2 script) to rapidly open streams within a single connection, well above the configured max_active_streams_in. Because the cap is advisory, the ATS worker allocates per-stream state before the throttle takes effect. Public PoCs for the sibling HTTP/2 flow-control DoS class (Rapid Reset, CONTINUATION Flood) are directly adaptable.
Conditions required:
  • Ability to speak raw HTTP/2 frames (SETTINGS, HEADERS, DATA)
  • TLS handshake completes — attacker has any valid client (no client-cert required in typical deployments)
Where this breaks in practice:
  • A CDN or WAF in front will pool the connection and absorb the burst
  • Cloudflare/Akamai/Fastly edges are patched against the sibling classes and will throttle upstream
Detection/coverage: Rapid stream-open rate on a single TCP connection is a strong IoC — Suricata/Zeek HTTP/2 parsers flag stream-count anomalies. ATS's own metrics (proxy.process.http2.total_client_streams) spike.
STEP 03

Exhaust worker memory / event loop

As stream state accumulates, the ATS worker's RSS climbs. On a typical 8-16 GB edge cache, a single attacker connection can allocate hundreds of MB in stream metadata; a handful of parallel connections push the worker into OOM-kill or heavy swap. The proxy stops serving legitimate traffic — full DoS of the vhost/tier.
Conditions required:
  • ATS worker has no cgroup memory limit forcing early kill
  • No connection-rate or concurrent-stream limit at the L4/L7 tier in front
Where this breaks in practice:
  • Systemd MemoryMax= or Kubernetes memory limits contain the blast — worker restarts, service degrades but recovers
  • Multi-instance CDN edges route around a downed ATS pop
Detection/coverage: OOM-kill in journalctl, traffic_manager restart events, spike in proxy.process.http2.stream_errors.
STEP 04

Sustain the outage

Attacker rotates source IPs (residential proxy pool, cheap VPS) to defeat single-IP rate limits and keeps the ATS tier flapping. Because HTTP/2 concentrates streams within a connection, the source-IP footprint is small compared to a classic L7 flood — hard for volumetric DDoS scrubbers tuned to request-per-second thresholds.
Conditions required:
  • Modest bot infrastructure (dozens of source IPs)
  • Attack window that fits within DDoS scrubber MTTD
Where this breaks in practice:
  • Any mature DDoS scrubber (Cloudflare Magic Transit, Akamai Prolexic, AWS Shield Advanced) mitigates within minutes
  • Runbook rollback: disable HTTP/2 (proxy.config.http2.enabled 0) — service degrades to HTTP/1.1 but survives
Detection/coverage: Anomaly on stream count per connection, HTTP/2 GOAWAY rate, and RSS growth of the traffic_server process.
03 · Intelligence Metadata

The supporting signals.

In-the-wild exploitationNone observed as of 2026-07-20. No campaigns attributed. Sibling HTTP/2 DoS classes (Rapid Reset CVE-2023-44487, CONTINUATION Flood CVE-2024-27316) have been exploited opportunistically — this bug follows the same shape.
Public PoCNo dedicated PoC published for CVE-2026-59173. However, the class is trivially reproducible with h2load -c 1 -m 10000 https://target/ or a 30-line Go program using x/net/http2. Consider PoC availability effectively immediate.
EPSS0.00225 — bottom decile. Consistent with a niche-product DoS lacking public tooling.
KEV statusNot listed. No CISA action deadline.
CVSSNo vendor/authority CVSS published. noisgate assessment: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H7.5 (High) by pure vector math, but adjusted down to 5.8 (Medium) after exposure/friction analysis.
Affected versionsApache Traffic Server 9.0.0 through 9.2.13 and 10.0.0 through 10.1.2.
Fixed versions9.2.14 and 10.1.3. No distro backports observed yet — check RHEL/Alma/Rocky EPEL, Debian security tracker, and Ubuntu USN once published.
Internet exposureShodan shows roughly ~15k hosts advertising Server: ATS/ banners globally — small compared to nginx (~40M) or HAProxy. Concentrated in CDN/telco ASNs (Yahoo/Verizon Media, Comcast, LinkedIn, Wikimedia).
Disclosure2026-07-18, coordinated via CERT/CC VU#885548 as part of a multi-vendor HTTP/2 stalled-flow-control disclosure.
ReporterOkta Red Team (per CERT/CC coordination) as part of the broader HTTP/2 flow-control DoS research track.
CWECWE-400 — Uncontrolled Resource Consumption.
04 · The Call

noisgate verdict.

Final Verdict
= UNCHANGED to MEDIUM (5.8/10)

The single most decisive factor is impact ceiling: availability-only DoS with no confidentiality or integrity impact and no memory-corruption path to RCE. Apache Traffic Server is a niche reverse proxy (~15k global exposure), the attack is loud enough for any L7 DDoS scrubber to mitigate, and the deployment role — an edge cache in front of stateless content — is inherently resilient to single-node failures via existing DDoS runbooks.

HIGH Impact class (DoS only, no RCE path)
HIGH Patch availability and fix correctness
MEDIUM Real-world exploitability given sibling-class PoCs
MEDIUM Installed-base exposure estimate

Why this verdict

  • Impact is availability-only. No memory corruption, no auth bypass, no data exposure. The worst outcome is a worker restart or a temporary tier outage — recoverable by design.
  • Deployment-role blast radius is bounded. ATS's canonical role is a stateless HTTP/HTTPS caching reverse proxy. Even at CDN scale, edge tiers are engineered for node loss; the chain does not pivot into origin, identity, or data.
  • Role multiplier: Low-value role (dev/test ATS) — outcome: process crash, negligible. Typical role (internal reverse proxy) — outcome: tier degradation, contained. High-value role (public CDN edge for a large property) — outcome: partial regional outage, mitigated by DDoS scrubber + h2-disable runbook. No role produces domain/fleet/data compromise. Floor stays at MEDIUM.
  • Exposure population is narrow. ~15k internet-facing ATS instances globally per Shodan — <0.05% of the reverse-proxy market. Most enterprise buyers do not run ATS.
  • No KEV, EPSS 0.00225. No exploitation evidence, no public dedicated PoC, and no campaign attribution.
  • Friction is meaningful. Any upstream DDoS scrubber, per-connection stream-cap at an L7 WAF, or systemd/cgroup memory ceiling breaks the chain.

Why not higher?

HIGH would require either a role multiplier (ATS running in a chain-ending high-value position — it doesn't) or a confidentiality/integrity impact (there is none). The bug is a stream-accounting race, not a parser bug or a memory-safety issue, so there is no plausible pivot to RCE. Sibling DoS-class CVEs like Rapid Reset also assessed at HIGH only because of *market* saturation across nginx/Envoy/every mainstream HTTP/2 stack — ATS's footprint doesn't justify that treatment.

Why not lower?

LOW is wrong because the vulnerability is unauthenticated and network-reachable, and for CDN operators running ATS as their edge tier, a coordinated attacker can cause user-visible regional outages. Anyone with ATS on the perimeter has a real, exploitable-tomorrow problem — that's not backlog hygiene, that's a MEDIUM with a mitigation path.

05 · Compensating Control

What to do — in priority order.

  1. Front ATS with a stream-cap-enforcing L7 (WAF/CDN/scrubber) — Cloudflare, Akamai, Fastly, AWS Shield Advanced, and Imperva all enforce per-connection HTTP/2 stream limits at the edge, well below what ATS accepts. If you already have one of these in front, you are largely covered. Applies to internet-facing ATS only — no mitigation SLA for MEDIUM, deploy as part of standing DDoS posture.
  2. Cap ATS worker memory with cgroups / systemd — Set MemoryMax= (systemd) or Kubernetes resources.limits.memory at 60-70% of host RAM so an OOM-kill happens fast and traffic_manager restarts the worker cleanly, converting a sustained outage into a brief blip. Configuration change, zero downtime.
  3. Disable HTTP/2 if you don't need it — Set proxy.config.http2.enabled 0 and reload. ATS falls back to HTTP/1.1 — some latency loss on modern clients but full mitigation of this CVE and any future HTTP/2 flow-control bugs. Reversible in one config toggle.
  4. Set proxy.config.http2.max_active_streams_in to a conservative value now — Even though the limit is advisory pre-patch, lowering it (e.g., 100) reduces the ceiling of allocatable stream state per connection, raising attacker cost. Not a fix, but blunts single-connection amplification.
  5. Schedule the vendor patch on the 365-day remediation track — Upgrade to ATS 9.2.14 or 10.1.3 during your next normal maintenance window. Per noisgate remediation SLA for MEDIUM: within 365 days.
What doesn't work
  • Volumetric DDoS scrubbing tuned to bandwidth — this attack is low-bandwidth by design (a few Mbps can OOM a worker). Scrubbers need HTTP/2-aware stream-count rules.
  • IP allowlisting — ATS's whole job is serving arbitrary internet clients on 443. Allowlisting defeats the product.
  • TLS mutual auth (mTLS) — attacker needs no auth; TLS completes before HTTP/2 stream logic runs. Adds cost but not a blocker unless mTLS is *required* by the listener.
  • Web application firewall signature updates — WAF rulesets target application payloads. This is an HTTP/2 framing-layer bug; standard OWASP rules do not fire on it.
06 · Verification

Crowdsourced verification payload.

Run on the target ATS host as any user that can execute traffic_server -V (typically the ats service account or root). Example: sudo ./check-cve-2026-59173.sh. Emits VULNERABLE / PATCHED / UNKNOWN and exits with 1/0/2 respectively.

noisgate-verify.sh
BASHREAD-ONLYSAFE
#!/usr/bin/env bash
# noisgate check for CVE-2026-59173 — Apache Traffic Server HTTP/2 stream-cap DoS
# Vulnerable: 9.0.0 - 9.2.13, 10.0.0 - 10.1.2
# Fixed:      9.2.14+, 10.1.3+
set -u

BIN="$(command -v traffic_server || true)"
if [[ -z "$BIN" ]]; then
  for cand in /usr/local/bin/traffic_server /opt/ats/bin/traffic_server /usr/bin/traffic_server; do
    [[ -x "$cand" ]] && BIN="$cand" && break
  done
fi

if [[ -z "$BIN" ]]; then
  echo "UNKNOWN: traffic_server binary not found in PATH or common locations"
  exit 2
fi

VER_RAW="$($BIN -V 2>&1 | head -n1)"
# Expect: 'Traffic Server 10.1.2 - ...' or 'traffic_server: Apache Traffic Server 9.2.13'
VER="$(echo "$VER_RAW" | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -n1)"

if [[ -z "$VER" ]]; then
  echo "UNKNOWN: could not parse version from: $VER_RAW"
  exit 2
fi

IFS='.' read -r MAJ MIN PATCH <<< "$VER"

vuln=0
case "$MAJ" in
  9)
    if (( MIN < 2 )) || { (( MIN == 2 )) && (( PATCH < 14 )); }; then vuln=1; fi
    ;;
  10)
    if (( MIN < 1 )) || { (( MIN == 1 )) && (( PATCH < 3 )); }; then vuln=1; fi
    ;;
  *)
    echo "UNKNOWN: unexpected major version $MAJ (raw: $VER_RAW)"
    exit 2
    ;;
esac

# Bonus: check whether HTTP/2 is enabled and stream cap is set
H2_STATE="unknown"
STREAM_CAP="unset"
for cfg in /etc/trafficserver/records.config /opt/ats/etc/trafficserver/records.config /usr/local/etc/trafficserver/records.config; do
  if [[ -r "$cfg" ]]; then
    grep -q '^CONFIG proxy.config.http2.enabled INT 1' "$cfg" && H2_STATE="enabled"
    grep -q '^CONFIG proxy.config.http2.enabled INT 0' "$cfg" && H2_STATE="disabled"
    STREAM_CAP="$(awk '/proxy.config.http2.max_active_streams_in/ {print $NF}' "$cfg" | tail -n1)"
    break
  fi
done

if (( vuln == 1 )); then
  echo "VULNERABLE: ATS $VER  (http2=$H2_STATE, max_active_streams_in=$STREAM_CAP)"
  echo "  Fix: upgrade to 9.2.14 or 10.1.3"
  exit 1
fi

echo "PATCHED: ATS $VER  (http2=$H2_STATE, max_active_streams_in=$STREAM_CAP)"
exit 0
07 · Bottom Line

If you remember one thing.

TL;DR
For internet-facing ATS: cap HTTP/2 stream counts at your upstream WAF/CDN and set proxy.config.http2.max_active_streams_in conservatively this week as standing DDoS hygiene — MEDIUM has no formal noisgate mitigation SLA, so treat this as opportunistic hardening, not a fire drill. Then schedule the actual upgrade to ATS 9.2.14 or 10.1.3 in your next maintenance window, well inside the noisgate remediation SLA of ≤ 365 days for MEDIUM. For internal-only ATS deployments (LAN caching, dev tiers), go straight to the 365-day remediation window — no interim mitigation required. Escalate only if you see rapid stream-open bursts against ATS listeners in traffic telemetry, in which case flip HTTP/2 off (proxy.config.http2.enabled 0) and reload while you patch.

Sources

  1. CERT/CC VU#885548 — HTTP/2 stalled flow-control DoS
  2. Apache Traffic Server — CVE list (cvedetails)
  3. Apache Traffic Server versions (cvedetails)
  4. Apache Software Foundation CVE feed (OpenCVE)
  5. Apache Traffic Server release notes (project)
  6. SecurityOnline — Apache Traffic Server latest release advisory
  7. SQ Magazine — Apache Traffic Server DoS coverage
  8. cve.report — Apache Traffic Server tracker
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.