Like a building with a trustworthy lobby sign that can still point visitors to a fake office upstairs
This finding maps to CVE-2018-11784 in Apache Tomcat's default servlet. Affected upstream Tomcat 7 versions are 7.0.23 through 7.0.90, fixed in 7.0.91 on 2018-09-19; the same flaw also affected Tomcat 8.5.0-8.5.33 and 9.0.0.M1-9.0.11. The issue is an open redirect: when Tomcat redirects a slashless directory request like /foo to /foo/, a crafted URL can make Tomcat send the victim somewhere attacker-controlled instead.
Tenable's MEDIUM / 4.3 baseline is technically fair, but operationally this is lower for most enterprises because it does not give code execution, data theft from the server, or auth bypass on Tomcat itself. The real impact is brand-trust abuse and phishing leverage against users, which matters most on internet-facing portals with user traffic; on internal-only or API-only Tomcat, the practical risk collapses fast.
4 steps from start to impact.
Fingerprint an affected Tomcat
curl, Nessus plugin 118035, or generic web fingerprinting; no exploit logic is needed yet.- The Tomcat service is reachable from the attacker or from a target user population
- Version or behavioral clues are exposed
- Many enterprises hide version banners behind reverse proxies
- Tenable's plugin is explicitly version-based and may overreport where distro backports exist
Find a redirectable directory path
nuclei-templates include a check for this behavior.- A suitable directory path exists and is handled by the default servlet
- The application or proxy does not already canonicalize the path safely
- Custom apps, reverse proxies, or frameworks often absorb routing before Tomcat's default servlet handles it
- Many deployments expose only app endpoints, not browsable static directory paths
Weaponize the redirect
302 or similar redirect to an attacker-chosen URI. This is an open redirect primitive, useful for phishing chains, token-stealing pretext, or security-control bypasses that naively trust same-brand URLs.- The target application is user-facing
- The victim can be induced to click the crafted link
- Modern email gateways, browser safebrowsing, and user training reduce click-through
- The bug does not execute on the server; impact depends on downstream social engineering success
Convert user trust into impact
- A user is exposed to the malicious link
- The downstream malicious site is live and believable
- Requires user interaction by design; no click, no impact
- MFA, SSO protections, web filtering, and browser reputation checks can break the chain
The supporting signals.
| Primary CVE | CVE-2018-11784 — Apache Tomcat default servlet open redirect |
|---|---|
| In-the-wild status | I found no CISA KEV listing and no strong evidence of broad, server-compromise campaigns tied to this CVE. CISA published an alert on 2018-10-04, but it was a standard patch notice, not an exploitation bulletin. |
| PoC / scanner availability | Public material exists: Packet Storm published a PoC/advisory reference, and ProjectDiscovery's nuclei-templates added cves/2018/CVE-2018-11784.yaml, so discovery is easy even if weaponization is low-drama. |
| EPSS | Tenable's CVE page reports EPSS 0.8217. That's high for a bug this operationally limited, which is a good reminder that EPSS can reflect scanner chatter and exploit discussion more than defender-relevant blast radius. |
| KEV status | Not present in the CISA Known Exploited Vulnerabilities catalog in the queried results. |
| CVSS vector | CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:L/A:N = network reachable, no auth required, but user interaction is required and server-side impact is limited to low integrity. |
| Affected versions | Upstream Tomcat 7.0.23-7.0.90 are affected; Apache rates the issue Moderate in the Tomcat 7 advisory. Tomcat 8.5.0-8.5.33 and 9.0.0.M1-9.0.11 were also affected upstream. |
| Fixed versions / backports | Upstream fix is 7.0.91. Distro backports exist: Ubuntu shows trusty tomcat7 fixed in 7.0.52-1ubuntu0.16, and Red Hat JBoss Web Server backported fixes into packages such as tomcat7-7.0.70-31.ep7.el7 under RHSA-2019:0131. |
| Scanning / exposure notes | The Tenable plugin is version-only and can overstate exposure where vendor backports are present. I did not retrieve authoritative current GreyNoise/Shodan/Censys counts for this exact CVE, so don't mistake internet-exposed Tomcat population for confirmed exploitability of this redirect behavior. |
| Disclosure timeline | Apache lists the fix in Tomcat 7.0.91 on 2018-09-19; NVD and Ubuntu show public disclosure on 2018-10-04; Tenable published plugin 118035 on 2018-10-10. |
noisgate verdict.
The decisive factor is required user interaction: this bug does not compromise the Tomcat host by itself and only becomes useful when an attacker can trick a victim into following a crafted link. That sharply limits blast radius compared with remotely exploitable server bugs, even though the service may be internet-facing.
Why this verdict
- Downgrade from vendor MEDIUM: vendor CVSS says 4.3, but the chain ends at a redirect, not code execution, auth bypass, or data exposure from Tomcat.
- User interaction is mandatory: the CVSS vector itself includes
UI:R, which means the attacker still needs a person to click and trust the URL. - Reachable population narrows fast in real deployments: many Tomcat instances sit behind reverse proxies, custom routing, or internal-only apps where this default-servlet path normalization never becomes a useful phishing primitive.
Why not higher?
There is no host takeover here. No RCE, no file read, no session break, no privilege gain, and no unauthenticated state change on the Tomcat server. Even on public portals, impact usually depends on a second-stage social-engineering success, which is not enough to justify HIGH.
Why not lower?
It is still a real vulnerability on user-facing branded infrastructure. Open redirects can materially improve phishing credibility, can occasionally help bypass weak allowlists or redirect-based workflows, and public detection content makes validation easy. So this is not noise; it's just not urgent security fire.
What to do — in priority order.
- Normalize redirects at the edge — Have the reverse proxy or load balancer canonicalize slashless directory requests safely and block external
Locationtargets where feasible. For a LOW verdict there is no SLA; treat this as standard hardening during normal change windows. - Constrain outbound redirects — In app code and gateway rules, allow redirects only to relative paths or an explicit host allowlist. This reduces abuse of trusted domains for phishing and is appropriate as backlog hygiene for a LOW issue.
- Hunt for suspicious external
Locationheaders — Review web logs and proxy telemetry for slashless directory requests that produce redirects to off-domain destinations. This is mainly useful on customer-facing portals and can be folded into routine detection engineering with no expedited deadline for a LOW verdict. - Fix scanner truth before fixing hosts — Validate whether the finding is an upstream Tomcat build or a distro-backported package such as Ubuntu or Red Hat JBoss Web Server. Tenable's plugin is version-driven, so clean triage avoids wasting maintenance windows on already-fixed backports.
- EDR on the Tomcat host doesn't solve the primary risk, because the server usually isn't being compromised at all.
- MFA on admin logins doesn't remove the redirect primitive; it only helps if the attacker is using the bug as part of a phishing chain.
- Closing the Manager app is irrelevant unless your exposure somehow depends on that interface; this bug lives in the default servlet redirect behavior.
Crowdsourced verification payload.
Run this on the target Tomcat host as a regular user with read access to the Tomcat install or package database. Invoke it as bash check_tomcat_cve_2018_11784.sh /opt/tomcat or with no argument to let it search common locations; it returns 0 PATCHED, 1 VULNERABLE, 2 UNKNOWN.
#!/usr/bin/env bash
# check_tomcat_cve_2018_11784.sh
# Detect likely exposure to CVE-2018-11784 for Apache Tomcat 7.
# Exit codes: 0=PATCHED, 1=VULNERABLE, 2=UNKNOWN
set -u
TARGET_PATH="${1:-}"
TOMCAT_VERSION=""
PKG_HINT=""
ver_lt() {
[ "$(printf '%s\n%s\n' "$1" "$2" | sort -V | head -n1)" != "$2" ]
}
ver_ge() {
[ "$(printf '%s\n%s\n' "$1" "$2" | sort -V | head -n1)" = "$2" ]
}
find_tomcat_base() {
local candidates=()
[ -n "$TARGET_PATH" ] && candidates+=("$TARGET_PATH")
candidates+=("$CATALINA_HOME" "$CATALINA_BASE" "/opt/tomcat" "/usr/share/tomcat" "/usr/share/tomcat7" "/var/lib/tomcat7" "/opt/rh/jws3/root/usr/share/tomcat")
for d in "${candidates[@]}"; do
[ -n "${d:-}" ] || continue
if [ -f "$d/lib/catalina.jar" ] || [ -f "$d/bin/version.sh" ]; then
echo "$d"
return 0
fi
done
return 1
}
get_version_from_manifest() {
local base="$1"
local jar="$base/lib/catalina.jar"
[ -f "$jar" ] || return 1
if command -v unzip >/dev/null 2>&1; then
unzip -p "$jar" META-INF/MANIFEST.MF 2>/dev/null | awk -F': ' '/Implementation-Version:/ {print $2; exit}'
return 0
elif command -v jar >/dev/null 2>&1; then
local tmp
tmp=$(mktemp -d)
(cd "$tmp" && jar xf "$jar" META-INF/MANIFEST.MF >/dev/null 2>&1 && awk -F': ' '/Implementation-Version:/ {print $2; exit}' META-INF/MANIFEST.MF)
rm -rf "$tmp"
return 0
fi
return 1
}
check_backports() {
# Ubuntu trusty fixed backport noted by Ubuntu security tracker
if command -v dpkg-query >/dev/null 2>&1; then
local dpkg_ver
dpkg_ver=$(dpkg-query -W -f='${Version}' tomcat7 2>/dev/null || true)
if [ -n "$dpkg_ver" ]; then
PKG_HINT="dpkg tomcat7=$dpkg_ver"
if command -v dpkg --compare-versions >/dev/null 2>&1; then
if dpkg --compare-versions "$dpkg_ver" ge "7.0.52-1ubuntu0.16"; then
echo "PATCHED: recognized Ubuntu/Debian package backport ($PKG_HINT)"
exit 0
fi
fi
fi
fi
# Red Hat JBoss Web Server 3.1 backport noted by RHSA-2019:0131
if command -v rpm >/dev/null 2>&1; then
local rpm_ver
rpm_ver=$(rpm -q --qf '%{VERSION}-%{RELEASE}' tomcat7 2>/dev/null || true)
if [ -n "$rpm_ver" ] && [ "$rpm_ver" != "package tomcat7 is not installed" ]; then
PKG_HINT="rpm tomcat7=$rpm_ver"
if rpmdev-vercmp >/dev/null 2>&1; then
:
fi
if [ "$rpm_ver" = "7.0.70-31.ep7.el7" ] || [ "$rpm_ver" = "7.0.70-31.ep7.el6" ] || [ "$rpm_ver" \
= "7.0.70-31.ep7.el7.noarch" ] || [ "$rpm_ver" = "7.0.70-31.ep7.el6.noarch" ]; then
echo "PATCHED: recognized Red Hat JBoss Web Server backport ($PKG_HINT)"
exit 0
fi
fi
fi
}
main() {
check_backports
local base
base=$(find_tomcat_base || true)
if [ -z "$base" ]; then
echo "UNKNOWN: could not locate Tomcat installation or recognized packaged backport"
exit 2
fi
TOMCAT_VERSION=$(get_version_from_manifest "$base" | tr -d '\r' || true)
if [ -z "$TOMCAT_VERSION" ] && [ -x "$base/bin/version.sh" ]; then
TOMCAT_VERSION=$(
CATALINA_HOME="$base" CATALINA_BASE="$base" "$base/bin/version.sh" 2>/dev/null | \
awk -F': ' '/Server version:/ {print $2}' | sed -E 's/.*Tomcat\/([0-9.]+).*/\1/' | head -n1
)
fi
if [ -z "$TOMCAT_VERSION" ]; then
echo "UNKNOWN: Tomcat found at $base but version could not be determined"
exit 2
fi
case "$TOMCAT_VERSION" in
7.*)
if ver_ge "$TOMCAT_VERSION" "7.0.23" && ver_lt "$TOMCAT_VERSION" "7.0.91"; then
echo "VULNERABLE: upstream Tomcat version $TOMCAT_VERSION at $base is in 7.0.23-7.0.90"
exit 1
elif ver_ge "$TOMCAT_VERSION" "7.0.91"; then
echo "PATCHED: upstream Tomcat version $TOMCAT_VERSION at $base is >= 7.0.91"
exit 0
else
echo "PATCHED: upstream Tomcat version $TOMCAT_VERSION predates the affected 7.0.23 range"
exit 0
fi
;;
8.*|9.*|10.*|11.*)
echo "UNKNOWN: script is scoped to the Tenable 7.x finding; detected Tomcat $TOMCAT_VERSION at $base"
exit 2
;;
*)
echo "UNKNOWN: unrecognized Tomcat version string '$TOMCAT_VERSION' at $base"
exit 2
;;
esac
}
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.