Like leaving dirty dishes for the dishwasher that only runs when the kitchen feels like it
CVE-2025-61795 is a denial-of-service flaw in Apache Tomcat's multipart upload handler. When an error occurs during multipart processing — including exceeding upload size limits — temporary file copies written to disk are not cleaned up immediately. Instead, they rely on Java's garbage collector to eventually delete them. Under the right combination of JVM settings, application memory pressure, and sustained upload load, an attacker can fill the temp directory faster than GC clears it, leading to disk exhaustion and service disruption. Affected versions span 9.0.0-M1 through 9.0.109 (also 10.1.0-M1–10.1.46, 11.0.0-M1–11.0.11, and EOL 8.5.x). Fixed in 9.0.110.
The vendor severity picture is a mess. Apache themselves rate this Low. The GHSA/CVSS 4.0 score is 2.3. Yet Tenable's plugin reports CVSS 3.0 Base 7.5 (High) while simultaneously assigning a VPR of 3.0 (Low). The reality aligns with Apache and the VPR: this is a conditional DoS with no confidentiality or integrity impact, requiring sustained malicious uploads against a server whose JVM happens to be slow on garbage collection. Tenable's CVSS 3.0 score of 7.5 is inflated because the v3.1 formula overweights network-reachable availability impacts without accounting for the preconditions that make exploitation unreliable.
3 steps from start to impact.
Identify a multipart upload endpoint
multipart/form-data POST requests. This is common in web applications with file upload features, form submissions, or API endpoints that accept binary payloads. No authentication is strictly required by the vulnerability itself, but the endpoint must actually process multipart data.- Network access to a Tomcat HTTP/HTTPS port
- At least one endpoint that accepts multipart uploads
- Many Tomcat instances are behind reverse proxies or WAFs that enforce upload size limits before Tomcat ever sees the request
- Upload endpoints are often authenticated, reducing the unauthenticated attack surface
Send sustained error-triggering multipart requests
maxFileSize or maxRequestSize limits. Each failed upload leaves temporary file fragments on disk that won't be cleaned until GC runs. The attacker needs to sustain this traffic over time to outpace garbage collection.- Ability to send sustained HTTP traffic to the target
- Multipart requests must actually trigger the error path (exceed limits, malformed parts)
- Rate limiting, WAF rules, or connection limits will throttle sustained upload floods
- The JVM must be under memory pressure such that GC is delayed — a well-tuned JVM with adequate heap may never trigger the condition
- Default Tomcat
maxSwallowSize(2MB) limits how much data per request is written before the connection is aborted
java.io.tmpdir) will show growth.Temp directory fills, Tomcat becomes unavailable
- Temp directory on a partition with limited free space
- GC cycle slower than the rate of temp file creation
- Dedicated temp partitions or tmpfs with size caps prevent full-disk impact on the OS
- Container deployments often have ephemeral storage limits that contain the blast
- Restarting Tomcat or triggering a manual GC clears the accumulated files
The supporting signals.
| In-the-Wild Exploitation | No known exploitation. Not listed in CISA KEV. No threat actor campaigns or incident reports reference this CVE. |
|---|---|
| Proof-of-Concept | A basic Python script demonstrating sustained multipart uploads exists in security research contexts, but no weaponized exploit tool has been published. The "exploit" is just sending many multipart POSTs — trivial to construct but unreliable to land. |
| EPSS Score | 1.165% (66th percentile) — below the threshold where EPSS suggests meaningful exploitation probability. |
| KEV Status | Not listed in CISA Known Exploited Vulnerabilities catalog as of 2026-09-17. |
| CVSS Vector | CVSS 4.0: CVSS:4.0/AV:N/AC:L/AT:P/PR:L/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N/E:U → 2.3 Low. Tenable uses CVSS 3.0 base 7.5 but their own VPR is 3.0 Low. Apache rates it Low. |
| Affected Versions | 9.0.0-M1 through 9.0.109; also 10.1.0-M1–10.1.46, 11.0.0-M1–11.0.11, and EOL 8.5.0–8.5.100 |
| Fixed Versions | 9.0.110, 10.1.47, 11.0.12. Distro backports: check RHEL, Debian, Ubuntu advisories for their Tomcat 9 packages. |
| Exposure Data | Shodan shows ~100,000 internet-facing Tomcat instances globally. However, exploitability requires sustained traffic to a multipart endpoint under specific JVM conditions — raw exposure count overstates actual risk. |
| Disclosure Timeline | Reported to Apache: 2025-09-07. Fix released: 2025-10-06 (9.0.110). Public disclosure: 2025-10-27. |
| Reporter | Not publicly credited in the Apache advisory. |
noisgate verdict.
The single most decisive factor is that this is a conditional denial-of-service with no confidentiality or integrity impact, requiring a specific combination of JVM garbage-collection latency, sustained malicious upload traffic, and limited temp-disk capacity — conditions that rarely align in production. Apache themselves rate this Low, CVSS 4.0 scores it 2.3, and Tenable's own VPR (3.0) contradicts their CVSS 3.0 base score of 7.5.
Why this verdict
- DoS-only impact ceiling: The vulnerability cannot lead to code execution, data exfiltration, or privilege escalation under any configuration. The absolute worst outcome is temporary service unavailability on one Tomcat instance, resolved by restart or disk cleanup.
- Multi-condition exploitation: Landing this requires (a) sustained network access to a multipart endpoint, (b) a JVM under enough memory pressure that GC is delayed, and (c) a temp directory without size caps. Each condition independently narrows the exploitable population.
- Role multiplier: Tomcat serves as an application tier in most deployments (typical role). In high-value roles — e.g., Tomcat fronting an identity provider or running inside a CI/CD pipeline — a successful DoS causes *availability loss*, not compromise. DoS on a Tomcat instance does not yield domain takeover, fleet compromise, data egress, or supply-chain pivot. The blast radius is single-host availability, not identity-scale or fleet-scale. The HIGH floor is not triggered because no realistic deployment-role outcome reaches compromise-level impact.
- Vendor agrees it's Low: Apache's own security team — who understand Tomcat internals best — explicitly rate this Low. The CVSS 4.0 score (2.3) and Tenable VPR (3.0) both corroborate this. The CVSS 3.0 score of 7.5 is a formula artifact, not a real-world risk signal.
- No threat intelligence signal: No KEV listing, no known campaigns, no weaponized tooling, EPSS at 1.165% (66th percentile). There is no evidence anyone is bothering to exploit this.
Why not higher?
This is DoS-only with zero confidentiality or integrity impact. The exploitation chain requires multiple simultaneous conditions (sustained traffic, JVM GC lag, limited disk) that rarely co-occur in production. There is no exploitation in the wild, no KEV listing, and the vendor rates it Low. Upgrading to MEDIUM would require either active exploitation evidence or a more reliable attack path.
Why not lower?
Despite the narrow conditions, the vulnerability is real and the attack surface (network-reachable multipart endpoints) does exist on internet-facing Tomcat instances. An IGNORE verdict would be inappropriate because a determined attacker with sustained access could plausibly trigger disk exhaustion on a misconfigured host. The EPSS score, while low, is non-trivial at the 66th percentile.
What to do — in priority order.
- Set explicit maxFileSize and maxRequestSize in your Tomcat Connector or application's MultipartConfig — Limiting upload sizes at the Tomcat level ensures the error path is triggered early with minimal disk write. This is your primary compensating control. Deploy within your standard change window — no mitigation SLA applies for a LOW verdict.
- Mount Tomcat's temp directory on a dedicated partition or tmpfs with a size cap — Isolating
java.io.tmpdirto a bounded filesystem prevents temp file accumulation from affecting the OS or other services. Even if the vuln is triggered, the blast radius is contained to that mount point. - Configure WAF or reverse proxy upload size limits — Enforce
client_max_body_size(nginx) or equivalent at the edge so oversized multipart requests never reach Tomcat. This eliminates the primary attack vector. - Monitor disk usage on the Tomcat temp directory — Set alerts at 80% capacity on the temp partition. This provides early warning of any temp file accumulation, whether from this CVE or normal operational issues.
- Tuning JVM GC alone — while faster GC reduces the window, it doesn't eliminate it. Under sustained attack, even an aggressive GC schedule can fall behind. The fix is upgrading Tomcat, not tuning GC.
- Network-level rate limiting on all POST requests — overly broad rate limiting will impact legitimate file uploads. You need endpoint-specific or content-type-specific rules to be effective without breaking functionality.
Crowdsourced verification payload.
Run this on each Tomcat host as any user with read access to the Tomcat installation directory. Example: bash check_cve_2025_61795.sh /opt/tomcat or bash check_cve_2025_61795.sh /usr/share/tomcat9. No root required.
#!/bin/bash
# CVE-2025-61795 - Apache Tomcat multipart upload temp file DoS
# Checks if installed Tomcat 9.x version is vulnerable (< 9.0.110)
# Usage: bash check_cve_2025_61795.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>"
echo "UNKNOWN - no CATALINA_HOME provided"
exit 2
fi
# Try version.sh first, fall back to catalina.sh or MANIFEST
VERSION=""
if [ -x "$CATALINA_HOME/bin/version.sh" ]; then
VERSION=$($CATALINA_HOME/bin/version.sh 2>/dev/null | grep 'Server number' | sed 's/.*: *//' | tr -d '[:space:]')
fi
if [ -z "$VERSION" ]; then
# Try reading from catalina.jar MANIFEST
JAR=$(find "$CATALINA_HOME" -name 'catalina.jar' -print -quit 2>/dev/null)
if [ -n "$JAR" ]; then
VERSION=$(unzip -p "$JAR" META-INF/MANIFEST.MF 2>/dev/null | grep 'Implementation-Version' | sed 's/.*: *//' | tr -d '[:space:]')
fi
fi
if [ -z "$VERSION" ]; then
echo "UNKNOWN - could not determine Tomcat version at $CATALINA_HOME"
exit 2
fi
echo "Detected Tomcat version: $VERSION"
# Check if version is 9.x
MAJOR=$(echo "$VERSION" | cut -d. -f1)
if [ "$MAJOR" != "9" ]; then
echo "UNKNOWN - this script checks Tomcat 9.x only (found $MAJOR.x)"
echo "For Tomcat 10.x, fixed version is 10.1.47; for 11.x, fixed is 11.0.12"
exit 2
fi
# Extract minor and patch: 9.0.XXX
MINOR=$(echo "$VERSION" | cut -d. -f2)
PATCH=$(echo "$VERSION" | cut -d. -f3 | sed 's/[^0-9].*//')
if [ "$MINOR" -eq 0 ] && [ "$PATCH" -ge 110 ]; then
echo "PATCHED - Tomcat $VERSION is >= 9.0.110"
exit 0
else
echo "VULNERABLE - Tomcat $VERSION is < 9.0.110 (CVE-2025-61795)"
exit 1
fiIf you remember one thing.
Sources
What defenders are saying.
Crowdsourced verification outputs.
Results submitted by users who ran the verification payload against their environment.