← Back to Feed CACHED · 2026-09-17 06:39:53 · CACHE_KEY tenable:201848
tenable:201848 · CWE-400 · Disclosed 2024-07-03

Apache Tomcat 9.0.0.M1 < 9.0.90

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

Like leaving a revolving door spinning forever because the counter says someone is still inside

CVE-2024-34750 is a denial-of-service flaw in Apache Tomcat's HTTP/2 stream handling. When an attacker sends HEADERS frames with payloads sized to trigger a StreamException without killing the connection, the activeRemoteStreamCount variable decrements without a matching increment — going negative. Tomcat then interprets any non-zero count as "streams still active" and sets the connection timeout to infinite. Repeat 8,192 times (Tomcat's default maxConnections) and the server stops accepting new clients. Affected versions span Tomcat 9.0.0-M1 through 9.0.89, 10.1.0-M1 through 10.1.24, 11.0.0-M1 through 11.0.0-M20, and EOL 8.5.0 through 8.5.100. The fix landed in 9.0.90, 10.1.25, and 11.0.0-M21.

The NVD rates this 7.5 HIGH based on the unauthenticated, network-reachable, low-complexity vector. That score is technically accurate *if* Tomcat's HTTP/2 connector faces the internet directly. In practice, the vast majority of enterprise Tomcat deployments sit behind nginx, Apache httpd, HAProxy, or a cloud ALB that terminates HTTP/2 upstream — Tomcat never sees the malformed frames. Tenable's own VPR already reflects this reality at 5.7 MEDIUM. The vendor severity overstates real-world risk for most shops.

"DoS-only bug in Tomcat HTTP/2 that most reverse-proxy architectures never expose"
02 · The Attack Path

4 steps from start to impact.

STEP 01

Identify HTTP/2-enabled Tomcat endpoint

The attacker locates a Tomcat instance that exposes an HTTP/2 connector directly to the network. This can be confirmed via ALPN negotiation during the TLS handshake or by observing h2 in the protocol upgrade response. If a reverse proxy terminates HTTP/2 upstream and forwards HTTP/1.1 to Tomcat, this chain dies here.
Conditions required:
  • Tomcat HTTP/2 connector enabled and reachable
  • No upstream proxy terminating HTTP/2 before Tomcat
Where this breaks in practice:
  • Most production Tomcat deployments sit behind a reverse proxy (nginx, Apache httpd, HAProxy, cloud ALB) that terminates HTTP/2
  • Default Tomcat server.xml ships with HTTP/1.1 NIO connector, not HTTP/2
Detection/coverage: Nessus plugin 201848 detects the vulnerable version via banner. GreyNoise and Shodan can identify exposed Tomcat instances with HTTP/2 ALPN.
STEP 02

Craft oversized HEADERS frames in the exploit window

The attacker constructs HTTP/2 HEADERS frames where the header block size exceeds maxHeaderSize (triggering isHeaderSizeExceeded()) but stays below maxHeaderCount × maxHeaderSize (avoiding isHeaderSwallowSizeExceeded()). This narrow window causes a StreamException that decrements activeRemoteStreamCount without it ever having been incremented, driving the counter to -1.
Conditions required:
  • Knowledge of Tomcat's header size thresholds (defaults are well-documented)
  • Ability to send raw HTTP/2 frames (any HTTP/2 client library suffices)
Where this breaks in practice:
  • WAF or HTTP/2-aware load balancer may reject oversized headers before they reach Tomcat
  • Rate limiting on new connections slows exhaustion
Detection/coverage: HTTP/2 connection-level anomalies (high HEADERS-to-DATA ratio, rapid stream resets) visible to protocol-aware IDS. No specific Snort/Suricata SID widely published.
STEP 03

Exhaust connection pool

With each malformed connection stuck open indefinitely (timeout set to infinite due to non-zero activeRemoteStreamCount), the attacker repeats the process ~8,192 times to hit Tomcat's default maxConnections. At this point, the server refuses all new connections. Memory pressure may also build as stuck connections accumulate socket buffers.
Conditions required:
  • Sustained network access to send ~8,192 connections
  • No connection-rate limiting or IP-based throttling
Where this breaks in practice:
  • Cloud WAFs and CDNs enforce per-IP connection limits well below 8,192
  • Operational monitoring (connection count alerts) would flag the spike before full exhaustion
  • Tomcat restart clears all stuck connections immediately
Detection/coverage: Connection-count monitoring in APM tools (Datadog, New Relic, Dynatrace). JMX currentThreadsBusy and connectionCount metrics on the HTTP/2 connector.
STEP 04

Denial of service achieved

The Tomcat instance becomes unreachable to legitimate users. Impact is limited to availability of applications hosted on that specific Tomcat instance. There is no path from this vulnerability to code execution, data exfiltration, or lateral movement. A service restart fully recovers the system.
Conditions required:
  • All previous steps completed successfully
Where this breaks in practice:
  • Multi-instance deployments behind a load balancer survive — traffic routes to healthy nodes
  • Auto-scaling groups in cloud environments spin up replacement instances
  • Restart is immediate recovery with no data loss
Detection/coverage: Standard uptime monitoring and health checks (HTTP 503/timeout alerts).
03 · Intelligence Metadata

The supporting signals.

In-the-Wild ExploitationNone observed. Not listed in CISA KEV. No campaigns or threat actor usage reported by Mandiant, CrowdStrike, or Recorded Future as of September 2026.
Proof of ConceptDetailed analysis published by devme4f explaining the stream-counting bug and exploitation window. No weaponized one-click tool on GitHub. HackerOne report #2586226 also documents the issue.
EPSS Score0.046 (4.6%) — 91st percentile. Moderate probability of exploitation, but still well below typical thresholds for urgent action.
CISA KEV StatusNot listed. No due date.
CVSS v3.1 VectorCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H — Network-reachable, no auth required, availability-only impact. The C:N/I:N is the key limiter: no confidentiality or integrity damage.
Affected VersionsTomcat 9.0.0-M1 – 9.0.89, 10.1.0-M1 – 10.1.24, 11.0.0-M1 – 11.0.0-M20, EOL 8.5.0 – 8.5.100
Fixed Versions9.0.90, 10.1.25, 11.0.0-M21. RHEL/CentOS backports available via tomcat package updates. Debian/Ubuntu track upstream.
Exposure DataShodan indexes ~378,000 internet-facing Tomcat instances globally, but the fraction with HTTP/2 connectors directly exposed (not behind a reverse proxy) is estimated at <5% of that population.
Disclosure Date2024-07-03 (Apache advisory). CVE reserved 2024-05-07. Fix committed 2024-06-18.
CreditReported to the Apache Tomcat security team. Specific researcher not publicly credited in the ASF advisory.
04 · The Call

noisgate verdict.

Final Verdict
= UNCHANGED to MEDIUM (5.5/10)

The single most decisive factor is availability-only impact behind ubiquitous reverse-proxy architectures — the vuln is DoS with no path to code execution or data breach, and the prerequisite HTTP/2 connector exposure is absent in the majority of enterprise Tomcat deployments where upstream proxies terminate HTTP/2. This limits both the blast radius and the attacker's return on investment to a narrow population.

HIGH Vulnerability mechanics and affected versions
HIGH No active exploitation or KEV listing
MEDIUM Fraction of deployments with HTTP/2 directly on Tomcat (estimated <5% of internet-facing)

Why this verdict

  • DoS-only impact ceiling: CVSS vector confirms C:N/I:N/A:H — no confidentiality or integrity compromise. The worst outcome is temporary service unavailability, fully recoverable by restart. This caps the realistic severity below any RCE or data-breach vuln.
  • HTTP/2 prerequisite narrows exposure: Tomcat's default server.xml ships with an HTTP/1.1 NIO connector. HTTP/2 requires explicit opt-in (UpgradeProtocol class in connector config). Enterprises that enable it typically terminate HTTP/2 at nginx, Apache httpd, or a cloud ALB — Tomcat speaks HTTP/1.1 behind the proxy. Estimated <5% of production Tomcat instances expose HTTP/2 connectors directly.
  • No exploitation pressure: Zero KEV listing, zero known campaigns, zero weaponized tooling. EPSS at 4.6% is moderate but reflects theoretical reachability, not observed attacker interest. After 2+ years with a published PoC analysis, nobody is using this.
  • Role multiplier: Tomcat occupies mid-tier application server roles. In high-value contexts (e.g., Tomcat fronting a critical API gateway without a proxy), the DoS impact could disrupt business operations — but the blast radius remains *availability of one service*, not domain takeover, fleet compromise, or supply-chain pivot. Even in the worst plausible high-value role, the outcome (temporary DoS of one app tier) does not meet the HIGH floor threshold of fleet-scale or identity-scale compromise.

Why not higher?

Upgrading to HIGH would require either active exploitation evidence, a path to code execution, or a blast radius beyond single-instance availability impact. None of these exist. The NVD 7.5 HIGH score assumes direct network exposure of the HTTP/2 connector, which is a minority configuration in enterprise Tomcat deployments. The DoS-only impact with immediate restart recovery does not warrant HIGH urgency.

Why not lower?

Dropping to LOW or IGNORE would understate the risk for the minority of deployments that *do* expose Tomcat HTTP/2 directly — in those cases, an unauthenticated remote attacker can fully exhaust the connection pool with no special tooling. The EPSS 91st percentile and the existence of a detailed public PoC analysis mean this is not purely theoretical. MEDIUM correctly captures the 'patch in normal cycle' priority.

05 · Compensating Control

What to do — in priority order.

  1. Terminate HTTP/2 at the reverse proxy, not at Tomcat — Configure nginx, Apache httpd, HAProxy, or your cloud ALB to handle HTTP/2 and forward HTTP/1.1 to Tomcat. This eliminates the attack surface entirely. Most architectures already do this — verify yours does. No deadline pressure per noisgate mitigation SLA (MEDIUM has no mitigation SLA).
  2. Set maxConnections and connection-rate limits on the Tomcat connector — Reduce maxConnections from the default 8,192 to the minimum your app needs and add acceptCount limits. This raises the bar for exhaustion. Pair with per-IP connection limits at the firewall or load balancer.
  3. Enable JMX connection-count alerting — Monitor Connector.connectionCount and ThreadPool.currentThreadsBusy via JMX or your APM. Alert when connection count exceeds 80% of maxConnections. This gives early warning before full DoS.
  4. Deploy WAF rules for HTTP/2 header anomalies — If Tomcat must handle HTTP/2 directly, configure your WAF to reject HTTP/2 HEADERS frames with header block sizes exceeding a reasonable threshold (e.g., 16 KB). This blocks the specific exploit window.
What doesn't work
  • Disabling HTTP/2 entirely on Tomcat — works as a control but may break applications that depend on server-push or HTTP/2 multiplexing features directly from Tomcat. Verify application requirements first.
  • IP-based rate limiting alone — the attacker needs only ~8,192 connections total, which can come from a small botnet or a handful of IPs. Per-IP limits help but don't eliminate the risk.
  • Tomcat connectionTimeout tuning — the bug overrides the configured timeout by setting it to infinite when activeRemoteStreamCount is non-zero. Adjusting the config value has no effect on already-poisoned connections.
06 · Verification

Crowdsourced verification payload.

Run this on each Tomcat host (Linux/macOS) as any user with read access to the Tomcat installation directory. Example: bash check_cve_2024_34750.sh /opt/tomcat — no root required.

noisgate-verify.sh
BASHREAD-ONLYSAFE
#!/usr/bin/env bash
# check_cve_2024_34750.sh — Detect Apache Tomcat CVE-2024-34750
# Usage: bash check_cve_2024_34750.sh <CATALINA_HOME>
# Exit codes: 0=PATCHED, 1=VULNERABLE, 2=UNKNOWN

set -euo pipefail

CATALINA_HOME="${1:-}"
if [ -z "$CATALINA_HOME" ]; then
  echo "Usage: $0 <CATALINA_HOME>"
  exit 2
fi

# Try to get version from catalina.sh or version.sh
VERSION_SH="$CATALINA_HOME/bin/version.sh"
SERVER_INFO="$CATALINA_HOME/lib/catalina.jar"

get_version() {
  if [ -x "$VERSION_SH" ]; then
    VERSION=$( "$VERSION_SH" 2>/dev/null | grep 'Server number' | awk -F: '{print $2}' | tr -d ' ' )
    if [ -n "$VERSION" ]; then echo "$VERSION"; return; fi
  fi
  # Fallback: extract from MANIFEST in catalina.jar
  if [ -f "$SERVER_INFO" ]; then
    VERSION=$( unzip -p "$SERVER_INFO" META-INF/MANIFEST.MF 2>/dev/null | grep 'Implementation-Version' | awk -F: '{print $2}' | tr -d ' \r' )
    if [ -n "$VERSION" ]; then echo "$VERSION"; return; fi
  fi
  echo ""
}

VERSION=$(get_version)
if [ -z "$VERSION" ]; then
  echo "UNKNOWN — could not determine Tomcat version at $CATALINA_HOME"
  exit 2
fi

echo "Detected Tomcat version: $VERSION"

# Parse major.minor.patch
IFS='.' read -r MAJOR MINOR PATCH <<< "$VERSION"

# Check affected ranges
# 9.0.0-M1 through 9.0.89 -> fixed in 9.0.90
# 10.1.0-M1 through 10.1.24 -> fixed in 10.1.25
# 11.0.0-M1 through 11.0.0-M20 -> fixed in 11.0.0-M21
# 8.5.0 through 8.5.100 (EOL, no fix)

if [ "$MAJOR" -eq 9 ] && [ "$MINOR" -eq 0 ]; then
  if [ "$PATCH" -lt 90 ]; then
    echo "VULNERABLE — Tomcat $VERSION is affected by CVE-2024-34750 (fixed in 9.0.90)"
    exit 1
  else
    echo "PATCHED — Tomcat $VERSION is >= 9.0.90"
    exit 0
  fi
elif [ "$MAJOR" -eq 10 ] && [ "$MINOR" -eq 1 ]; then
  if [ "$PATCH" -lt 25 ]; then
    echo "VULNERABLE — Tomcat $VERSION is affected by CVE-2024-34750 (fixed in 10.1.25)"
    exit 1
  else
    echo "PATCHED — Tomcat $VERSION is >= 10.1.25"
    exit 0
  fi
elif [ "$MAJOR" -eq 11 ] && [ "$MINOR" -eq 0 ]; then
  # M-releases parse as 0.0.x; for GA releases:
  if [ "$PATCH" -lt 1 ]; then
    echo "VULNERABLE — Tomcat $VERSION (11.0.0 milestone) is likely affected. Verify >= 11.0.0-M21."
    exit 1
  else
    echo "PATCHED — Tomcat $VERSION is >= 11.0.1"
    exit 0
  fi
elif [ "$MAJOR" -eq 8 ] && [ "$MINOR" -eq 5 ]; then
  echo "VULNERABLE — Tomcat $VERSION (8.5.x EOL) is affected. No official fix; upgrade to 9.0.90+."
  exit 1
else
  echo "UNKNOWN — Tomcat $VERSION is outside known affected ranges for CVE-2024-34750"
  exit 2
fi
07 · Bottom Line

If you remember one thing.

TL;DR
This is a DoS-only vulnerability in Tomcat's HTTP/2 stream handling with no path to code execution or data breach. Most enterprise Tomcat deployments are already protected by reverse proxies that terminate HTTP/2 upstream. Monday morning: verify that your Tomcat instances do *not* expose HTTP/2 connectors directly to untrusted networks — if they don't, this is a routine patching item. Per the noisgate remediation SLA for MEDIUM, apply the vendor patch (upgrade to Tomcat 9.0.90 / 10.1.25 / 11.0.0-M21) within 365 days. There is no noisgate mitigation SLA for MEDIUM — go straight to the remediation window. If you discover any Tomcat instances serving HTTP/2 directly to the internet without a proxy, prioritize those for patching in your next maintenance window and add a reverse proxy in front of them immediately. For EOL 8.5.x instances, begin migration planning to a supported branch.

Sources

  1. Tenable Plugin 201848
  2. Apache Tomcat 9 Security Advisories
  3. NVD — CVE-2024-34750
  4. devme4f — Analyzing CVE-2024-34750 Tomcat DoS
  5. Red Hat CVE-2024-34750
  6. GitHub Advisory GHSA-wm9w-rjj3-j356
  7. FIRST EPSS API — CVE-2024-34750
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.