← Back to Feed CACHED · 2026-05-17 09:42:19 · cache_key CVE-2025-29912
tenable:121120 · CWE-668 · Disclosed 2017-04-17

Apache Tomcat 7

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

This is a bad lock between apartments, not a burglar walking in from the street

Plugin 121120 maps to CVE-2017-5648. In Apache Tomcat 7.0.0 through 7.0.75 (7.0.76 fixes it), some listener calls exposed the wrong object wrapper, so a malicious webapp already deployed on the same Tomcat instance could keep a reference to another app's request/response and read or tamper with cross-application data. Apache rated the issue Low, and its own advisory is explicit that exploitation depends on running an untrusted application under a SecurityManager on the affected instance.

The raw CVSS v3 score of 9.1 badly overstates most enterprise risk because it assumes a clean unauthenticated remote path that usually does not exist here. In real estates, this is post-deployment, same-instance, multi-tenant abuse: the attacker needs a way to get a hostile app onto the server and the deployment has to use Tomcat's SecurityManager model. For the typical single-app or same-trust-zone Tomcat deployment, Tenable's VPR Medium 5.2 is still too hot; this lands as LOW.

"Looks scary on paper, but it needs a hostile app already running inside your Tomcat."
02 · The Attack Path

4 steps from start to impact.

STEP 01

Land a hostile WAR on the target Tomcat

The attacker first needs to deploy a malicious Java web application containing crafted listener code. The practical weapon is just a custom WAR using standard Servlet listener APIs; there is no special exploit framework magic here. This is the decisive gate: without code running as a co-tenant on the same Tomcat, the CVE is inert.
Conditions required:
  • Attacker can deploy or influence a WAR on the same Tomcat instance
  • Tomcat version is 7.0.0-7.0.75
  • Target hosts multiple applications with different trust levels
Where this breaks in practice:
  • Requires prior compromise of CI/CD, Manager access, developer pipeline, or supply chain
  • Most enterprises do not allow arbitrary WAR deployment by untrusted users
  • Many Tomcat estates are single-purpose app servers, not hostile multi-tenant shared hosting
Detection/coverage: Version scanners will flag the package, but they do not validate whether a hostile deploy path exists. App-deployment auditing, Manager/Host-Manager logs, and build pipeline controls matter more than network scanning.
STEP 02

Abuse listener facade handling under SecurityManager

A malicious listener abuses the bug described in Apache's bug 60718 fix path so it can retain a non-facade request or response reference. That retained reference can later expose or modify data associated with another web application on the same instance. The implementation detail is fixed in Apache revision 1785777.
Conditions required:
  • Tomcat is running with a SecurityManager-enabled model relevant to this bug
  • The hostile app's listener code executes during request lifecycle events
Where this breaks in practice:
  • SecurityManager-dependent deployments are a minority pattern in enterprise Tomcat
  • Many modern deployments moved away from this shared-container trust model entirely
  • The attacker must write functioning Java listener code, not just send a malformed HTTP request
Detection/coverage: No mainstream remote scanner can prove exploitability here. Detection is mostly code review of deployed WARs, unusual listener classes, and runtime instrumentation of cross-context access.
STEP 03

Harvest or tamper with neighboring app traffic

Once the hostile app holds the wrong object reference, it can observe or alter information tied to another application on the same Tomcat instance. In practice this means session identifiers, request attributes, or response content becoming visible or modifiable across application boundaries. The impact is real, but the blast radius stays inside that shared Tomcat trust boundary.
Conditions required:
  • Victim and attacker-controlled apps share the same Tomcat instance
  • Cross-app request/response data of interest exists
Where this breaks in practice:
  • Impact is constrained to co-hosted apps on that one server/JVM
  • No direct OS-level code execution or server takeover follows from this CVE alone
  • Modern app isolation via separate JVMs, containers, or hosts kills the chain
Detection/coverage: Exploit telemetry is poor at the network layer. Look for anomalous session reuse, impossible cross-app behavior, and suspicious custom listener classes in deployed artifacts.
STEP 04

Pivot using stolen app context

If sensitive session material or response data is exposed, the attacker can chain that into application-level impersonation or data manipulation. This is where the business impact shows up, but it is a secondary effect that depends on what the co-hosted apps actually do. The CVE itself does not provide pre-auth internet compromise.
Conditions required:
  • Victim app uses data that can be abused if observed or modified
  • Attacker can reach the victim application's workflows after harvesting context
Where this breaks in practice:
  • Requires meaningful neighboring applications on the same instance
  • MFA, app-layer authorization, and session binding can reduce value of stolen context
  • Many environments have no untrusted neighboring app in the first place
Detection/coverage: Application logs and IAM telemetry may show session anomalies; Nessus alone will not.
03 · Intelligence Metadata

The supporting signals.

In-the-wild statusNo current evidence found that CVE-2017-5648 is in CISA KEV, and I found no public GreyNoise reporting tied to this specific CVE. Current KEV catalog review supports not KEV-listed as of today: CISA KEV Catalog.
PoC / exploit availabilityTenable marks "No known exploits are available" on plugin 121120, which fits the real-world friction here. Internet references claiming GitHub PoCs mostly point to CVE indexers rather than a mature weaponized exploit chain: Tenable plugin 121120, cvefeed entry.
EPSSTenable's CVE page currently shows EPSS 0.19005. That is not zero, but it is still a weak signal compared with remotely weaponized Tomcat bugs: Tenable CVE page.
KEV statusNot listed in the CISA Known Exploited Vulnerabilities catalog based on current catalog review. That matters because this CVE is old, high-profile on paper, and still has not shown the exploitation evidence threshold KEV requires: CISA KEV Catalog.
CVSS vector vs realityNVD scores it 9.1 / Critical with CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N, but Apache labels it Low because the real prerequisite is a malicious app already running under the right trust model. This is a textbook case of base CVSS ignoring deployment friction: NVD, Apache advisory.
Affected versionsApache states the bug affects Tomcat 7.0.0-7.0.75, plus 8.0.0.RC1-8.0.41, 8.5.0-8.5.11, and 9.0.0.M1-9.0.0.M17. Plugin 121120 is only the Tomcat 7 slice: Apache advisory, Tenable plugin 121120.
Fixed versions / backportsUpstream fix is 7.0.76+. Distros backported fixes long ago; for example Debian Jessie shows tomcat7 7.0.56-3+deb8u10, and Amazon Linux 1 fixed it via ALAS-2017-873 for tomcat7: Debian tracker, ALAS-2017-873.
Exposure / scanning realityTomcat as a platform is widely deployed and often internet-facing, but that does not translate into easy exposure for this CVE because the reachable population collapses once you add the same instance + untrusted app + SecurityManager prerequisites. Public internet inventories are therefore a poor proxy for exploitability here: HHS HC3 Tomcat sector alert, Censys Internet Map.
Disclosure timelineApache lists the issue as fixed on March 16, 2017 in 7.0.76; NVD publication is April 17, 2017. Use those exact dates when reconciling scanner age and exception handling: Apache advisory, NVD.
Reporter / root causeApache says the issue was noticed while investigating bug 60718; the weakness is tracked as CWE-668 Exposure of Resource to Wrong Sphere. This is about broken isolation between co-hosted apps, not internet-first RCE: Apache advisory, NVD/OpenCVE mirror data.
04 · The Call

noisgate verdict.

Final Verdict
DOWNGRADED to LOW (2.9/10)

The single biggest downward driver is that exploitation requires a hostile application already deployed on the same Tomcat instance; that is a post-initial-access or supply-chain condition, not an internet-first compromise path. Add the narrow SecurityManager prerequisite and the exposed population collapses from "all old Tomcat" to a much smaller multi-tenant subset.

HIGH Attack-path friction assessment
MEDIUM Current absence of public exploitation evidence
HIGH Affected-version and fix mapping for Tomcat 7

Why this verdict

  • Requires prior foothold: the attacker needs a way to deploy or influence a malicious WAR on the same Tomcat instance before this CVE matters.
  • SecurityManager narrows the population: Apache's own advisory ties exploitation to running an untrusted application under a SecurityManager, a far smaller real-world subset than raw version scanners imply.
  • Blast radius stays local to the shared container: impact is cross-application data exposure/tampering inside that Tomcat trust boundary, not direct host takeover or unauthenticated internet RCE.

Why not higher?

There is no clean unauthenticated remote exploit path from the internet to server compromise. The chain assumes either an earlier compromise stage, a malicious insider deployment path, or a shared-hosting model with untrusted co-tenants. Those are compounding friction points, not edge details.

Why not lower?

If you do run shared Tomcat with mixed-trust applications, the impact is not purely theoretical; request/response context crossing app boundaries can lead to session theft or application-level abuse. Older Tomcat 7 estates also correlate with weak operational hygiene, so this should still be cleaned up rather than ignored.

05 · Compensating Control

What to do — in priority order.

  1. Separate trust boundaries — Run applications from different teams or trust levels in separate Tomcat instances, JVMs, or containers. This kills the same-instance cross-app premise of the bug; for a LOW verdict there is no SLA (treat as backlog hygiene), so implement during normal platform hardening rather than emergency change windows.
  2. Lock down deployment paths — Restrict Tomcat Manager/Host-Manager, CI/CD publish rights, artifact repositories, and WAR upload paths to a tightly controlled admin set. This addresses the hardest exploit prerequisite directly; for LOW, fold it into standard access-governance work with no SLA (treat as backlog hygiene).
  3. Inventory SecurityManager usage — Find which Tomcat services actually start with -security or java.security.manager semantics and flag them as the only realistically exposed subset. For LOW, there is no SLA (treat as backlog hygiene), but this scoping step lets you close exceptions cleanly.
  4. Review deployed listeners — Enumerate WAR contents for custom ServletContextListener, ServletRequestListener, and related listener classes, especially on shared instances. Malicious or unexpected listener code is the exploit vehicle; for LOW, do this as part of routine app attestation and artifact review.
What doesn't work
  • A WAF does not solve this because the bug is not a malformed-request edge on the front door; it is abuse by already deployed server-side code.
  • Simple internet exposure reduction alone is insufficient. Useful generally, yes, but this CVE can still matter on internal shared Tomcat if an attacker already has app-deploy capability.
  • Blindly disabling SecurityManager removes this specific precondition but also removes a broader isolation control; that is not a sound compensating pattern unless you understand the rest of the platform risk.
06 · Verification

Crowdsourced verification payload.

Run this on the target host or from an admin workstation with filesystem access to the Tomcat install. Invoke it as python3 check_tomcat_cve_2017_5648.py /opt/tomcat or py check_tomcat_cve_2017_5648.py "C:\Tomcat7"; no root/admin is required unless the Tomcat directories are permission-restricted. The script reports VULNERABLE only when it finds a Tomcat version below 7.0.76 and evidence that SecurityManager mode is enabled; otherwise it returns PATCHED or UNKNOWN.

noisgate-verify.py
PYTHONREAD-ONLYSAFE
#!/usr/bin/env python3
# check_tomcat_cve_2017_5648.py
# Detect likely exposure to CVE-2017-5648 on an Apache Tomcat installation.
# Exit codes:
#   0 = PATCHED
#   1 = VULNERABLE
#   2 = UNKNOWN

import os
import re
import sys
from pathlib import Path

EXIT_PATCHED = 0
EXIT_VULN = 1
EXIT_UNKNOWN = 2


def read_text(path):
    try:
        return Path(path).read_text(encoding='utf-8', errors='ignore')
    except Exception:
        return ''


def parse_version_from_text(text):
    patterns = [
        r'Apache Tomcat Version\s*([0-9]+\.[0-9]+\.[0-9]+)',
        r'server\.info=Apache Tomcat/([0-9]+\.[0-9]+\.[0-9]+)',
        r'Apache Tomcat/([0-9]+\.[0-9]+\.[0-9]+)',
    ]
    for pat in patterns:
        m = re.search(pat, text, re.IGNORECASE)
        if m:
            return m.group(1)
    return None


def version_tuple(v):
    try:
        return tuple(int(x) for x in v.split('.'))
    except Exception:
        return None


def find_version(base):
    candidates = [
        base / 'RELEASE-NOTES',
        base / 'RUNNING.txt',
        base / 'webapps' / 'docs' / 'changelog.html',
        base / 'lib' / 'catalina.jar',  # fallback path indicator only
        base / 'bin' / 'version.sh',
        base / 'bin' / 'version.bat',
        base / 'lib' / 'org' / 'apache' / 'catalina' / 'util' / 'ServerInfo.properties',
    ]

    # Try common text files first.
    for c in candidates:
        if c.exists() and c.is_file():
            text = read_text(c)
            v = parse_version_from_text(text)
            if v:
                return v, str(c)

    # Search broadly but shallowly for ServerInfo.properties or RELEASE-NOTES.
    for root, _, files in os.walk(base):
        if len(Path(root).parts) - len(base.parts) > 5:
            continue
        for name in files:
            if name in ('RELEASE-NOTES', 'RUNNING.txt', 'ServerInfo.properties'):
                p = Path(root) / name
                text = read_text(p)
                v = parse_version_from_text(text)
                if v:
                    return v, str(p)
    return None, None


def security_manager_enabled(base):
    hints = []
    candidates = [
        base / 'bin' / 'catalina.sh',
        base / 'bin' / 'catalina.bat',
        base / 'bin' / 'setenv.sh',
        base / 'bin' / 'setenv.bat',
        base / 'conf' / 'catalina.policy',
        base / 'conf' / 'logging.properties',
    ]

    for c in candidates:
        if c.exists() and c.is_file():
            text = read_text(c)
            if re.search(r'(^|\s)-security(\s|$)', text, re.IGNORECASE):
                hints.append(f'{c}: contains -security')
            if re.search(r'java\.security\.manager', text, re.IGNORECASE):
                hints.append(f'{c}: contains java.security.manager')

    # Lightweight service file scan on Unix-like systems.
    for svc_dir in ('/etc/systemd/system', '/usr/lib/systemd/system', '/etc/init.d'):
        p = Path(svc_dir)
        if p.exists() and p.is_dir():
            for child in p.iterdir():
                if 'tomcat' in child.name.lower() and child.is_file():
                    text = read_text(child)
                    if re.search(r'(^|\s)-security(\s|$)', text, re.IGNORECASE):
                        hints.append(f'{child}: service contains -security')
                    if re.search(r'java\.security\.manager', text, re.IGNORECASE):
                        hints.append(f'{child}: service contains java.security.manager')

    return (len(hints) > 0), hints


def main():
    if len(sys.argv) != 2:
        print('UNKNOWN - Usage: python3 check_tomcat_cve_2017_5648.py <TOMCAT_HOME>')
        sys.exit(EXIT_UNKNOWN)

    base = Path(sys.argv[1])
    if not base.exists() or not base.is_dir():
        print(f'UNKNOWN - Path not found or not a directory: {base}')
        sys.exit(EXIT_UNKNOWN)

    version, source = find_version(base)
    if not version:
        print(f'UNKNOWN - Could not determine Tomcat version under {base}')
        sys.exit(EXIT_UNKNOWN)

    vt = version_tuple(version)
    if not vt:
        print(f'UNKNOWN - Parsed unusable version string: {version}')
        sys.exit(EXIT_UNKNOWN)

    fixed = (7, 0, 76)

    # Only assess Tomcat 7 here; plugin 121120 is specifically Tomcat 7.0.0 < 7.0.76.
    if vt[0] != 7:
        print(f'PATCHED - Detected Tomcat {version} from {source}; plugin 121120 applies to Tomcat 7 only')
        sys.exit(EXIT_PATCHED)

    if vt >= fixed:
        print(f'PATCHED - Detected Tomcat {version} from {source}; fixed in 7.0.76+')
        sys.exit(EXIT_PATCHED)

    sm_enabled, hints = security_manager_enabled(base)
    if sm_enabled:
        hint_text = '; '.join(hints[:5])
        print(f'VULNERABLE - Detected Tomcat {version} (< 7.0.76) and SecurityManager evidence: {hint_text}')
        sys.exit(EXIT_VULN)

    print(f'UNKNOWN - Detected Tomcat {version} (< 7.0.76) but found no clear SecurityManager evidence. Manually verify runtime startup flags (-security / java.security.manager).')
    sys.exit(EXIT_UNKNOWN)


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

If you remember one thing.

TL;DR
Monday morning: do not treat this like an internet-fire RCE just because CVSS says 9.1. First, scope where Tomcat 7.0.0-7.0.75 is actually running with SecurityManager and whether those hosts carry mixed-trust or customer-supplied apps; if not, document the exception and move on. Because this is a LOW noisgate verdict, there is no noisgate mitigation SLA and no noisgate remediation SLA beyond normal backlog hygiene: patch it on the next planned Tomcat maintenance cycle, and prioritize only the rare shared-instance, mixed-trust deployments for earlier cleanup.

Sources

  1. Tenable Nessus Plugin 121120
  2. Apache Tomcat 7 security page
  3. NVD CVE-2017-5648
  4. Ubuntu CVE-2017-5648
  5. Debian security tracker CVE-2017-5648
  6. Amazon Linux ALAS-2017-873
  7. CISA Known Exploited Vulnerabilities Catalog
  8. HHS HC3 Apache Tomcat Vulnerabilities Sector Alert
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.