This is a tenant peeking through the landlord's mailroom window, not a burglar kicking in the front door
The finding maps to CVE-2015-5174. In Apache Tomcat 7.0.0 through 7.0.64, a path validation bug lets code running inside a webapp call ServletContext.getResource() / getResourceAsStream() / getResourcePaths() with "/.." and get a directory listing of the parent deployment directory. Apache is explicit that this only matters when you are running untrusted web applications under a Java SecurityManager; the usual exposure is disclosure of $CATALINA_BASE/webapps, not arbitrary file read or code execution.
The scanner's MEDIUM label overstates real enterprise risk. Apache itself rated it Low, and that is the right instinct: the attacker typically needs to have already crossed a much bigger line first by deploying or controlling an app on the target Tomcat instance. In most enterprise fleets, Tomcat is not used as hostile multi-tenant shared hosting, and Java SecurityManager-based sandboxing is uncommon enough that the reachable population is narrow before the bug even starts to matter.
4 steps from start to impact.
Gain code execution inside a deployed webapp
- Authenticated remote access to deploy or modify an application, or prior compromise of an app on the Tomcat host
- Shared Tomcat instance hosting more than one relevant application
- Target is Apache Tomcat 7.x in the vulnerable range
- Requiring app deployment/control is already a substantial breach stage
- Many enterprises run one app per instance/container, which kills the cross-app value
- Tomcat 7 is legacy and the exact multi-tenant pattern is not common in modern estates
webapps/ should catch the prerequisite more reliably than vulnerability scanning catches the exploit.Rely on SecurityManager sandboxing being enabled
"/..".- Java SecurityManager is enabled for Tomcat
- The deployment model assumes the SecurityManager is providing isolation between applications
- SecurityManager-based isolation is niche in enterprise Tomcat deployments
- If you are not using untrusted multi-tenant apps, the boundary being bypassed often has no practical attacker value
Trigger the limited traversal primitive
ServletContext resource methods with a path of "/..". Apache notes this is limited: "/../" was already rejected, and the practical result is typically a listing of the parent deployment directory, not broad arbitrary traversal.- Application code can invoke the affected
ServletContextAPIs - Tomcat version is 7.0.0 through 7.0.64
- The primitive is narrow and leaks metadata, not immediate full file contents
- Exploded deployment directories make it more useful; packed or isolated layouts reduce impact
Use the directory listing as second-stage recon
$CATALINA_BASE/webapps. That can support lateral movement or targeted follow-on abuse, but this CVE alone does not grant arbitrary file read, integrity loss, or code execution.- There are other interesting applications or artifacts in the parent deployment directory
- The attacker has a follow-on weakness to exploit using the newly learned paths
- Requires a separate second-stage bug or secret exposure to become materially worse
- Single-app instances or per-app containers collapse the blast radius
The supporting signals.
| In-the-wild status | I found no CISA KEV listing and no credible public reporting of active campaigns abusing this specific CVE as of 2025-06-04. |
|---|---|
| PoC availability | There is a public Packet Storm reference linked from NVD/Tenable, but this is a niche sandbox-bypass/info-leak primitive, not a broadly weaponized internet exploit chain. |
| EPSS | 0.30% (~53rd percentile) in the CVE Details snapshot, which is low and consistent with limited attacker demand. |
| KEV status | Not listed in the CISA Known Exploited Vulnerabilities Catalog as checked on 2025-06-04. |
| CVSS view | CVSS 3.0 4.3 / CVSS:3.0/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N. Translation: network reachable in theory, but it still needs low privileges / authenticated control and only yields low confidentiality impact. |
| Affected versions | Upstream Apache says Tomcat 7.0.0 to 7.0.64 are affected by CVE-2015-5174. |
| Fixed version | Upstream fix is Apache Tomcat 7.0.65. Distro builds may be fixed via backports without reporting 7.0.65 literally, so package provenance matters. |
| Backport examples | Debian tracker shows wheezy tomcat6 fixed in 6.0.45+dfsg-1~deb7u1; Ubuntu addressed related Tomcat packages in USN-3024-1. Do not treat raw upstream version strings as authoritative on packaged systems. |
| Exposure/scanning reality | CVE Details surfaces SecurityScorecard data showing broad internet association, but that is a coarse version/exposure signal and does not prove the rare SecurityManager + untrusted-app prerequisite is present. |
| Disclosure / reporter | Apache says the issue was identified by the Tomcat Security Team on 2015-08-12 and made public on 2016-02-22. |
noisgate verdict.
The single biggest downward pressure is that exploitation typically requires the attacker to already control or deploy a webapp on the target Tomcat instance. That makes this a post-initial-access, narrow-blast-radius sandbox leak, not a frontline remote compromise issue.
Why this verdict
- Major friction: attacker needs app control first — this is not a clean unauthenticated edge exploit; it assumes authenticated deployment rights or an already-compromised app.
- Population narrows again with SecurityManager — Apache explicitly scopes impact to deployments running untrusted webapps under a SecurityManager, a pattern that is uncommon in modern enterprise application hosting.
- Impact is bounded — the primitive usually exposes a parent directory listing like
$CATALINA_BASE/webapps, which is useful recon but not arbitrary file read or code execution by itself. - Vendor baseline is inflated for operations — a scanner's generic MEDIUM is understandable from raw CVSS mechanics, but it ignores that the path to exploitation starts after a bigger compromise milestone.
Why not higher?
It is not higher because this is not an internet-edge RCE, not a credential bypass, and not even a general file-read primitive. The chain depends on rare deployment assumptions: shared Tomcat hosting, untrusted apps, SecurityManager isolation, and an attacker who already has application-level foothold.
Why not lower?
It is not IGNORE because the bug does break an intended sandbox boundary, and in the specific shared-hosting model it can leak deployment structure for neighboring apps. If you actually run adversarial or separately managed tenants on one Tomcat instance, that is a real cross-app isolation failure.
What to do — in priority order.
- Restrict deployment rights — Lock down Tomcat Manager, CI/CD service accounts, and filesystem write paths so only tightly scoped admins can deploy or modify applications. For a LOW verdict there is no SLA (treat as backlog hygiene), but this is the single best control because it removes the prerequisite the attacker really needs.
- Isolate applications per instance — Move away from shared multi-app Tomcat where feasible so one compromised app cannot enumerate sibling deployments. For LOW, there is no mitigation SLA; fold this into platform hardening and modernization work rather than an emergency change.
- Verify package backports before chasing versions — On distro-managed systems, check the package advisory rather than only the upstream
7.0.65string, because vendor backports may already contain the fix. For LOW, do this during normal vulnerability review and backlog hygiene. - Watch
webapps/for drift — File integrity monitoring and EDR on deployed WARs/JSPs and exploded app directories catch the real dangerous event here: unauthorized app deployment or modification. Again, LOW means no formal mitigation deadline, but the control is high-value broadly.
- A WAF does not meaningfully solve this because the vulnerable action is typically performed by malicious application code already running inside Tomcat, not by a distinctive external request pattern.
- Generic network ACLs only help if they prevent the earlier deployment foothold; they do not stop one already-running webapp from asking Tomcat for the parent directory listing.
- Hardening TLS/ciphers is irrelevant to this flaw; the weakness is path validation inside Tomcat's application resource handling.
Crowdsourced verification payload.
Run this on the target Tomcat host as a user with read access to the Tomcat install. Invoke it with the Tomcat base path, for example: bash check_cve_2015_5174.sh /opt/tomcat. It needs no root privileges, but distro-packaged/backported builds may return UNKNOWN by design.
#!/usr/bin/env bash
# check_cve_2015_5174.sh
# Detects likely exposure to CVE-2015-5174 for Apache Tomcat 7.x
# Exit codes: 0=PATCHED, 1=VULNERABLE, 2=UNKNOWN
set -u
TARGET="${1:-${CATALINA_HOME:-}}"
if [[ -z "$TARGET" ]]; then
echo "UNKNOWN - usage: $0 /path/to/tomcat"
exit 2
fi
if [[ ! -d "$TARGET" ]]; then
echo "UNKNOWN - target path does not exist: $TARGET"
exit 2
fi
get_version() {
local base="$1"
local out=""
if [[ -x "$base/bin/version.sh" ]]; then
out=$("$base/bin/version.sh" 2>/dev/null | awk -F': ' '/Server number/ {print $2; exit}')
if [[ -n "$out" ]]; then
echo "$out"
return 0
fi
fi
local jar=""
for jar in "$base/lib/catalina.jar" "$base/server/lib/catalina.jar"; do
if [[ -f "$jar" ]]; then
out=$(unzip -p "$jar" META-INF/MANIFEST.MF 2>/dev/null | awk -F': ' '/Implementation-Version/ {print $2; exit}')
if [[ -n "$out" ]]; then
echo "$out"
return 0
fi
fi
done
return 1
}
ver=$(get_version "$TARGET") || {
echo "UNKNOWN - could not determine Tomcat version from $TARGET"
exit 2
}
ver=$(echo "$ver" | tr -d '\r' | xargs)
# Distro/backport hinting: raw upstream comparison is unsafe when suffixes are present.
if [[ "$ver" =~ [+-] || "$ver" =~ (deb|el|ubuntu|redhat|amzn|suse|dfsg) ]]; then
echo "UNKNOWN - version '$ver' looks distro-packaged/backported; verify package advisory instead"
exit 2
fi
if [[ ! "$ver" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "UNKNOWN - unrecognized version format: $ver"
exit 2
fi
IFS='.' read -r major minor patch <<< "$ver"
# This check is scoped to Tomcat 7.x because the finding presented is Tenable plugin 121117.
if [[ "$major" != "7" ]]; then
echo "UNKNOWN - detected Tomcat $ver; this script is scoped to Tomcat 7.x"
exit 2
fi
if (( minor != 0 )); then
echo "UNKNOWN - unexpected Tomcat 7 minor version format: $ver"
exit 2
fi
if (( patch < 65 )); then
echo "VULNERABLE - Tomcat version $ver is earlier than 7.0.65"
exit 1
else
echo "PATCHED - Tomcat version $ver is 7.0.65 or later"
exit 0
fi
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.