A bouncer who stops checking IDs as soon as one person in a group flashes a valid one
CVE-2026-53404 is a control-flow bug in Apache Tomcat's RewriteValve — the optional URL rewriting filter modeled on Apache httpd's mod_rewrite. When a RewriteRule is guarded by a chain of RewriteCond directives that mixes [OR] flags and plain (AND) conditions, the valve short-circuits the moment the first OR condition matches and never evaluates the remaining AND conditions. The rewrite then fires even though the full predicate was never satisfied. Affected: Tomcat 11.0.0-M1 through 11.0.22 and Tomcat 9.0.0.M1 through 9.0.118. Fixed in 11.0.23 / 9.0.119 (commits b647cb58 and fe06ae8a).
Apache marked this Low, and that's the right call. The bug only manifests if (a) you've enabled the rewrite valve at all — it ships off by default — and (b) your rewrite.config actually mixes [OR]-flagged and unflagged conditions guarding a single rule, AND (c) one of those conditions is acting as a security gate (e.g., requiring an internal IP or specific Host header before allowing an internal-only path). That's a small slice of the install base, and the worst-case outcome is rule misfire — typically an internal URL being rewritten/exposed — not RCE, not auth bypass to admin. Vendor severity matches reality.
4 steps from start to impact.
Identify Tomcat with RewriteValve enabled
RewriteValve is configured (custom rewrite behavior visible in 301/302 responses, path normalization, host-based redirects). The valve is not enabled by default — it requires an explicit <Valve className="org.apache.catalina.valves.rewrite.RewriteValve" /> plus a rewrite.config in WEB-INF or conf/Catalina/<host>/. Tooling: curl, httpx, nuclei rewrite fingerprints.- Internet- or intranet-reachable Tomcat 9.0.0–9.0.118 or 11.0.0-M1–11.0.22
- RewriteValve explicitly enabled by the operator
- RewriteValve is opt-in; most Tomcat deployments use a fronting reverse proxy (nginx, httpd, F5) for rewrites instead
- Fingerprinting rewrite behavior blindly is noisy and unreliable
Locate a security-sensitive ruleset using [OR] + AND mix
RewriteRule is gated by something like RewriteCond %{REMOTE_ADDR} ^10\. [OR] + RewriteCond %{REMOTE_ADDR} ^192\.168\. + RewriteCond %{HTTP_HOST} ^internal\.corp$. Attacker needs to discover the rule logic, typically by leaked config, source-code repo exposure, or trial-and-error against known internal paths. Tooling: GitHub dorking, dirsearch, config-leak hunting.- Operator wrote rewrite rules that use [OR] chains as access-control predicates
- Attacker can guess or enumerate the gated URL
- Most rewrite rules are cosmetic (canonical host, trailing slash) — not security-bearing
- Treating mod_rewrite as an authorization layer is a well-known anti-pattern; mature shops gate behind authn/Z, not Host/IP rewrites
Trigger the short-circuit
[OR] condition trivially matches (e.g., a Host header the operator considered 'internal') even though the trailing AND condition (true source IP) does not. The valve evaluates the OR-flagged condition, sees a hit, skips the remaining unflagged conditions, and applies the RewriteRule. Tooling: curl -H 'Host: internal.corp', Burp Repeater.- The first [OR] condition is attacker-controllable (Host, User-Agent, query string, cookie)
- Subsequent AND condition is the real gate (REMOTE_ADDR, mTLS attr)
- If the gate condition uses REMOTE_ADDR and the OR condition uses the same, the bug has no effect
- Reverse proxies in front often re-write Host and clean headers, neutralizing the trick
Reach the rewritten resource
- Rewritten target lacks its own authentication
- Target is reachable from the Tomcat instance
- Defense-in-depth (Spring Security, Tomcat realms, app-layer authn) on the target endpoint stops this dead
- Most internal endpoints behind a rewrite gate still require session/cookie/SSO
rewrite.config for [OR] mixed with unflagged RewriteCond blocks — Grep every Catalina host config and WEB-INF/rewrite.config for [OR]. Any rule that mixes [OR] and AND-style conditions, AND uses one of them as a security predicate (IP, Host, mTLS attr), is a live exposure. Splitting into two separate rules or restructuring the predicate eliminates the bug pre-patch. Complete within the noisgate remediation window for LOW (backlog hygiene, ~365 days), but if any flagged rule is a security gate, treat it as a CRITICAL config error and fix immediately.<Valve className="...rewrite.RewriteValve"/> entry from server.xml / context.xml on hosts that don't need rewrites. Eliminates this CVE and reduces overall attack surface.RemoteAddrValve / RemoteIpValve or upstream NGFW/WAF rules — not in RewriteCond. Refactor any configs that use rewrite as authorization within the LOW remediation window.- WAF signatures — there is no malicious payload to match; the request looks ordinary (a normal Host header).
- Bumping CVSS-based scanner thresholds — most scanners won't flag this as actionable because Apache rated it Low; relying on scanner severity hides it.
- Front-end TLS / mTLS — does not help; the bug fires after termination, inside Tomcat's valve chain.
- Disabling SSI / JSP / CGI — unrelated; the defect is in valve evaluation, not in any execution engine.
The supporting signals.
| In-the-wild exploitation | None observed. No GreyNoise tagging, no honeypot hits, no incident-response reports as of 2026-07-01. |
|---|---|
| Public PoC | No weaponized PoC published. The Apache commit diffs (b647cb58, fe06ae8a) make the logic trivial to reproduce in a lab. |
| EPSS | Pending first scoring window post-disclosure; expected to land <1% / <50th percentile given Low severity and no PoC. |
| CISA KEV | Not listed. |
| Vendor severity | Apache: Low (no CVSS vector published in advisory) |
| CWE | CWE-670 — Always-Incorrect Control Flow Implementation |
| Affected versions | Tomcat 9.0.0.M1 – 9.0.118, Tomcat 11.0.0-M1 – 11.0.22. Tomcat 10.1.x advisory page should be cross-checked; Tomcat 8.5 is EOL. |
| Fixed versions | Tomcat 9.0.119, Tomcat 11.0.23 (commits b647cb58, fe06ae8a) |
| Exposure / scanning data | Shodan shows ~1.2M internet-reachable Tomcat banners; the population using RewriteValve is a tiny fraction — no public dataset quantifies it. Treat exposed-and-vulnerable as a rounding error of total Tomcat installs. |
| Disclosure timeline | Reported 2026-05-28, disclosed 2026-06-29. Reporter not publicly credited in the advisory text. |
Sources.
Why this verdict
- Non-default component: RewriteValve is opt-in. The vast majority of Tomcat deployments never load it — fronting nginx/httpd/F5 handles rewrites.
- Configuration-dependent bug: Even with the valve enabled, the defect only manifests when an
[OR]chain is mixed with unflagged AND conditions guarding the same rule. Cosmetic rewrites (canonical host, trailing slash) are unaffected. - Anti-pattern dependency: Exploiting it for security impact requires that the operator used rewrite conditions as an access-control gate — long discouraged by Tomcat and httpd documentation alike.
- Bounded blast radius: Successful exploitation surfaces whatever the rewrite target exposes. Any sane app behind it has its own authn. No RCE, no deserialization, no admin takeover from this CVE alone.
- Role multiplier: Tomcat itself is widely deployed, but the affected component (RewriteValve) is never the identity, hypervisor, CI, backup, or kernel-agent layer. Even on a high-value host running Tomcat (e.g., an internal app server), the bug yields at most an unauthorized URL rewrite — not fleet-scale or domain-scale compromise. Floor stays at LOW.
- No KEV / no PoC / no in-the-wild: Disclosed 2026-06-29; nothing weaponized. EPSS will settle near zero.
Why not higher?
MEDIUM would require either a default-on configuration, a security-gating use pattern that's common in the wild, or a chained impact (auth bypass, RCE) that this CVE does not provide. HIGH would require KEV listing or an authentication-layer breakthrough — neither is present.
Why not lower?
IGNORE is wrong because the defect IS exploitable in the narrow shops that do gate internal paths via mixed-OR rewrites, and patching is a cheap point-release bump. It deserves backlog tracking, not active suppression.
Crowdsourced verification payload.
Run this on each Tomcat host as a user able to read $CATALINA_HOME/conf/ and $CATALINA_BASE/webapps/*/WEB-INF/. Invoke as ./check-cve-2026-53404.sh /opt/tomcat. Prints VULNERABLE, PATCHED, or UNKNOWN and exits 1/0/2 respectively.
#!/usr/bin/env bash
# check-cve-2026-53404.sh — Tomcat RewriteValve [OR] short-circuit
# Usage: ./check-cve-2026-53404.sh <CATALINA_HOME>
set -u
CATALINA_HOME="${1:-/opt/tomcat}"
if [[ ! -d "$CATALINA_HOME" ]]; then
echo "UNKNOWN: $CATALINA_HOME not found"; exit 2
fi
# 1) Version detection
VER="$("$CATALINA_HOME/bin/version.sh" 2>/dev/null | awk -F': ' '/Server number/ {print $2}')"
if [[ -z "$VER" ]]; then
echo "UNKNOWN: cannot determine Tomcat version"; exit 2
fi
# 2) Compare against fixed versions
vuln=0
IFS='.' read -r MA MI PA <<<"$VER"
case "$MA" in
9) [[ "$MI" -eq 0 && "$PA" -lt 119 ]] && vuln=1 ;;
11) [[ "$MI" -eq 0 && "$PA" -lt 23 ]] && vuln=1 ;;
*) : ;; # 10.1 / 8.5 / future — confirm via advisory
esac
# 3) RewriteValve usage check
rv=0
rx=0
while IFS= read -r f; do
grep -lq 'org.apache.catalina.valves.rewrite.RewriteValve' "$f" && rv=1
done < <(find "$CATALINA_HOME" -type f \( -name 'server.xml' -o -name 'context.xml' \) 2>/dev/null)
while IFS= read -r cfg; do
if grep -qE '^[[:space:]]*RewriteCond[^#]*\[OR\]' "$cfg" \
&& grep -qE '^[[:space:]]*RewriteCond[^#]*$' "$cfg"; then
rx=1
fi
done < <(find "$CATALINA_HOME" -type f -name 'rewrite.config' 2>/dev/null)
# 4) Verdict
if [[ $vuln -eq 0 ]]; then
echo "PATCHED: Tomcat $VER is at or above fixed release"
exit 0
fi
if [[ $rv -eq 1 && $rx -eq 1 ]]; then
echo "VULNERABLE: Tomcat $VER, RewriteValve enabled, mixed [OR]+AND RewriteCond present"
exit 1
elif [[ $rv -eq 1 ]]; then
echo "VULNERABLE (low impact): Tomcat $VER with RewriteValve enabled; no mixed-OR ruleset found, but patch recommended"
exit 1
else
echo "PATCHED (effective): Tomcat $VER vulnerable build, but RewriteValve not enabled — defect unreachable"
exit 0
fi