← Back to Feed CACHED · 2026-05-17 09:42:19 · cache_key CVE-2025-29912
tenable:121119 · CWE-20 · Disclosed 2016-06-21

Apache Tomcat 7

ASSESSED — NOISGATE V0.5
Vendor
Reassessed
Verdict:
01 · The Real Story

This is less a master key and more a way to jam the mail slot with a weirdly sized package

Tenable plugin 121119 maps to CVE-2016-3092, a CPU-consumption denial of service in the package-renamed copy of Apache Commons FileUpload used by Apache Tomcat 7.0.0 through 7.0.69. The trigger is a crafted multipart/form-data request where the boundary length sits just below Tomcat's 4096-byte read buffer, making file upload parsing take orders of magnitude longer than normal.

The vendor's HIGH label follows the unauthenticated network-reachable DoS math, but it overshoots real enterprise risk. This is not RCE, not auth bypass, not data theft; it only matters on applications that actually parse multipart uploads, and modern reverse proxies, upload limits, rate controls, and autoscaling all add real friction. For most fleets this is a downgrade to MEDIUM unless the host runs a business-critical internet-facing upload workflow where availability loss is itself mission-critical.

"High CVSS, but in practice this is a narrow unauthenticated DoS on file-upload endpoints, not a broad server takeover."
02 · The Attack Path

4 steps from start to impact.

STEP 01

Find a multipart upload surface with curl or Burp

The attacker first needs an HTTP endpoint on the Tomcat-backed application that accepts multipart/form-data, such as profile image upload, document intake, or import features. This is not a Tomcat root-path bug; the request must reach code paths that invoke the servlet upload parser described in the Apache Tomcat advisory.
Conditions required:
  • Tomcat 7.x is in the affected range 7.0.0 to 7.0.69
  • A reachable application endpoint accepts multipart uploads
  • The attacker can send raw HTTP requests to that endpoint
Where this breaks in practice:
  • Many Tomcat apps never expose file upload externally
  • Upload endpoints are often behind auth, WAF, or API gateways
  • A version-only scanner cannot confirm the vulnerable code path is actually reachable
Detection/coverage: Most network scanners, including this Nessus plugin, are version-based only. App discovery, HTTP routing reviews, and proxy logs are needed to confirm exposed multipart endpoints.
STEP 02

Send a crafted boundary with a simple custom script

Using curl, Burp Repeater, or any short Python/Go script, the attacker sends a multipart body whose boundary length is just under 4096 bytes. Apache documents that this specific boundary shape causes the upload parser to take dramatically longer, burning CPU while processing the request.
Conditions required:
  • The endpoint passes the request into Tomcat's multipart parser
  • Request size and header limits still allow the crafted boundary through
Where this breaks in practice:
  • Reverse proxies may reject abnormal multipart formatting or cap header/body size
  • Per-IP rate limiting can turn this from service impact into noisy nuisance traffic
  • WAFs and API gateways often flag malformed or extreme multipart patterns
Detection/coverage: Look for unusually long boundary= parameters in request logs, repeated multipart/form-data POSTs, and elevated 4xx/5xx or upstream timeout patterns around upload endpoints.
STEP 03

Force expensive parsing in MultipartStream

The vulnerable parser spends disproportionate CPU time searching for the boundary marker, so even low-skill traffic can tie up request-processing resources. The impact is availability degradation: worker threads stay busy longer, response latency spikes, and the service may become unresponsive under sustained requests.
Conditions required:
  • The Tomcat node has finite request threads and CPU headroom
  • Traffic volume is enough to outpace normal recovery
Where this breaks in practice:
  • Load balancers can spread impact across nodes
  • Node restarts or auto-healing reduce persistence
  • This does not give foothold, persistence, or lateral movement
Detection/coverage: JVM and APM telemetry should show CPU spikes and long request times around upload handlers. Thread dumps may implicate multipart parsing rather than application business logic.
STEP 04

Cause service degradation, not compromise

The end state is denial of service against the affected application function or node. There is no privilege gain and no direct confidentiality or integrity impact from this CVE alone.
Conditions required:
  • The targeted workflow is operationally important enough that slowdown equals outage
Where this breaks in practice:
  • HA pairs, CDNs, queue-backed upload designs, and blue/green pools limit blast radius
  • Attackers usually prefer flaws that yield access, not just compute burn
Detection/coverage: Operational monitoring is more valuable than signature detection here: watch saturation, thread pool exhaustion, and upload endpoint latency.
03 · Intelligence Metadata

The supporting signals.

In-the-wild statusNo confirmed active exploitation found in the reviewed sources; OpenCVE marks KEV: no.
Proof-of-concept availabilityLow barrier to weaponize. This is easy to reproduce with a custom HTTP client because the trigger is just a specially sized multipart boundary; public trackers also reference public PoC availability, but no widely used Metasploit-grade campaign surfaced in review.
EPSSOpenCVE shows EPSS 0.36479. Treat that as a signal of attacker interest in the CVE family, not as proof this specific Tomcat deployment is broadly exploitable.
KEV statusNot listed in CISA KEV according to OpenCVE enrichment; no KEV date applies.
CVSS vectorCVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H — pure network-reachable availability hit, with no confidentiality or integrity impact.
Affected versionsApache states Tomcat 7.0.0 to 7.0.69 are affected for this issue; Tenable's plugin is the same mapping.
Fixed versionsUpstream fixed in Tomcat 7.0.70. Debian shows backported fixes for tomcat7 including 7.0.56-3+deb8u3 on Jessie and 7.0.28-4+deb7u5 on Wheezy; Ubuntu lists fixes for older packaged tomcat6 branches, illustrating why package version alone can mislead.
Scanning / exposure realityTomcat is widely internet-exposed in general, but no authoritative public scan count for CVE-2016-3092-exposed upload endpoints surfaced in review. Reachability depends on whether a live app actually exposes multipart upload, which internet census tools usually cannot prove.
Disclosure timelineApache says the issue was made public on 2016-06-21 and fixed in Tomcat 7.0.70.
ReporterApache credits the TERASOLUNA Framework Development Team, reported via JPCERT.
04 · The Call

noisgate verdict.

Final Verdict
DOWNGRADED to MEDIUM (5.6/10)

The decisive downgrade factor is application-path friction: the attacker needs a reachable multipart upload endpoint, not just any Tomcat listener. This flaw is unauthenticated and remotely triggerable, but it only yields CPU-bound availability loss and stops well short of code execution or tenant escape.

HIGH Plugin-to-CVE mapping and affected version range
MEDIUM Real-world exploitability across mixed enterprise Tomcat deployments

Why this verdict

  • Down from HIGH because this is DoS only — the CVSS is driven entirely by availability impact; there is no auth bypass, data exposure, or code execution.
  • Down again because attacker reachability is narrower than the score implies — exploitation requires a live multipart/form-data upload path, and many Tomcat services do not expose one externally.
  • Down again because common controls add real drag — reverse proxies, WAFs, request-size limits, and rate limiting often break or dampen malformed upload abuse before Tomcat burns CPU.

Why not higher?

There is no evidence here of broad in-the-wild exploitation, no KEV listing, and no post-exploitation value beyond temporary service degradation. A flaw that only burns CPU on specific upload endpoints should not sit in the same bucket as unauthenticated RCE on every exposed node.

Why not lower?

I am not dropping this to LOW because the trigger is still remote, unauthenticated, and cheap to generate. If you run a public upload-heavy workflow on old Tomcat 7, an attacker can create meaningful operational pain without owning the box.

05 · Compensating Control

What to do — in priority order.

  1. Clamp multipart request size and rate — Set strict body-size, part-count, and per-IP rate limits at the reverse proxy or API gateway so abnormal upload traffic is rejected before Tomcat parses it. For a MEDIUM verdict there is no mitigation SLA, but apply this opportunistically on internet-facing upload paths while you work toward patching within the remediation window.
  2. Hide or gate upload endpoints — Move admin/import/upload functions behind authentication, VPN, or an internal ingress tier where feasible. This directly removes the unauthenticated remote precondition that makes the bug interesting.
  3. Watch upload handlers, not just host CPU — Alert on long-running multipart POSTs, upload endpoint latency, thread pool exhaustion, and repeated oversized boundary strings. This catches abuse faster than generic host-availability alerts.
  4. Drain legacy Tomcat 7 from public duty — Even if this single CVE is only MEDIUM, a public-facing Tomcat 7 estate is technical debt with a growing vulnerability stack. Use this finding as leverage to retire or front-end-isolate the platform.
What doesn't work
  • A network IDS signature alone is weak here because the attack is just weird-but-valid HTTP multipart traffic and can be reshaped easily.
  • EDR on the host will not reliably save you from parser-driven CPU exhaustion; there may be no payload, child process, or memory corruption signal to catch.
  • Version-only exception logic is dangerous on distro builds because backports can make an older-looking package fixed, while custom Tomcat installs can remain vulnerable outside package management.
06 · Verification

Crowdsourced verification payload.

Run this on the target Tomcat host or from an auditor workstation that can read the Tomcat install directory over SSH or a mounted filesystem. Invoke it as python3 verify_tomcat_121119.py /opt/tomcat with read access only; no root is required. It checks an upstream Tomcat install tree and reports VULNERABLE, PATCHED, or UNKNOWN for this specific 7.0.0 < 7.0.70 finding.

noisgate-verify.py
PYTHONREAD-ONLYSAFE
#!/usr/bin/env python3
# verify_tomcat_121119.py
# Check Apache Tomcat against Nessus plugin 121119 / CVE-2016-3092
# Usage: python3 verify_tomcat_121119.py /path/to/tomcat
# Exit codes: 0=PATCHED, 1=VULNERABLE, 2=UNKNOWN

import os
import re
import sys
import zipfile

TARGET_FIXED = (7, 0, 70)


def parse_version(text):
    m = re.search(r'Apache Tomcat/?\s*([0-9]+)\.([0-9]+)\.([0-9]+)', text)
    if not m:
        m = re.search(r'([0-9]+)\.([0-9]+)\.([0-9]+)', text)
    if not m:
        return None
    return tuple(int(x) for x in m.groups())


def read_server_info(catalina_home):
    candidates = [
        os.path.join(catalina_home, 'lib', 'catalina.jar'),
        os.path.join(catalina_home, 'server', 'lib', 'catalina.jar'),
    ]
    for jar_path in candidates:
        if not os.path.isfile(jar_path):
            continue
        try:
            with zipfile.ZipFile(jar_path, 'r') as zf:
                for name in (
                    'org/apache/catalina/util/ServerInfo.properties',
                    'META-INF/MANIFEST.MF',
                ):
                    try:
                        data = zf.read(name).decode('utf-8', errors='ignore')
                        ver = parse_version(data)
                        if ver:
                            return ver, jar_path, name
                    except KeyError:
                        continue
        except Exception:
            continue
    return None, None, None


def main():
    if len(sys.argv) != 2:
        print('UNKNOWN - usage: python3 verify_tomcat_121119.py /path/to/tomcat')
        sys.exit(2)

    catalina_home = sys.argv[1]
    if not os.path.isdir(catalina_home):
        print(f'UNKNOWN - path not found: {catalina_home}')
        sys.exit(2)

    version, source_file, source_member = read_server_info(catalina_home)
    if not version:
        print('UNKNOWN - could not determine Tomcat version from catalina.jar')
        sys.exit(2)

    version_str = '.'.join(str(x) for x in version)
    source_desc = f'{source_file}!{source_member}'

    # Plugin 121119 applies only to Tomcat 7.x before 7.0.70
    if version[0] != 7:
        print(f'PATCHED - detected Apache Tomcat {version_str} at {source_desc}; plugin 121119 targets Tomcat 7.x only')
        sys.exit(0)

    if version < TARGET_FIXED:
        print(f'VULNERABLE - detected Apache Tomcat {version_str} at {source_desc}; affected range is 7.0.0 through 7.0.69')
        sys.exit(1)

    print(f'PATCHED - detected Apache Tomcat {version_str} at {source_desc}; fixed upstream in 7.0.70+')
    sys.exit(0)


if __name__ == '__main__':
    main()
07 · Bottom Line

If you remember one thing.

TL;DR
Monday morning: treat this as legacy Tomcat hygiene with availability risk, not as an emergency breach path. For a MEDIUM verdict there is no noisgate mitigation SLA — go straight to the 365-day remediation window; patch or replace affected Tomcat 7 instances by the noisgate remediation SLA of ≤365 days, but move internet-facing upload services to the front of that queue and add proxy-side request limits during the next normal maintenance cycle.

Sources

  1. Tenable Nessus Plugin 121119
  2. Apache Tomcat 7 security page
  3. NVD CVE-2016-3092
  4. OpenCVE CVE-2016-3092
  5. Ubuntu CVE-2016-3092
  6. Debian Security Tracker CVE-2016-3092
  7. Apache Wicket note on CVE-2016-3092
  8. CVE record
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.