Someone left a back door in the attic of a house that was bricked shut at the factory
CVE-2025-46701 is an improper case-sensitivity handling flaw (CWE-178) in Apache Tomcat's CGI servlet. By manipulating the letter casing of the pathInfo component of a URI mapped to the CGI servlet, an unauthenticated attacker can bypass security constraints that would normally gate access to CGI resources. The bug spans an enormous version range — 9.0.0.M1 through 9.0.104, plus equivalent ranges in 10.1.x, 11.0.x, and the EOL 8.5.x branch — which is why scanners light up on nearly every unpatched Tomcat instance. Fixed in 9.0.105, 10.1.41, and 11.0.7.
Tenable stamps this Medium (CVSS v3.1 7.3 / CVSS v4.0 6.3). That overstates real-world risk dramatically. Apache's own advisory rates it Low. The decisive fact: the CGI servlet is disabled by default and has been for years. It exists to run legacy Perl/Python/shell scripts behind Tomcat — a pattern that was niche in 2010 and is vanishingly rare in 2026 Java deployments. Even among the ~100K internet-facing Tomcat instances visible on Shodan, the fraction serving CGI endpoints is negligible. The bypass yields partial confidentiality and integrity impact (CVSS C:L/I:L/A:L) — not RCE, not privilege escalation. This is a scan-noise CVE for 99%+ of enterprises.
4 steps from start to impact.
Identify Tomcat with CGI servlet enabled
cgi servlet and cgi servlet-mapping in web.xml, or equivalent programmatic registration. This is a non-default configuration. Without this step, the entire chain is dead.- Tomcat instance reachable over HTTP/HTTPS
- CGI servlet explicitly enabled in
web.xml(disabled by default)
- CGI servlet has been disabled by default for all supported Tomcat branches
- Modern Java apps use servlets/JSP/Spring — CGI is legacy and extremely uncommon
- Enterprise hardening guides (CIS Benchmark for Tomcat) explicitly remove CGI servlet config
Map CGI-protected resources
<security-constraint> entries in web.xml. The constraints must specifically apply to the pathInfo portion of the CGI URI, not to the servlet path itself. This is a narrow configuration pattern.- CGI servlet maps to a known URL pattern (e.g.,
/cgi-bin/*) - Security constraints are applied to pathInfo sub-paths of the CGI mapping
- Most CGI configurations use broad wildcard constraints or network-layer ACLs, not fine-grained pathInfo constraints
- Many deployments protect CGI with IP allowlists or reverse-proxy rules instead of Tomcat security constraints
Craft case-manipulated URI
pathInfo segment (e.g., /cgi-bin/Admin/secret.cgi becomes /cgi-bin/ADMIN/secret.cgi). Due to CWE-178, the security constraint matcher fails to match the case-altered path, while the underlying OS (particularly Windows with case-insensitive filesystems) still resolves the CGI script.- Case-insensitive filesystem (Windows) or case-insensitive CGI script resolution
- Security constraint uses exact or case-sensitive pattern matching on pathInfo
- Linux/macOS filesystems are case-sensitive by default — the altered-case path would 404 unless the CGI runtime itself is case-insensitive
- On case-sensitive systems, the bypass is a self-DoS — the script simply isn't found
- Impact is limited to accessing the CGI resource — no RCE, no shell, no privilege escalation
Access protected CGI resource
- The protected CGI resource performs a security-sensitive action
- CGI scripts in modern deployments are overwhelmingly simple utility scripts, not admin panels
- Even if accessed, the script runs with Tomcat's process permissions — no privilege escalation beyond the Tomcat service account
The supporting signals.
| In-the-Wild Exploitation | None observed. Not listed on CISA KEV. No known campaigns. Apache rates severity as Low. |
|---|---|
| Proof of Concept | No public PoC. Tenable marks exploit availability but no named repos or researchers have published working exploit code. The bypass is trivially conceptual (change letter case in URL) but requires the rare CGI-enabled config to be useful. |
| EPSS Score | 2.93% (86th percentile) — moderate probability band, reflecting the wide version range more than actual exploitability. |
| KEV Status | Not listed. No CISA KEV entry as of 2026-09-17. |
| CVSS v3.1 Vector | CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:L — Network-accessible, no auth, but only Low impact across all three pillars. The 7.3 score is mechanically inflated by the no-auth/no-interaction base metrics. |
| CVSS v4.0 Score | 6.3 (Medium) per Tenable; 1.7 (Low) per GHSA with E:U (exploit maturity unreported) and AT:P (attack prerequisites). |
| Affected Versions | 9.0.0.M1–9.0.104, 10.1.0.M1–10.1.40, 11.0.0.M1–11.0.6, 8.5.0–8.5.100 (EOL) |
| Fixed Versions | 9.0.105, 10.1.41, 11.0.7. Distro backports: check RHEL/Debian/Ubuntu advisories for JWS and tomcat9 packages. |
| Scanning / Exposure | Shodan indexes ~100K internet-facing Tomcat instances globally. The fraction with CGI servlet enabled is not separately tracked but is estimated at well under 1% based on the feature being disabled by default and deprecated in modern Java stacks. |
| Disclosure | Reported to Apache 2025-05-14. Fixed 2025-05-26. Public disclosure 2025-05-29. Researcher not publicly credited. |
noisgate verdict.
The single most decisive factor is that the CGI servlet is disabled by default in all supported Tomcat branches, reducing the reachable population to a negligible fraction of the installed base. Even where enabled, the bypass yields only partial C/I/A impact against a legacy feature with no path to RCE or privilege escalation.
Why this verdict
- Disabled by default: The CGI servlet must be explicitly enabled in
web.xml. It has been off by default across all Tomcat branches for years. CIS Benchmarks for Tomcat explicitly recommend removing it. This single prerequisite eliminates >99% of deployments from the vulnerable population. - Low blast radius even when exploitable: The CVSS impact is C:L/I:L/A:L — partial read, partial tamper, partial availability. There is no path to RCE, shell access, or privilege escalation. The attacker accesses whatever the CGI script does, bounded by the Tomcat service account.
- Platform friction compounds: The case-sensitivity bypass is most effective on Windows (case-insensitive FS). On Linux — where the majority of Tomcat instances run — the altered-case path simply 404s, making the bug a non-issue on the dominant platform.
- Role multiplier: Tomcat occupies high-value roles (app tier for identity apps, CI/CD frontends, production APIs). However, in those roles the CGI servlet is effectively never enabled — these are Java servlet/Spring deployments. The high-value-role floor does not apply because the vulnerable component (CGI servlet) is architecturally absent from high-value Tomcat deployments. No realistic high-value-role chain succeeds.
- No threat signal: Not on KEV, no campaigns, no public PoC, EPSS at 86th percentile (moderate). Apache themselves rate this Low.
Why not higher?
There is no evidence of exploitation, no public PoC, and the prerequisite (CGI servlet enabled) is absent from default configurations and virtually all modern Tomcat deployments. The impact ceiling is partial — no RCE, no privilege escalation, no data exfiltration path beyond what the CGI script itself exposes. Raising this to MEDIUM would overstate risk for a feature that >99% of defenders don't have enabled.
Why not lower?
The bug is real, the version range is vast, and the EPSS score is not trivial at the 86th percentile. A small number of legacy deployments — particularly Windows-hosted Tomcat instances running CGI scripts for backward compatibility — are genuinely exposed. An IGNORE verdict would be inappropriate because those edge-case environments need to patch. LOW correctly signals backlog-priority remediation.
What to do — in priority order.
- Confirm CGI servlet is disabled — Verify that the
cgiservlet definition andcgiservlet-mapping are commented out or absent in$CATALINA_HOME/conf/web.xmland all application-levelweb.xmlfiles. If CGI is not enabled, you are not vulnerable — document this and close the finding. No mitigation SLA applies at LOW severity. - If CGI is enabled: restrict by IP at the reverse proxy — If you genuinely need the CGI servlet, block external access to
/cgi-bin/*(or your CGI URL pattern) at the reverse proxy (nginx, Apache httpd, F5) or WAF. This is a compensating control until you can patch within the noisgate remediation SLA for LOW (backlog). - Normalize URI case at the WAF/proxy — Configure your WAF or reverse proxy to lowercase-normalize all inbound URI paths before forwarding to Tomcat. This neutralizes the case-manipulation bypass regardless of Tomcat version.
- Patch to 9.0.105+ — The definitive fix. Roll this into your next scheduled Tomcat maintenance window. At LOW severity, treat as backlog hygiene — no hard deadline, but don't let it rot past your next quarterly patch cycle.
- Disabling
enableCmdLineArguments— This parameter (already off by default) prevents a *different* CGI vulnerability (CVE-2019-0232 RCE). It does not affect the case-sensitivity constraint bypass in CVE-2025-46701. - Network segmentation alone — If the Tomcat instance is reachable by users/clients who should be constrained by the bypassed security rule, network segmentation doesn't help; the attacker is an authorized network participant exploiting an authorization bypass.
- Java Security Manager — Deprecated since Java 17 and removed in Java 24. Even when active, it constrains the CGI process permissions but does not fix the constraint-bypass logic in Tomcat's URI matcher.
Crowdsourced verification payload.
Run on each Tomcat host (Linux/macOS) or from an auditor workstation with SSH access. Requires read access to $CATALINA_HOME. Example: bash check_cve_2025_46701.sh /opt/tomcat. No root needed.
#!/usr/bin/env bash
# check_cve_2025_46701.sh — CVE-2025-46701 exposure check
# Usage: bash check_cve_2025_46701.sh /path/to/catalina_home
# Exit codes: 0 = PATCHED/NOT_VULNERABLE, 1 = VULNERABLE, 2 = UNKNOWN
set -euo pipefail
CATALINA_HOME="${1:?Usage: $0 /path/to/catalina_home}"
VERSION_FILE="$CATALINA_HOME/lib/catalina.jar"
WEB_XML="$CATALINA_HOME/conf/web.xml"
# --- Detect Tomcat version ---
if [ ! -f "$VERSION_FILE" ]; then
echo "UNKNOWN — catalina.jar not found at $VERSION_FILE"
exit 2
fi
VERSION=$(unzip -p "$VERSION_FILE" org/apache/catalina/util/ServerInfo.properties 2>/dev/null \
| grep '^server.number=' | cut -d= -f2 | tr -d '[:space:]')
if [ -z "$VERSION" ]; then
echo "UNKNOWN — could not extract Tomcat version"
exit 2
fi
echo "Detected Tomcat version: $VERSION"
# --- Version comparison (9.x branch only) ---
MAJOR=$(echo "$VERSION" | cut -d. -f1)
MINOR=$(echo "$VERSION" | cut -d. -f2)
PATCH=$(echo "$VERSION" | cut -d. -f3)
PATCHED=0
if [ "$MAJOR" -eq 9 ] && [ "$MINOR" -eq 0 ]; then
[ "$PATCH" -ge 105 ] && PATCHED=1
elif [ "$MAJOR" -eq 10 ] && [ "$MINOR" -eq 1 ]; then
[ "$PATCH" -ge 41 ] && PATCHED=1
elif [ "$MAJOR" -eq 11 ]; then
[ "$MINOR" -gt 0 ] && PATCHED=1
[ "$MINOR" -eq 0 ] && [ "$PATCH" -ge 7 ] && PATCHED=1
elif [ "$MAJOR" -gt 11 ]; then
PATCHED=1
fi
# --- Check CGI servlet enablement ---
CGI_ENABLED=0
if [ -f "$WEB_XML" ]; then
# Look for uncommented cgi servlet-class definition
if grep -q '<servlet-class>org.apache.catalina.servlets.CGIServlet</servlet-class>' "$WEB_XML" 2>/dev/null; then
# Make sure it's not inside a comment block (rough check)
if ! grep -B5 'CGIServlet' "$WEB_XML" | grep -q '<!--'; then
CGI_ENABLED=1
fi
fi
fi
# --- Verdict ---
if [ "$PATCHED" -eq 1 ]; then
echo "PATCHED — Tomcat $VERSION is at or above the fixed version."
exit 0
elif [ "$CGI_ENABLED" -eq 0 ]; then
echo "PATCHED — Tomcat $VERSION is below fixed version BUT CGI servlet is not enabled. Not exploitable."
exit 0
else
echo "VULNERABLE — Tomcat $VERSION with CGI servlet ENABLED. Patch to 9.0.105+ / 10.1.41+ / 11.0.7+."
exit 1
fiIf you remember one thing.
Sources
What defenders are saying.
Crowdsourced verification outputs.
Results submitted by users who ran the verification payload against their environment.