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.
4 steps from start to impact.
Find a multipart upload surface with curl or Burp
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.- Tomcat 7.x is in the affected range
7.0.0to7.0.69 - A reachable application endpoint accepts multipart uploads
- The attacker can send raw HTTP requests to that endpoint
- 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
Send a crafted boundary with a simple custom script
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.- The endpoint passes the request into Tomcat's multipart parser
- Request size and header limits still allow the crafted boundary through
- 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
boundary= parameters in request logs, repeated multipart/form-data POSTs, and elevated 4xx/5xx or upstream timeout patterns around upload endpoints.Force expensive parsing in MultipartStream
- The Tomcat node has finite request threads and CPU headroom
- Traffic volume is enough to outpace normal recovery
- Load balancers can spread impact across nodes
- Node restarts or auto-healing reduce persistence
- This does not give foothold, persistence, or lateral movement
Cause service degradation, not compromise
- The targeted workflow is operationally important enough that slowdown equals outage
- 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
The supporting signals.
| In-the-wild status | No confirmed active exploitation found in the reviewed sources; OpenCVE marks KEV: no. |
|---|---|
| Proof-of-concept availability | Low 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. |
| EPSS | OpenCVE 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 status | Not listed in CISA KEV according to OpenCVE enrichment; no KEV date applies. |
| CVSS vector | CVSS: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 versions | Apache states Tomcat 7.0.0 to 7.0.69 are affected for this issue; Tenable's plugin is the same mapping. |
| Fixed versions | Upstream 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 reality | Tomcat 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 timeline | Apache says the issue was made public on 2016-06-21 and fixed in Tomcat 7.0.70. |
| Reporter | Apache credits the TERASOLUNA Framework Development Team, reported via JPCERT. |
noisgate verdict.
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.
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-dataupload 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.
What to do — in priority order.
- 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.
- 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.
- 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.
- 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.
- 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.
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.
#!/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()
If you remember one thing.
Sources
What defenders are saying.
Crowdsourced verification outputs.
Results submitted by users who ran the verification payload against their environment.