← Back to Feed CACHED · 2026-09-14 08:46:34 · CACHE_KEY CVE-2025-48976
CVE-2025-48976 · CWE-770 · Disclosed 2025-06-16

Allocation of resources for multipart headers with insufficient limits enabled a DoS vulnerability in…

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

Imagine every door in your building can be jammed shut with a single envelope stuffed with too many pages

CVE-2025-48976 is a resource-exhaustion denial-of-service in Apache Commons FileUpload, the de-facto multipart/form-data parsing library for the Java ecosystem. The flaw is dead simple: the library hard-coded a 10 KB ceiling on per-part header sizes but imposed no limit on the number of parts or the number of headers per part. An attacker sends a single HTTP POST with thousands of parts, each carrying dozens of custom headers, and the server allocates memory for all of them until the JVM stalls. Affected versions span commons-fileupload 1.0 through 1.5.x and commons-fileupload2-core 2.0.0-M1 through 2.0.0-M3. Because Apache Tomcat bundles its own copy of this code, Tomcat 9.0.0.M1–9.0.105, 10.1.0.M1–10.1.41, and 11.0.0.M1–11.0.7 are independently affected under the sibling CVE-2025-48988.

The vendor's HIGH / 7.5 rating is honest and well-calibrated. This is unauthenticated, low-complexity, no-interaction DoS over the network — all the attack-path knobs are turned to maximum ease. What keeps it from CRITICAL is the impact ceiling: availability loss only, with no path to code execution, data exfiltration, or privilege escalation. A restart plus a WAF rule restores service. Given the 142,000+ Maven Central dependents on commons-fileupload 1.x alone, plus Tomcat's installed base, the exposure population is enormous — but the consequence per hit is bounded at service disruption.

"Trivial unauthenticated DoS with public PoC against one of Java's most pervasive libraries — patch or throttle."
02 · The Attack Path

4 steps from start to impact.

STEP 01

Identify multipart upload endpoint

The attacker locates any HTTP endpoint that accepts multipart/form-data — file uploads, form submissions, API calls. No authentication or special knowledge is needed; a simple Content-Type probe or directory brute-force suffices. The endpoint only needs to invoke FileUpload.parseRequest() or Tomcat's built-in multipart parsing.
Conditions required:
  • Target application exposes at least one multipart-capable endpoint
  • Target is reachable over the network
Where this breaks in practice:
  • Endpoint may sit behind a CDN or WAF that enforces body-size or part-count limits
  • Internal-only apps are unreachable from the internet
Detection/coverage: WAF rules that cap multipart part counts or header counts will log/block. Standard access logs show the oversized POST.
STEP 02

Craft malicious multipart payload

Using the public PoC (Samb102/POC-CVE-2025-48988-CVE-2025-48976), the attacker constructs a POST body containing 1,000 parts with 50 custom headers each. No special tooling beyond Python requests is required. The payload is deterministic — no brute-forcing, no race conditions, no heap grooming.
Conditions required:
  • Attacker has network connectivity to the endpoint
Where this breaks in practice:
  • Payload is large (~tens of MB); bandwidth-constrained attackers may struggle at scale
  • PoC defaults target Tomcat specifically; adaptation to other servlet containers is trivial but requires awareness
Detection/coverage: IDS signatures for abnormal multipart part counts. GreyNoise / honeypot correlation may detect scanning for upload endpoints.
STEP 03

Send parallelized requests

The PoC fires 1,000 concurrent requests from 50 workers. Each request forces the JVM to allocate memory for all part headers before any application-level validation runs. The heap fills, GC thrashes, and the application thread pool saturates. CPU spikes to 100% within seconds on a default-configured Tomcat instance.
Conditions required:
  • Target JVM has default or generous heap settings
  • No reverse-proxy rate limiting in front of the application
Where this breaks in practice:
  • Enterprise load balancers (F5, HAProxy, Envoy) with connection-rate limits will throttle the flood
  • Kubernetes pods with memory limits will OOMKill and restart, limiting sustained impact
  • Tomcat maxParameterCount or maxPartCount (if set) can cap part processing
Detection/coverage: APM alerts on heap exhaustion, GC pause spikes, or thread-pool saturation. Container orchestrator OOMKill events.
STEP 04

Service denial achieved

The target application becomes unresponsive. Legitimate users receive HTTP 503 or connection timeouts. If the JVM OOMs hard, the process crashes. Recovery requires a restart or, in containerized environments, occurs automatically via liveness probes — but the attacker can sustain the attack with continued requests.
Conditions required:
  • Steps 1–3 succeeded
Where this breaks in practice:
  • Auto-scaling or container restarts limit downtime window
  • Geographic rate limiting or IP reputation blocking can cut off the attacker
Detection/coverage: Uptime monitors, synthetic transactions, and health-check failures all fire immediately.
03 · Intelligence Metadata

The supporting signals.

In-the-Wild StatusNo confirmed active campaigns. Not on CISA KEV. However, EPSS 62.6% (99th percentile) signals extremely high exploitation probability — the statistical model expects widespread opportunistic scanning.
Proof of ConceptPublic PoC by Samb102 on GitHub — Python script, weaponized with Docker lab. Fires 1,000 parallel multipart requests × 1,000 parts × 50 headers from 50 workers. Trivially adaptable.
EPSS0.62646 — 99th percentile. Among the highest-probability CVEs in the current window.
KEV StatusNot listed as of 2026-09-14.
CVSS VectorCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H — Network attack, no auth, no interaction, availability-only impact. GHSA independently scored CVSS 4.0 at 8.7.
Affected Versionscommons-fileupload 1.0 – 1.5.x; commons-fileupload2-core 2.0.0-M1 – 2.0.0-M3. Also Tomcat 9.0.x ≤ 9.0.105, 10.1.x ≤ 10.1.41, 11.0.x ≤ 11.0.7 (via CVE-2025-48988).
Fixed Versionscommons-fileupload 1.6.0, commons-fileupload2-core 2.0.0-M4. Tomcat 9.0.106, 10.1.42, 11.0.8.
Exposure DataMaven Central shows 142,000+ dependents on commons-fileupload 1.x. Tomcat is the world's most-deployed Java servlet container. Combined exposure is massive but the vulnerable parsing path requires an active multipart endpoint.
Disclosure Date2025-06-16, coordinated by the Apache Software Foundation.
ReporterNot individually credited in the ASF advisory. Discovered during internal code review / community contribution.
04 · The Call

noisgate verdict.

Final Verdict
= UNCHANGED to HIGH (7.5/10)

The single most decisive factor is the availability-only impact ceiling — this is a pure DoS with no path to code execution, data access, or lateral movement, which caps the severity below CRITICAL despite trivial unauthenticated exploitation. The enormous installed base (142K+ Maven dependents, all supported Tomcat branches) and a weaponized public PoC at the 99th EPSS percentile justify maintaining — not downgrading — the vendor's HIGH rating.

HIGH Vulnerability mechanics and affected versions
HIGH Availability-only impact assessment
MEDIUM In-the-wild exploitation status (no KEV, but EPSS is extreme)

Why this verdict

  • Unauthenticated, zero-interaction, low-complexity network attack — every multipart endpoint in every affected Java app is a target. No friction on the attacker's side of the equation.
  • Massive exposure population — commons-fileupload 1.x has 142K+ Maven Central dependents; Tomcat is independently affected across three major branches. This is not a niche library.
  • Weaponized public PoC — Samb102's exploit is copy-paste ready with a Docker lab, and EPSS at the 99th percentile reflects the statistical expectation of mass scanning.
  • Role multiplier: Commons FileUpload and Tomcat are used across every deployment role — workstations (dev), line-of-business apps, identity providers (Keycloak on Tomcat), CI/CD (Jenkins), and monitoring dashboards. A DoS against an IdP or CI server causes cascading outages, but the blast radius remains service unavailability, not compromise. Even in the worst high-value role scenario (IdP down → auth outage across the fleet), recovery is a restart, not a forensic investigation. This keeps the floor at HIGH, not CRITICAL.
  • Impact ceiling is availability-only — CVSS C:N/I:N/A:H. No memory corruption, no arbitrary write, no deserialization chain. The vulnerability cannot be upgraded to RCE by chaining with other primitives.

Why not higher?

CRITICAL requires a path to confidentiality or integrity impact, or an availability impact so catastrophic it threatens safety (OT/ICS). This CVE is pure resource exhaustion — the JVM runs out of heap and the process stalls or crashes. Recovery is a restart. Even against high-value targets like an IdP running on Tomcat, the outcome is a temporary outage, not domain takeover or data breach. There is no chain to RCE.

Why not lower?

Downgrading below HIGH would ignore the combination of zero-authentication exploitation, a weaponized public PoC, 99th-percentile EPSS, and the broadest possible Java library exposure. Any internet-facing Java application that accepts file uploads is a sitting target with no attacker prerequisites. The statistical model strongly predicts mass exploitation attempts, and the library's ubiquity means your fleet almost certainly includes affected instances.

05 · Compensating Control

What to do — in priority order.

  1. Deploy WAF rules to limit multipart part count and header count — Configure your WAF (ModSecurity, AWS WAF, Cloudflare, F5 ASM) to reject requests with more than 100 parts or more than 20 headers per part. This directly blocks the attack vector. Deploy within 30 days per the noisgate mitigation SLA for HIGH.
  2. Set Tomcat maxPartCount parameter — In Tomcat's server.xml or web.xml, set <multipart-config><max-file-size> and the maxParameterCount connector attribute. Tomcat 10.1.42+ adds explicit maxPartCount; on older versions, maxParameterCount provides partial coverage. Apply to all Tomcat instances.
  3. Configure JVM heap limits and container memory ceilings — Ensure -Xmx is set conservatively and Kubernetes resources.limits.memory is enforced. This converts a hang into an OOMKill + automatic restart, limiting the blast radius to seconds of downtime rather than sustained outage.
  4. Rate-limit POST requests to upload endpoints — At the reverse proxy or API gateway layer, enforce per-IP rate limits (e.g., 10 multipart POSTs/minute) on known upload paths. This blunts parallelized attacks even if the payload structure isn't inspected.
What doesn't work
  • Network-level DDoS protection (Cloudflare L3/L4, AWS Shield) — this is an application-layer (L7) attack using valid HTTP. Volumetric DDoS mitigation won't inspect multipart structure.
  • Authentication requirements alone — if the upload endpoint already requires auth, it helps narrow attackers to credential holders, but authenticated users can still trigger the DoS. The fix must be at the parsing layer.
  • Java Security Manager — deprecated since Java 17 and doesn't restrict heap allocation patterns. It cannot prevent this class of resource exhaustion.
06 · Verification

Crowdsourced verification payload.

Run this on any host where you need to check for vulnerable commons-fileupload JARs or Tomcat versions. Execute as any user with read access to the application's lib directories. Example: bash check_cve_2025_48976.sh /opt/tomcat /opt/myapp/WEB-INF/lib

noisgate-verify.sh
BASHREAD-ONLYSAFE
#!/usr/bin/env bash
# check_cve_2025_48976.sh — Detect CVE-2025-48976 / CVE-2025-48988
# Usage: bash check_cve_2025_48976.sh <dir1> [dir2] ...
# Exit codes: 0 = PATCHED/UNKNOWN, 1 = VULNERABLE

set -euo pipefail

VULNERABLE=0

if [ $# -eq 0 ]; then
  echo "Usage: $0 <directory> [directory ...]"
  echo "Scans for vulnerable commons-fileupload JARs and Tomcat versions."
  exit 2
fi

for DIR in "$@"; do
  if [ ! -d "$DIR" ]; then
    echo "[SKIP] Not a directory: $DIR"
    continue
  fi

  # Check commons-fileupload 1.x (vulnerable: 1.0–1.5.x)
  find "$DIR" -name 'commons-fileupload-*.jar' 2>/dev/null | while read -r JAR; do
    VER=$(basename "$JAR" | sed -E 's/commons-fileupload-([0-9][0-9.]*).*/\1/')
    MAJOR=$(echo "$VER" | cut -d. -f1)
    MINOR=$(echo "$VER" | cut -d. -f2)
    if [ "$MAJOR" -eq 1 ] && [ "$MINOR" -lt 6 ]; then
      echo "[VULNERABLE] $JAR (version $VER < 1.6.0)"
      VULNERABLE=1
    else
      echo "[PATCHED]    $JAR (version $VER)"
    fi
  done

  # Check commons-fileupload2-core (vulnerable: 2.0.0-M1 through 2.0.0-M3)
  find "$DIR" -name 'commons-fileupload2-core-*.jar' 2>/dev/null | while read -r JAR; do
    BASENAME=$(basename "$JAR")
    if echo "$BASENAME" | grep -qE '2\.0\.0-M[123][^0-9]'; then
      echo "[VULNERABLE] $JAR (pre-2.0.0-M4)"
      VULNERABLE=1
    else
      echo "[PATCHED]    $JAR"
    fi
  done

  # Check Tomcat version via catalina.jar MANIFEST or version.sh
  CATALINA_JAR=$(find "$DIR" -name 'catalina.jar' -path '*/lib/*' 2>/dev/null | head -1)
  if [ -n "${CATALINA_JAR:-}" ]; then
    TC_VER=$(unzip -p "$CATALINA_JAR" org/apache/catalina/util/ServerInfo.properties 2>/dev/null | grep 'server.number' | cut -d= -f2 | tr -d '[:space:]')
    if [ -n "$TC_VER" ]; then
      TC_MAJOR=$(echo "$TC_VER" | cut -d. -f1)
      TC_MINOR=$(echo "$TC_VER" | cut -d. -f2)
      TC_PATCH=$(echo "$TC_VER" | cut -d. -f3)
      VULN_TC=0
      if [ "$TC_MAJOR" -eq 9 ] && [ "$TC_MINOR" -eq 0 ] && [ "$TC_PATCH" -le 105 ]; then VULN_TC=1; fi
      if [ "$TC_MAJOR" -eq 10 ] && [ "$TC_MINOR" -eq 1 ] && [ "$TC_PATCH" -le 41 ]; then VULN_TC=1; fi
      if [ "$TC_MAJOR" -eq 11 ] && [ "$TC_MINOR" -eq 0 ] && [ "$TC_PATCH" -le 7 ]; then VULN_TC=1; fi
      if [ "$VULN_TC" -eq 1 ]; then
        echo "[VULNERABLE] Tomcat $TC_VER at $(dirname "$CATALINA_JAR") (CVE-2025-48988)"
        VULNERABLE=1
      else
        echo "[PATCHED]    Tomcat $TC_VER at $(dirname "$CATALINA_JAR")"
      fi
    fi
  fi
done

if [ "$VULNERABLE" -eq 1 ]; then
  echo ""
  echo "RESULT: VULNERABLE"
  exit 1
else
  echo ""
  echo "RESULT: PATCHED (or no matching JARs found — verify manually)"
  exit 0
fi
07 · Bottom Line

If you remember one thing.

TL;DR
Monday morning: run an SCA scan (Dependency-Track, Snyk, or the verification script above) across your Java fleet to identify every instance of commons-fileupload < 1.6.0 and Tomcat < 9.0.106 / 10.1.42 / 11.0.8. Prioritize internet-facing apps with file-upload functionality — these are directly exploitable with a public PoC and zero authentication. Per the noisgate mitigation SLA for HIGH, deploy WAF part-count limits or Tomcat maxPartCount configuration within 30 days. Per the noisgate remediation SLA, complete library upgrades and Tomcat patching across all environments within 180 days. Given the 99th-percentile EPSS and weaponized PoC, front-load internet-facing systems into the first mitigation wave. This is DoS-only — no emergency weekend patching — but the attack surface is too broad and the tooling too accessible to let it slide past the 30-day mitigation window.

Sources

  1. GitHub Advisory — GHSA-vv7r-c36w-3prj
  2. Public PoC — Samb102/POC-CVE-2025-48988-CVE-2025-48976
  3. NVD — CVE-2025-48976 Detail
  4. Apache Tomcat 10 Security Advisories
  5. IBM Security Bulletin — WebSphere Application Server
  6. Exploit Intel — CVE-2025-48976
  7. Maven Central — commons-fileupload
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.