This is a fire alarm wired only to rooms that actually have an upload door
Tenable plugin 171657 maps to CVE-2023-24998 in Tomcat's bundled FileUpload code. In affected Apache Tomcat 9.0.0-M1 through 9.0.70, an attacker can send a multipart request with an excessive number of parts and drive resource consumption into a denial of service condition. The issue is network-reachable in theory, but in practice it only matters where a deployed application actually exposes a Tomcat-backed multipart upload workflow.
The vendor's HIGH label reflects the raw CVSS math, not the deployment reality. For most enterprises this lands lower because exploitation usually needs a reachable upload endpoint, often one that is authenticated or fronted by a proxy with body limits, and the impact is availability only rather than code execution or data loss. If you run customer-facing upload services on old Tomcat, keep it on the radar; if Tomcat is just an internal app container with no public upload surface, this is patchable hygiene rather than an incident driver.
4 steps from start to impact.
Find a Tomcat app that actually accepts multipart uploads
ffuf, browser dev tools, or Burp Suite. A bare Tomcat banner is not enough; the vulnerable code path is only exercised when the app accepts file or form-part uploads.- Tomcat version is
9.0.0-M1to9.0.70 - A deployed webapp exposes a multipart/form-data endpoint
- The endpoint is reachable from the attacker's network position
- Many Tomcat instances are back-end app servers with no direct internet exposure
- Many applications never expose multipart upload at all
- Authenticated upload flows reduce reachable population to post-login attackers
Send excessive multipart parts with a simple HTTP client
curl, Burp Repeater/Intruder, or a custom Python script, the attacker submits a crafted multipart request or series of requests containing a very large number of parts. Tomcat processes the parts without an effective built-in cap in these versions, consuming CPU, heap, temp storage, descriptors, and worker capacity.- The endpoint accepts multipart/form-data
- Upstream reverse proxies and WAFs do not block or cap the request pattern
- Proxy request-body limits and rate limits often stop the request before Tomcat sees it
- CDN/WAF/NGFW policies may throttle abnormal upload behavior
- Applications that validate auth before parsing uploads narrow exposure further
POST requests to upload endpoints. Generic vulnerability scanners usually do not exercise this safely.Exhaust request-processing resources
- The crafted requests must reach the vulnerable parser
- The service lacks sufficient rate limiting, circuit breaking, or autoscaling headroom
- Clustered deployments may absorb single-node failures
- Kubernetes or service managers often auto-restart the process
- Monitoring usually catches the resource spike quickly
Cause service disruption, not takeover
- The target service is business-relevant enough that an outage matters
- Impact is confined to availability
- Failover, queuing, and edge throttles can reduce user-visible disruption
The supporting signals.
| Primary CVE | CVE-2023-24998 — Tomcat's bundled FileUpload code can be abused for DoS via excessive multipart parts |
|---|---|
| In-the-wild status | No authoritative active-exploitation evidence found. I found no CISA KEV listing, and Tenable's plugin metadata says 'Exploit Ease: No known exploits are available.' |
| Proof-of-concept availability | Low-confidence / mixed. The bug is straightforward to reproduce with curl or Burp against a real upload path, but I found no authoritative, widely cited weaponized exploit chain. Treat this as *easy to script*, not *widely operationalized*. |
| EPSS | Moderately elevated exploit probability in common mirrors — Docker Scout's indexed record shows roughly 0.38449 / 97.2nd percentile. Useful as a threat signal, but it overstates urgency here because EPSS does not know whether your Tomcat estate actually exposes multipart upload endpoints. |
| KEV status | Not listed in the CISA Known Exploited Vulnerabilities catalog at review time; no KEV date added |
| CVSS vector | CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H — pure availability impact with no confidentiality or integrity loss |
| Affected versions | Apache Tomcat 9.0.0-M1 through 9.0.70 for this plugin; GitHub Advisory also maps the Tomcat ranges >= 9.0.0-M1, < 9.0.71 |
| Fixed versions | Upstream fix point is 9.0.71 for this advisory. Also note the later follow-on CVE-2023-28709 fixed in 9.0.74 because the original Tomcat-side fix was incomplete under certain non-default connector settings. |
| Distro backports | Backports exist: Debian tracks tomcat9 bullseye fixed in 9.0.43-2~deb11u7 and later; SUSE shipped SUSE-SU-2023:0696-1 for Tomcat. Do not assume upstream version strings are the only safe state. |
| Exposure reality | This is not internet-census-friendly. Shodan/Censys-style Tomcat counts would massively overstate risk because the vulnerable path depends on application behavior: a reachable multipart endpoint, not just a Tomcat listener. The decisive exposure question is *which apps accept uploads*, especially unauthenticated ones. |
noisgate verdict.
The single biggest downward pressure is that exploitation requires a reachable multipart upload workflow, not just a Tomcat version match. That sharply reduces the exposed population compared with the vendor's network-reachable CVSS baseline, and the impact stays in the availability-only lane.
Why this verdict
- Reachability is narrower than CVSS implies: an attacker needs a real multipart upload endpoint. A version-only hit on a Tomcat server does not mean the vulnerable parser is exposed to the internet.
- Attacker position often implies prior access or app knowledge: if uploads are authenticated, internal-only, or buried behind application routing, this becomes post-login or post-recon rather than a blind unauthenticated internet smash.
- Impact is availability-only: this is service disruption, not RCE, auth bypass, or data theft. Outages matter, but they usually trip monitoring fast and are easier to contain than compromise-level flaws.
Why not higher?
I did not find authoritative evidence of active exploitation, KEV inclusion, or a broadly weaponized exploit ecosystem. More importantly, the vuln only fires on a subset of Tomcat deployments that expose multipart uploads, so the reachable population is materially smaller than the vendor severity suggests.
Why not lower?
This is still unauthenticated network abuse in the common case where a public upload form exists, and Tomcat is widely deployed enough that somebody in a 10,000-host estate almost certainly has that pattern. If the affected app is customer-facing and revenue-bearing, even availability-only impact can be painful.
What to do — in priority order.
- Cap upload request size and part counts at the edge — Enforce multipart limits in the reverse proxy, API gateway, ingress, or WAF so abusive requests die before Tomcat parses them. For a MEDIUM verdict there is no mitigation SLA; apply this as hardening where upload services are exposed, while patching inside the 365-day remediation window.
- Require authentication on upload workflows — Move upload endpoints behind auth wherever business logic allows. This changes attacker position from anonymous internet traffic to authenticated or already-compromised users, which is the biggest practical reduction in exploitability; again, no mitigation SLA for MEDIUM, but prioritize internet-facing upload apps.
- Rate-limit and circuit-break upload paths — Apply per-IP and per-session request throttles on
POSTupload routes, and add concurrency ceilings to protect connector threads and app workers. This contains the abuse pattern that matters here: repeated multipart parsing under load. - Monitor JVM and temp storage saturation — Alert on upload-route concentration, rising 5xx, connector thread exhaustion, temp-directory growth, heap pressure, and restart loops. These controls do not remove the bug, but they shorten time-to-detect and keep DoS from turning into a prolonged business outage.
- Hiding the Tomcat banner doesn't help; the exploit target is the upload path, not the server fingerprint.
- EDR alone won't save you; this is a resource exhaustion problem that often looks like a legitimate application surge rather than malware execution.
- Patching only the reverse proxy is not enough unless it actually enforces multipart/body limits; otherwise the abusive request still reaches Tomcat.
Crowdsourced verification payload.
Run this on the target Tomcat host as a normal user if the Tomcat install path is readable; root is only needed if the files live in restricted directories. Invoke it as bash verify_tomcat_cve_2023_24998.sh /opt/tomcat or run with no argument to try common install paths automatically.
#!/usr/bin/env bash
# verify_tomcat_cve_2023_24998.sh
# Checks whether a local Apache Tomcat 9 install is in the vulnerable range for CVE-2023-24998
# Affected: 9.0.0-M1 through 9.0.70
# Fixed: 9.0.71+
# Exit codes: 0=PATCHED, 1=VULNERABLE, 2=UNKNOWN
set -u
TARGET_PATH="${1:-}"
FOUND_HOME=""
VERSION=""
candidates=()
if [ -n "$TARGET_PATH" ]; then
candidates+=("$TARGET_PATH")
fi
candidates+=(
/opt/tomcat
/opt/apache-tomcat*
/usr/share/tomcat
/usr/share/tomcat*
/var/lib/tomcat*
/srv/tomcat*
)
find_tomcat_home() {
local p
for p in "${candidates[@]}"; do
for expanded in $p; do
if [ -x "$expanded/bin/catalina.sh" ]; then
echo "$expanded"
return 0
fi
done
done
return 1
}
extract_version() {
local home="$1"
local out
out="$($home/bin/catalina.sh version 2>/dev/null || true)"
VERSION="$(printf '%s\n' "$out" | awk -F': ' '/Server number/ {print $2; exit}')"
if [ -z "$VERSION" ]; then
VERSION="$(printf '%s\n' "$out" | awk -F': ' '/Server version/ {print $2; exit}' | sed -E 's/.*\/([0-9]+\.[0-9]+\.[0-9]+([.-]M[0-9]+)?).*/\1/')"
fi
if [ -z "$VERSION" ] && [ -f "$home/RELEASE-NOTES" ]; then
VERSION="$(grep -Eom1 'Apache Tomcat Version [0-9]+\.[0-9]+\.[0-9]+([.-]M[0-9]+)?' "$home/RELEASE-NOTES" | awk '{print $4}')"
fi
}
normalize() {
# Convert versions like 9.0.0-M1 / 9.0.0.M1 / 9.0.70 into sortable fields
# Output: major minor patch milestoneFlag milestoneNum
local v="$1"
v="${v//-M/.M}"
local major minor patch extra
IFS='.' read -r major minor patch extra <<< "$v"
major="${major:-0}"
minor="${minor:-0}"
patch="${patch:-0}"
if [[ "$patch" =~ ^M([0-9]+)$ ]]; then
echo "${major} ${minor} 0 1 ${BASH_REMATCH[1]}"
return
fi
if [[ "$extra" =~ ^M([0-9]+)$ ]]; then
echo "${major} ${minor} ${patch} 1 ${BASH_REMATCH[1]}"
return
fi
echo "${major} ${minor} ${patch} 0 0"
}
is_vulnerable() {
local v="$1"
read -r maj min pat mflag mnum <<< "$(normalize "$v")"
# Only assess Tomcat 9.0.x here
if [ "$maj" -ne 9 ] || [ "$min" -ne 0 ]; then
return 2
fi
# Milestones like 9.0.0-M1 are vulnerable
if [ "$mflag" -eq 1 ]; then
if [ "$mnum" -ge 1 ]; then
return 0
else
return 2
fi
fi
# Numeric versions: 9.0.0 through 9.0.70 are vulnerable; 9.0.71+ patched
if [ "$pat" -lt 71 ]; then
return 0
fi
return 1
}
FOUND_HOME="$(find_tomcat_home || true)"
if [ -z "$FOUND_HOME" ]; then
echo "UNKNOWN: could not locate a Tomcat installation path"
exit 2
fi
extract_version "$FOUND_HOME"
if [ -z "$VERSION" ]; then
echo "UNKNOWN: found Tomcat at $FOUND_HOME but could not determine version"
exit 2
fi
is_vulnerable "$VERSION"
case $? in
0)
echo "VULNERABLE: Tomcat version $VERSION at $FOUND_HOME is in range 9.0.0-M1 through 9.0.70"
exit 1
;;
1)
echo "PATCHED: Tomcat version $VERSION at $FOUND_HOME is 9.0.71 or later"
exit 0
;;
*)
echo "UNKNOWN: Tomcat version $VERSION at $FOUND_HOME is outside the 9.0.x assessment scope of this script"
exit 2
;;
esac
If you remember one thing.
9.0.71+ or vendor backports, and close the work inside the noisgate remediation SLA of ≤365 days; only carve out a faster exception for business-critical public upload apps.Sources
What defenders are saying.
Crowdsourced verification outputs.
Results submitted by users who ran the verification payload against their environment.