This is a sharp edge on the showroom model, not a flaw in the engine
Tenable plugin 162498 maps to CVE-2022-34305, a reflected XSS in Tomcat's examples web application, specifically the Form authentication example. The affected Tomcat line for this finding is 9.0.30 through 9.0.64, fixed in 9.0.65; other affected branches were 8.5.50-8.5.81, 10.0.0-M1-10.0.22, and 10.1.0-M1-10.1.0-M16.
The vendor's MEDIUM label is technically fair in a vacuum, but operationally inflated for enterprise patch triage. The bug is only reachable if the examples webapp is actually deployed and reachable, and exploitation still requires user interaction in a browser; that's a long way from the scanner's broad version-only match.
3 steps from start to impact.
Find a Tomcat host with the examples app still deployed
/examples/ is exposed. The practical weapon here is simple HTTP probing or search-engine-style reconnaissance; the vulnerable code is not in core request handling but in the sample Form authentication example.- Unauthenticated network reachability to the Tomcat HTTP(S) listener
- Tomcat version 9.0.30-9.0.64
- The
examplesweb application is installed and accessible
- Many production estates remove sample apps entirely
- Reverse proxies often hide Tomcat directly and block
/examples/ - Version-only scanner findings do not prove the vulnerable webapp exists
/examples/jsp/security/protected/ is reachable.Deliver a crafted XSS link
- A user must browse to the crafted URL
- The request must hit the vulnerable example endpoint
- Browser-side script execution must not be blocked by existing controls
- Requires social engineering or another delivery path
- Modern email/web filtering may block obviously malicious URLs
- If the examples app is not internet-exposed, the attacker needs internal reach or a victim already on-network/VPN
/examples/ and suspicious parameters.Run script in the victim's browser under Tomcat origin
- Successful browser execution
- A victim with a meaningful session or access level
- Same-origin access to anything worth stealing or invoking
- Impact is bounded to browser/session context, not server-side code execution
- No direct JVM, OS, or filesystem compromise from this CVE alone
- If no admin workflows share the origin, blast radius is modest
/examples/.The supporting signals.
| Primary CVE | CVE-2022-34305 — Tomcat examples webapp reflected XSS (CWE-79) |
|---|---|
| In-the-wild status | No authoritative evidence found of broad active exploitation; not present in the public CISA KEV catalog in reviewed sources |
| Proof-of-concept availability | Public exploit references exist, including a GitHub PoC (zeroc00I/CVE-2022-34305) and a Nuclei check surfaced via Vulners/Wiz |
| EPSS | Tenable shows EPSS 0.16853 (~16.9%), which is elevated for a bug this operationally narrow; treat as threat interest, not business impact |
| KEV status | Not KEV-listed in reviewed CISA catalog sources; no KEV added date because none was found |
| CVSS vector | CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N — the big limiter is UI:R and the impact stays in the browser/session plane |
| Affected versions | Tomcat 9.0.30-9.0.64 for this plugin; broader CVE scope also includes 8.5.50-8.5.81, 10.0.0-M1-10.0.22, 10.1.0-M1-10.1.0-M16 |
| Fixed versions | Upstream fixed in 9.0.65; Debian tracks fix at tomcat9 9.0.65-1 and later distro backports (e.g. bullseye security currently fixed in newer backported package) |
| Exposure reality | Internet-facing Tomcat is common, but this flaw only matters when the examples app is deployed; Apache's own security guidance says the examples webapp should always be removed from security-sensitive installs |
| Disclosure / reporter | Publicly disclosed 2022-06-23; Apache says it was reported to the Tomcat Security Team on 2022-06-22 and does not name an external researcher in the advisory material reviewed |
noisgate verdict.
The decisive downgrade factor is that exploitation depends on the examples sample webapp being deployed and reachable; a version-only Nessus hit does not prove that prerequisite. Even then, the attacker still needs user interaction, so this is not a wormable or direct server-side compromise class of issue.
Why this verdict
- Downward pressure: sample app required — the vulnerable code lives in Tomcat's
examplesweb application, not in the core servlet container, so estates that remove sample apps are not actually exposed even if the version matches. - Downward pressure: user interaction required — the CVSS vector includes
UI:R; the attacker needs a victim to load a crafted URL, which implies phishing, chat delivery, or another lure step. - Downward pressure: browser-side impact — this is XSS with session/origin abuse potential, not JVM RCE, container escape, or arbitrary file write.
- Downward pressure: exposure fraction is narrow — in real enterprise deployments, the fraction of Tomcat servers with
/examples/still published externally should be far below the fraction merely running Tomcat 9.0.30-9.0.64. - Baseline kept above IGNORE — if a victim with meaningful privileges browses the page and admin functions share the same origin, the attacker can still steal session context or trigger actions.
Why not higher?
There is no evidence here of unauthenticated server-side code execution, privilege escalation on the host, or easy autonomous exploitation. The chain requires both a configuration mistake (examples left deployed) and a delivery step (victim interaction), which compounds the friction hard enough to push this well below MEDIUM in most estates.
Why not lower?
It is still a real remotely triggerable web bug when the sample app is exposed, and many orgs inherit Tomcat inside third-party products that leave default content behind. If the vulnerable examples app shares origin with admin or authenticated workflows, the resulting session theft or forced actions can still hurt.
What to do — in priority order.
- Remove the examples app — Delete or undeploy
$CATALINA_BASE/webapps/examples(or the equivalent packaged sample app) because that removes the vulnerable surface entirely. For a LOW verdict there is no SLA from noisgate, but this is still cheap backlog hygiene and should be folded into the next normal hardening cycle. - Block
/examples/at the proxy — If you cannot touch the application server immediately, deny access to/examples/*at the reverse proxy, ingress, or WAF. This is an effective temporary control because the bug is tied to a specific sample application path; for LOW, do it during routine config maintenance rather than emergency change windows. - Verify same-origin admin exposure — Check whether Tomcat Manager, Host Manager, product admin consoles, or authenticated business apps share the same origin as the exposed examples app. If they do, the impact of this XSS rises because stolen cookies and browser-driven actions become more valuable.
- Patch during regular maintenance — Upgrade to 9.0.65+ or consume the relevant distro backport to close the finding cleanly. For a LOW verdict, keep it in scheduled remediation rather than front-of-queue emergency patching.
- Relying on MFA does not stop browser-side script execution once a victim is already authenticated to the origin.
- Generic EDR on the server is not a strong control here because the exploit runs in the victim browser, not as a new process on the Tomcat host.
- Only upgrading if the scanner sees Tomcat externally is insufficient; internal-only portals can still be exploitable if staff browse to the sample app.
Crowdsourced verification payload.
Run this on the target host or on a mounted Tomcat installation directory. Invoke it as python3 check_tomcat_cve_2022_34305.py /opt/tomcat or python check_tomcat_cve_2022_34305.py "C:\Program Files\Apache Software Foundation\Tomcat 9.0"; no admin rights are required if you can read the Tomcat files.
#!/usr/bin/env python3
# check_tomcat_cve_2022_34305.py
# Exit codes:
# 0 = PATCHED
# 1 = VULNERABLE
# 2 = UNKNOWN
import os
import re
import sys
import zipfile
from pathlib import Path
def parse_version(v):
m = re.match(r'^(\d+)\.(\d+)\.(\d+)', v or '')
if not m:
return None
return tuple(int(x) for x in m.groups())
def read_manifest_version(catalina_jar):
try:
with zipfile.ZipFile(catalina_jar, 'r') as zf:
data = zf.read('META-INF/MANIFEST.MF').decode('utf-8', errors='ignore')
for line in data.splitlines():
if line.startswith('Implementation-Version:'):
return line.split(':', 1)[1].strip()
if line.startswith('Specification-Version:'):
spec = line.split(':', 1)[1].strip()
if spec:
return spec
except Exception:
return None
return None
def find_version(base):
candidates = [
base / 'lib' / 'catalina.jar',
base / 'bin' / 'bootstrap.jar',
]
for c in candidates:
if c.exists():
v = read_manifest_version(c)
if v:
return v
release_notes = [
base / 'RELEASE-NOTES',
base / 'RUNNING.txt',
base / 'webapps' / 'ROOT' / 'RELEASE-NOTES.txt',
]
for rn in release_notes:
if rn.exists():
try:
text = rn.read_text(errors='ignore')
m = re.search(r'Apache Tomcat Version\s+([0-9]+\.[0-9]+\.[0-9]+)', text)
if m:
return m.group(1)
except Exception:
pass
return None
def examples_present(base):
paths = [
base / 'webapps' / 'examples',
base / 'webapps' / 'examples.war',
base / 'webapps-javaee' / 'examples',
base / 'webapps-javaee' / 'examples.war',
]
return any(p.exists() for p in paths)
def vulnerable_range(version_tuple):
# Plugin scope: Tomcat 9.0.30 < 9.0.65
return (9, 0, 30) <= version_tuple < (9, 0, 65)
def main():
if len(sys.argv) != 2:
print('UNKNOWN - usage: python3 check_tomcat_cve_2022_34305.py <CATALINA_BASE_or_HOME>')
sys.exit(2)
base = Path(sys.argv[1])
if not base.exists() or not base.is_dir():
print(f'UNKNOWN - path not found: {base}')
sys.exit(2)
version = find_version(base)
if not version:
print('UNKNOWN - could not determine Tomcat version from local files')
sys.exit(2)
vt = parse_version(version)
if not vt:
print(f'UNKNOWN - unparseable Tomcat version: {version}')
sys.exit(2)
has_examples = examples_present(base)
if vulnerable_range(vt) and has_examples:
print(f'VULNERABLE - Tomcat {version} with examples webapp present')
sys.exit(1)
elif vulnerable_range(vt) and not has_examples:
print(f'PATCHED - Tomcat {version} is in affected range but examples webapp is absent; CVE-2022-34305 not reachable locally')
sys.exit(0)
else:
print(f'PATCHED - Tomcat {version} is outside plugin affected range')
sys.exit(0)
if __name__ == '__main__':
main()
If you remember one thing.
/examples/ is actually exposed. For a LOW verdict there is no noisgate mitigation SLA and noisgate remediation SLA is essentially backlog hygiene, so verify presence of the sample app first, remove or block /examples/ during normal hardening work, and roll the Tomcat upgrade into your standard maintenance cycle rather than burning an emergency window.Sources
What defenders are saying.
Crowdsourced verification outputs.
Results submitted by users who ran the verification payload against their environment.