CVE-2026-53404 is a logic flaw in Apache Tomcat’s RewriteValve. The bug is narrow, but the security lesson is bigger than the CVE description makes it look: if rewrite rules are being used as part of an access-control, routing, host-validation, or path-isolation boundary, a small difference in condition evaluation can change which requests are allowed to proceed.
Apache describes the issue as “Bad ornext processing in RewriteValve.” In affected Tomcat versions, when a request matched the first condition in an OR chain, later non-OR conditions could be skipped and the rewrite could succeed anyway. Apache marks the issue as Low severity, says it was reported to the Tomcat security team on May 28, 2026, and says it was made public on June 29, 2026. The affected supported ranges are Tomcat 11.0.0-M1 through 11.0.22, 10.1.0-M1 through 10.1.55, and 9.0.0.M1 through 9.0.118; the CVE record also names 8.5.0 through 8.5.100 and warns that other end-of-support versions may be affected. The fixed versions are 11.0.23, 10.1.56, and 9.0.119. (Apache Tomcat)
That does not mean every Tomcat server is exposed in a meaningful way. A Tomcat instance has to be running an affected version, using RewriteValve, and using a rule shape where OR-chained conditions are followed by a condition that should still be enforced. It also does not mean the bug is harmless. Rewrite rules often begin as convenience plumbing and quietly become policy: block this path, redirect this host, map this tenant, prevent this admin route from reaching the app, normalize this proxy path before authorization, or send disallowed traffic to a safe endpoint. CVE-2026-53404 matters when a team believed a rewrite rule meant “A or B, and also C,” but Tomcat evaluated it closer to “A is enough.”
The facts that matter first
| Champ d'application | Current public information |
|---|---|
| CVE | CVE-2026-53404 |
| Produit | Apache Tomcat |
| Composant | RewriteValve |
| Classe de vulnérabilité | Always-Incorrect Control Flow Implementation |
| CWE | CWE-670 |
| Apache title | Bad ornext processing in RewriteValve |
| Apache severity | Faible |
| Public disclosure | June 29, 2026 |
| Reported to Apache | May 28, 2026 |
| Affected Tomcat 11 | 11.0.0-M1 through 11.0.22 |
| Affected Tomcat 10.1 | 10.1.0-M1 through 10.1.55 |
| Affected Tomcat 9 | 9.0.0.M1 through 9.0.118 |
| Affected Tomcat 8.5 | 8.5.0 through 8.5.100, but 8.5 is already end-of-life |
| Versions corrigées | 11.0.23, 10.1.56, 9.0.119 |
| NVD status at the time reviewed | NVD had not provided its own CVSS score, while CISA-ADP contributed CVSS 3.1 7.3 High |
| CISA-ADP SSVC | Exploitation none, automatable yes, technical impact partial |
| Main exposure condition | RewriteValve enabled with OR-chained RewriteCond rules followed by non-OR conditions that should still restrict the rewrite |
| What it is not | Not described by Apache as direct remote code execution, not a universal Tomcat compromise, not enough to prove exposure from a banner alone |
The severity story deserves careful reading. Apache’s own Tomcat security pages list CVE-2026-53404 as Low. NVD’s page shows no NVD-assigned CVSS score at the time reviewed, but it also shows a CISA-ADP CVSS 3.1 score of 7.3 High, with vector AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:L. NVD also records CISA-ADP SSVC values of exploitation none, automatable yes, and partial technical impact. (Apache Tomcat)
That difference is not unusual for configuration-sensitive web-server bugs. A vendor may rate the component flaw as low because it only applies to a specific feature and rule pattern. A scoring system may rate the hypothetical impact higher because the attack vector is remote, unauthenticated, and can affect confidentiality or integrity when the vulnerable rule guards something important. A useful triage process should preserve both views: do not panic because a scanner says High, but do not dismiss it because the upstream severity says Low.
What RewriteValve does in Tomcat

Tomcat’s RewriteValve implements URL rewrite behavior similar to Apache HTTP Server’s mod_rewrite. It can be configured as a Valve using the class name org.apache.catalina.valves.rewrite.RewriteValve. Tomcat’s documentation says it can be added at the Host level, using a rewrite.config file in the Host configuration folder, or placed in a web application’s context.xml, using a rewrite.config file in the application’s WEB-INF directory. (Apache Tomcat)
That placement matters for security review. A global Host-level RewriteValve may apply to multiple applications under the same virtual host. A webapp-level RewriteValve may be owned by an application team rather than the platform team. In real environments, rules may live in container images, vendor packages, application WARs, configuration management templates, or deployment overlays. A version scanner can tell you Tomcat is old. It cannot tell you whether a particular rewrite condition is acting as a security boundary.
Tomcat’s rewrite configuration uses directives that closely resemble mod_rewrite, en particulier RewriteCond et RewriteRule. RewriteCond defines a condition; one or more conditions can precede a rule, and the rule is used only if the rule pattern matches and the conditions are satisfied. (Apache Tomcat)
The important flag for CVE-2026-53404 is ornext|OR. Tomcat’s own documentation says the ornext|OR flag combines rule conditions with a local OR instead of the implicit AND. Its example shows three host conditions chained with [OR], allowing one rule to apply when any of those hosts match. Apache HTTP Server’s mod_rewrite documentation says the same thing in different words: without [OR], multiple RewriteCond directives are evaluated in sequence with an implied logical AND; with [OR], conditions can be combined locally. (Apache Tomcat)
A simple rewrite rule might be harmless:
RewriteRule ^/old-products/(.*)$ /products/$1 [R=301,L]
That kind of rule is mostly routing. If it goes wrong, a link redirects incorrectly. But many deployments use conditions:
RewriteCond %{HTTP_HOST} ^admin\.example\.com$
RewriteCond %{REQUEST_URI} ^/console
RewriteRule ^(.*)$ /internal-admin$1 [L]
That is no longer just cosmetic routing. The rule says, in effect, “only when the host is the admin host and the request path is the console path, rewrite into the internal admin route.” If a condition is skipped, the request may enter a different part of the application than operators intended.
CVE-2026-53404 is specifically about that kind of condition logic.
The bug in plain language
The vulnerable shape is easiest to understand as a Boolean expression.
A rewrite author may intend this:
(host is localhost OR host is 127.0.0.1) AND path starts with /admin
That expression has two parts. The first part is an OR group. The second part is a mandatory path check. The rule should only succeed when one host condition is true and the path condition is also true.
The vulnerable behavior described by Apache is different. If the first condition in an OR chain matched, later non-OR conditions were skipped and the rewrite succeeded. (Apache Tomcat)
Translated into operational terms, a request could satisfy the host part and bypass the later path part. The exact impact depends on what the rule did after matching. If the rule only rewrote /old à /new, the impact may be minor. If the rule redirected disallowed requests, blocked admin paths, mapped tenant-specific paths, or protected internal endpoints, the result could be authorization confusion.
The Apache fix aligns the rewrite condition ornext processing with mod_rewrite, which follows sequential condition evaluation. Tomcat release notes for 9.0.119, 10.1.56, and 11.0.23 all list this alignment as a notable change. (Apache Tomcat)
The upstream commit message for the Tomcat 11 fix says: “Align the rewrite conditions ornext processing with mod_rewrite” and adds that the behavior now follows sequential condition evaluation. The diff also adds a regression test named testOrCondDoesNotSkipNonOrCond, using conditions on HTTP_HOST followed by a REQUEST_URI check. That test name is unusually clear: the security-relevant property is that an OR condition must not cause a later non-OR condition to disappear. (GitHub)

Why a Low-rated rewrite bug can still matter
A URL rewrite layer often sits before the application code that developers normally inspect. That makes it easy for assumptions to drift. A Java developer may read controller code and assume /admin is only reachable through a certain path. An operations engineer may read a rewrite.config file and assume disallowed paths are redirected before reaching the app. A security reviewer may test the happy path but never test the exact combination of Host header, path, scheme, and request method that causes a condition chain to behave differently.
CVE-2026-53404 sits in that gap.
The bug is not a generic exploit primitive. It does not create a shell. It does not automatically disclose files. It does not turn every Tomcat server into an unauthenticated admin panel. Its practical risk comes from misapplied policy. When rewrite logic is part of a policy boundary, a skipped condition means the boundary may not be the boundary you thought it was.
Common security-sensitive RewriteValve use cases include:
| Rewrite use case | Why teams use it | How CVE-2026-53404 could matter |
|---|---|---|
| Admin path routing | Send /admin ou /console to a separate internal route | A later URI condition could be skipped after an OR host match |
| Host-based isolation | Route tenants or environments by Hôte header | A rule may apply to a broader host/path combination than expected |
| Reverse-proxy normalization | Normalize paths before forwarding to a backend | A request may be normalized into a backend route under the wrong conditions |
| Legacy endpoint migration | Rewrite old paths into new application paths | Usually lower risk unless old paths carry auth or tenant assumptions |
| Bot or method filtering | Redirect or block traffic based on headers or methods | A non-OR method or URI check may not run |
| Static resource protection | Prevent direct access to internal files or folders | A rewrite can create an unintended alternate path if used as the only guard |
| Multi-application hosting | Apply Host-level rewrite logic across several apps | One shared rule can affect more than one application |
The safest rule of thumb is simple: if a rewrite rule is only for presentation, the bug is likely a maintenance issue. If a rewrite rule changes who can reach what, treat it as security logic and test it like security logic.
Affected versions and the Tomcat 8.5 problem
Apache and NVD list the affected supported ranges as Tomcat 11.0.0-M1 through 11.0.22, 10.1.0-M1 through 10.1.55, and 9.0.0.M1 through 9.0.118. NVD also lists 8.5.0 through 8.5.100 and says other end-of-support versions may also be affected. The recommended fixed versions are 11.0.23, 10.1.56, and 9.0.119. (NVD)
Tomcat 8.5 is a separate operational issue. Apache announced that support for Tomcat 8.5.x ended on March 31, 2024. After that date, releases from the 8.5 branch are highly unlikely, bugs affecting only 8.5 are not addressed, and security vulnerability reports are not checked against the 8.5 branch. Apache’s Tomcat 8 security page also states that vulnerabilities reported after March 31, 2024 are not listed there and will not be fixed, and that users should upgrade to 9.0.x or later to obtain security fixes. (Apache Tomcat)
That means an 8.5 deployment cannot wait for an Apache 8.5.101 release that fixes CVE-2026-53404. The realistic options are to migrate to a supported Tomcat branch, obtain support from a third-party extended-support provider if available and appropriate, or remove the vulnerable exposure by disabling or rewriting the risky RewriteValve rules while planning the migration. The last option is a risk reduction step, not a substitute for leaving an unsupported server branch.
Tomcat 9 also has a timeline. Apache has announced that Tomcat 9.0.x support ends on March 31, 2027. That does not change the immediate fix for CVE-2026-53404, but it matters for planning: Tomcat 9 users should patch now and avoid turning the 2027 support cliff into another emergency. (Apache Tomcat)
Who is actually exposed
Version is only the first filter. Exposure depends on three additional questions.
First, is RewriteValve enabled? A default Tomcat install that does not use RewriteValve does not exercise this code path for application routing. You still may need to patch Tomcat for the broader June 2026 Tomcat batch, but CVE-2026-53404 specifically requires the RewriteValve path.
Second, does the deployment use OR-chained rewrite conditions? Search for [OR] et ornext en rewrite.config. The exact syntax may vary in capitalization. Rules without OR chains are not the condition shape described by this CVE.
Third, does a later non-OR condition matter for security? If the skipped condition only changes a cosmetic redirect, exposure may be low. If the skipped condition limits a sensitive path, method, host, scheme, or header, exposure is more serious.
A useful triage table looks like this:
| Deployment condition | Likely priority | Pourquoi |
|---|---|---|
| Affected Tomcat version, RewriteValve not enabled | Lower for this CVE, still patch normally | The vulnerable component path is not used |
RewriteValve enabled, no [OR] ou ornext conditions | Lower for this CVE | The described OR-chain behavior is absent |
| RewriteValve enabled, OR chains used only for cosmetic redirects | Medium-low | Incorrect redirect behavior is possible, but security impact may be limited |
| OR chain followed by URI, method, scheme, host, or header condition | Moyenne à élevée | The skipped non-OR condition may change policy |
| Rewrite rules protect admin, tenant, internal, or upload routes | High validation priority | Misrouting can become access-control failure |
| Tomcat 8.5 with RewriteValve and OR chains | High operational priority | The branch is unsupported, so normal upstream patching is not available |
Do not rely only on a remote scanner. Tenable’s Tomcat 9 plugin for the June 2026 batch notes that it has not attempted to exploit the issues and relies on the application’s self-reported version number. That is useful for inventory, but it cannot distinguish a cosmetic rewrite from a security-critical rewrite. (Tenable®)
Safe PoC demo, showing the control-flow mistake without attacking a server
The following demonstration is intentionally not an exploit for a live Tomcat server. It does not connect to a network service, does not scan targets, and does not use a production payload. It is a toy model that helps defenders understand the vulnerable logic pattern: an OR group followed by a mandatory non-OR condition.
The intended rule is:
(host == "localhost" OR host == "127.0.0.1") AND path starts with "/admin"
A request with host=localhost et path=/public should not match because the path condition is false. The vulnerable pattern is that the first OR condition matches and the later non-OR path condition is skipped.
"""
Safe local demonstration for CVE-2026-53404-style condition confusion.
This code does not run Tomcat, does not send HTTP requests, and does not test
any real system. It only models the control-flow idea behind the bug:
an OR-chained condition should not make a later non-OR condition disappear.
"""
from dataclasses import dataclass
from typing import Callable, List
@dataclass
class Condition:
name: str
test: Callable[[dict], bool]
or_next: bool = False
def intended_sequential_eval(conditions: List[Condition], request: dict) -> bool:
"""
Correct mental model for this example:
evaluate the OR group, then still require the later non-OR condition.
"""
i = 0
result = True
while i < len(conditions):
current = conditions[i]
if current.or_next:
# Start a local OR group.
group_result = current.test(request)
i += 1
# Include each following condition that is part of the OR group.
while i < len(conditions):
group_result = group_result or conditions[i].test(request)
if not conditions[i].or_next:
i += 1
break
i += 1
result = result and group_result
continue
result = result and current.test(request)
i += 1
return result
def vulnerable_style_eval(conditions: List[Condition], request: dict) -> bool:
"""
Deliberately flawed toy evaluator:
if the first OR condition matches, it skips the next non-OR condition.
This is not Tomcat code. It is a simplified model of the bad outcome.
"""
i = 0
while i < len(conditions):
current = conditions[i]
if current.or_next and current.test(request):
# The mistake: treating the first OR match as enough for the rule,
# rather than continuing to require later non-OR checks.
return True
if not current.test(request):
return False
i += 1
return True
conditions = [
Condition("host is localhost", lambda r: r["host"] == "localhost", or_next=True),
Condition("host is 127.0.0.1", lambda r: r["host"] == "127.0.0.1"),
Condition("path starts with /admin", lambda r: r["path"].startswith("/admin")),
]
request = {
"host": "localhost",
"path": "/public",
}
print("Request:", request)
print("Correct evaluation:", intended_sequential_eval(conditions, request))
print("Flawed evaluation:", vulnerable_style_eval(conditions, request))
Expected output:
Request: {'host': 'localhost', 'path': '/public'}
Correct evaluation: False
Flawed evaluation: True
The output shows why the bug matters. The request satisfies the first host condition, but it does not satisfy the path condition. A rewrite that treats the first OR match as enough can apply to a request that should have stayed outside the rule.
A Tomcat-style rule pattern with similar intent could look like this:
RewriteCond %{HTTP_HOST} ^localhost$ [OR]
RewriteCond %{HTTP_HOST} ^127\.0\.0\.1$
RewriteCond %{REQUEST_URI} ^/admin
RewriteRule ^(.*)$ /blocked$1 [R]
The point is not that this exact rule is common or dangerous in every deployment. The point is that the third condition is not optional. If the rule author wrote it, the rule author intended it to matter. CVE-2026-53404 is about a condition evaluation path where that later non-OR condition could be skipped.
How to find affected RewriteValve usage
Start with inventory. On a traditional Tomcat deployment, check the installed version:
$CATALINA_HOME/bin/version.sh
For package-managed systems, use the package manager as well:
# Debian or Ubuntu-style systems
dpkg -l | grep -i tomcat
# RHEL, Fedora, SUSE, and similar RPM-based systems
rpm -qa | grep -i tomcat
For container images, inspect the image and runtime filesystem rather than assuming the base image name is accurate:
docker run --rm your-image:tag sh -c 'ls -la /usr/local/tomcat 2>/dev/null || true'
docker run --rm your-image:tag sh -c 'find / -name "catalina.jar" 2>/dev/null | head'
For embedded Tomcat in Java applications, look for tomcat-embed-core. Snyk’s advisory for this CVE specifically identifies org.apache.tomcat.embed:tomcat-embed-core as affected in the version ranges [9.0.0.M1,9.0.119), [10.1.0-M1,10.1.56)et [11.0.0-M1,11.0.23), and recommends upgrading to 9.0.119, 10.1.56, 11.0.23, or later. (VulnInfo Guide)
Maven:
mvn dependency:tree | grep -i 'tomcat-embed-core'
Gradle:
./gradlew dependencies --configuration runtimeClasspath | grep -i 'tomcat-embed-core'
Then search for RewriteValve configuration:
# Search common Tomcat configuration locations
grep -RIn "org.apache.catalina.valves.rewrite.RewriteValve" \
"$CATALINA_BASE/conf" "$CATALINA_HOME/conf" 2>/dev/null
# Search deployed applications
find "$CATALINA_BASE/webapps" -type f \
\( -name "context.xml" -o -name "rewrite.config" \) \
-print 2>/dev/null
Search for OR-chained conditions:
find "$CATALINA_BASE" -name "rewrite.config" -print0 2>/dev/null |
xargs -0 grep -HniE '\[(.*\bOR\b.*|.*\bornext\b.*)\]'
Also search container build context and application repositories:
grep -RInE 'RewriteCond|RewriteRule|\[OR\]|\bornext\b|RewriteValve' .
If you find [OR], do not stop at the first match. Read the entire block of conditions above each RewriteRule. The risky shape is not merely “OR exists.” The risky shape is “OR exists, and a later non-OR condition still needs to be true for the rewrite to be safe.”
A practical review checklist:
| Review item | What to look for | Pourquoi c'est important |
|---|---|---|
| Valve placement | Host-level vs webapp-level | Host-level rules may affect multiple apps |
| Rule ownership | Platform team, app team, vendor package, container template | Ownership affects patch and test path |
| OR chain | [OR], [ornext], mixed-case variants | This is the condition shape tied to the CVE |
| Later non-OR condition | URI, method, scheme, host, header, environment variable | This is the condition that may be skipped |
| Security intent | Admin route, internal route, tenant route, auth-sensitive redirect | Higher impact if rewrite influences access |
| Fallback behavior | Redirect, internal rewrite, forbidden response, proxy route | Determines actual consequence |
| Test coverage | Automated request tests for positive and negative cases | Prevents regression after patch or rewrite |
How to validate behavior safely

Validation should happen in an authorized staging or lab environment. Do not test third-party systems. Do not send crafted requests to production assets unless you own them, have written authorization, and have a change or testing window.
A minimal validation flow looks like this:
- Copy the exact
rewrite.configinto a staging Tomcat instance that matches the production version. - Build a small test matrix of requests that should match and should not match.
- Include requests where the first OR condition is true but the later non-OR condition is false.
- Record the response status,
Locationheader if redirected, and application route reached. - Upgrade to a fixed Tomcat version.
- Run the same matrix again.
- Preserve before-and-after evidence.
For a local lab only, a request might look like this:
curl -i \
-H 'Host: localhost' \
'http://127.0.0.1:8080/public'
Then compare with a request that should satisfy the path condition:
curl -i \
-H 'Host: localhost' \
'http://127.0.0.1:8080/admin'
The key is not the payload. The key is the expected truth table. If your rule says (A OR B) AND C, then a request satisfying A but not C should not trigger the protected rewrite. A good test case makes that visible.
For complex rules, write the expected logic explicitly before testing:
| Test case | Host condition A | Host condition B | Path condition C | Expected rule match |
|---|---|---|---|---|
| Localhost admin | True | False | True | True |
| Localhost public | True | False | False | False |
| 127.0.0.1 admin | False | True | True | True |
| 127.0.0.1 public | False | True | False | False |
| External admin | False | False | True | False |
If the “localhost public” case matches before the patch, your rule is in the danger zone.
Why scanner output can be misleading
Several vulnerability tools and databases now track CVE-2026-53404, but they do not all represent the same kind of evidence.
NVD gives the authoritative CVE detail page and records the Apache description, affected versions, CISA-ADP score, CWE-670, and references. It does not prove your deployment is using a risky rewrite rule. (NVD)
Snyk maps the issue to org.apache.tomcat.embed:tomcat-embed-core, which is especially useful for Spring Boot and other embedded Tomcat applications. It also reports EPSS data and package-level fixed versions. That is dependency intelligence, not runtime rule validation. (VulnInfo Guide)
Tenable’s plugin groups CVE-2026-53404 with other Tomcat vulnerabilities fixed in the same release line and explicitly says the scanner has not attempted to exploit the issues, relying on the application’s self-reported version number. That is helpful for broad detection, but it may overstate or understate the practical risk of this specific CVE depending on whether RewriteValve is used and how rules are written. (Tenable®)
SUSE rates the issue as moderate on its CVE page and shows a SUSE CVSS 3.1 score of 6.5, while also displaying the CISA-ADP 7.3 score. Its product table is useful for SUSE package tracking, but it is not a substitute for checking your rewrite configuration. (SUSE)
Red Hat’s Bugzilla entry summarizes the issue as incorrect control flow in the rewrite valve that allows unexpected rule processing and says the flaw can potentially allow security bypasses or unauthorized access due to misapplied configurations. That wording captures the real-world concern well: the bug is only meaningful when the configuration gives the rewrite rule security meaning. (Red Hat Bugzilla)
A sane vulnerability ticket should separate four things:
| Evidence type | Exemple | What it proves | Ce qu'il ne prouve pas |
|---|---|---|---|
| Version evidence | Tomcat 9.0.118 detected | The host may be in the affected range | RewriteValve is enabled |
| Package evidence | tomcat-embed-core before 9.0.119 | The app depends on an affected library | The app uses RewriteValve |
| Configuration evidence | RewriteValve et rewrite.config found | The code path may be active | The rule is security-sensitive |
| Behavioral evidence | Local test shows rule matches when C is false | The deployment has a meaningful exposure | Exploitation against unrelated targets |
| Remediation evidence | Upgrade plus passing negative tests | The specific behavior was fixed in your environment | Every unrelated Tomcat issue is resolved |
The best remediation tickets include all five.
Logs and detection signals
CVE-2026-53404 is not an IOC-rich vulnerability. There is no universal URI, header, user agent, or payload that proves exploitation. The same request that is malicious in one deployment may be ordinary in another. Detection therefore has to be behavior- and configuration-oriented.
Start with the access logs. Look for requests that combine unusual Host headers with sensitive paths, legacy paths, or paths controlled by rewrite rules. If the rewrite resulted in a redirect, inspect Location headers. If the rewrite internally mapped to another route, application logs may be more useful than access logs because the application may record the final route rather than the original request.
Useful signals include:
| Signal | Where to look | Why it helps | Common false positive |
|---|---|---|---|
| Requests to sensitive paths with unexpected Host headers | Access logs, proxy logs | Rewrite conditions often use HTTP_HOST | Health checks, local monitoring |
| Requests that trigger unexpected redirects | Access logs, client telemetry | Rewrite success may appear as 30x behavior | Normal migration redirects |
| Internal route reached from public-looking path | App logs, tracing | Suggests rewrite changed routing | Legitimate route aliases |
| High volume of path variations near admin routes | WAF, proxy logs | Attackers may probe rewrite boundaries | Crawlers, broken links |
| Version-only scanner finding | Scanner output, SBOM | Identifies candidates for review | No RewriteValve in use |
[OR] in security-sensitive rewrite rule | Config repository | Stronger exposure signal | Cosmetic redirects |
If you have structured logs, preserve both the original request and the route that the app handled. Reverse proxies, service meshes, and application frameworks often normalize or rewrite request data in their own layers. For CVE-2026-53404, the distinction between original URI, rewritten URI, servlet path, and final handler can matter.
A simple NGINX or proxy log format that records Host and URI is often enough to support triage:
log_format rewrite_triage '$remote_addr host=$host method=$request_method '
'uri="$request_uri" status=$status '
'upstream="$upstream_addr" location="$sent_http_location"';
In Java application logs, include the request URI and handler route where possible. Avoid logging secrets or full query strings if they may contain tokens.
Remédiation
The primary fix is to upgrade Tomcat to a fixed version: 11.0.23, 10.1.56, 9.0.119, or later in the same supported line. Apache lists the issue as fixed in those release lines, and the Tomcat release notes explicitly call out aligning ornext condition processing with mod_rewrite. (Apache Tomcat)
For package-managed systems:
# Debian or Ubuntu-style systems
sudo apt update
sudo apt install --only-upgrade tomcat9 tomcat10 tomcat11
# RPM-based systems
sudo dnf update 'tomcat*'
Package names vary by distribution and repository. Always confirm the resulting version after the update.
For embedded Tomcat, upgrade the dependency rather than only updating a system package:
Maven:
<properties>
<tomcat.version>9.0.119</tomcat.version>
</properties>
Gradle:
ext['tomcat.version'] = '9.0.119'
For Spring Boot, do not blindly override managed dependencies unless you understand the compatibility implications. Prefer a Spring Boot release that already manages a fixed Tomcat version, or follow the framework’s documented dependency override process.
For containers, rebuild the image. Updating the host does not update the Tomcat libraries inside an existing image:
docker build --pull -t your-app:tomcat-fixed .
docker run --rm your-app:tomcat-fixed sh -c '$CATALINA_HOME/bin/version.sh || true'
For Tomcat 8.5, plan migration. Apache’s end-of-life notice means security fixes are not coming from the upstream 8.5 branch. If an immediate migration is not possible, reduce exposure while the migration is scheduled:
# Prefer explicit, duplicated rules over a security-sensitive OR chain
# when you need a temporary mitigation and cannot patch immediately.
RewriteCond %{HTTP_HOST} ^localhost$
RewriteCond %{REQUEST_URI} ^/admin
RewriteRule ^(.*)$ /blocked$1 [R]
RewriteCond %{HTTP_HOST} ^127\.0\.0\.1$
RewriteCond %{REQUEST_URI} ^/admin
RewriteRule ^(.*)$ /blocked$1 [R]
Duplicating rules is less elegant, but it can be easier to reason about under pressure. Do not treat this as a permanent substitute for patching. It is a temporary risk reduction pattern when the dangerous shape is “OR group plus later mandatory condition.”
Hardening RewriteValve rules after the patch
Patching fixes the known implementation bug. It does not automatically make every rewrite policy good.
Use the CVE as an excuse to clean up rewrite logic. Rewrite rules are often hard to review because they encode security assumptions in terse regular expressions. A rule that makes sense to the person who wrote it in 2021 may be unreadable to the team responsible for it in 2026.
Good hardening practices include:
| Practice | Better pattern | Why it helps |
|---|---|---|
| Avoid security-critical OR chains when possible | Duplicate clear rules | Easier to review and test |
| Keep authorization in the app or proxy ACL | Use RewriteValve for routing, not primary auth | Reduces policy ambiguity |
| Add negative tests | Test requests that satisfy A but not C | Catches the exact CVE pattern |
| Document rule intent | Comment why each condition exists | Prevents unsafe cleanup |
| Log original and rewritten path | Preserve evidence | Makes triage possible |
| Review regex complexity | Avoid catastrophic backtracking | Tomcat docs warn that poorly formed Java regex can cause ReDoS |
| Pin and scan dependencies | Poursuivre tomcat-embed-core and server packages | Finds embedded exposure |
Tomcat’s RewriteValve documentation itself warns that poorly formed rewrite regex patterns can be vulnerable to catastrophic backtracking, also known as regular expression denial of service. That warning is not the same issue as CVE-2026-53404, but it belongs in the same review. If you are touching rewrite rules, review both control-flow logic and regex safety. (Apache Tomcat)
A practical post-patch test file can be small:
rewrite_tests:
- name: localhost admin should match
host: localhost
path: /admin
expected_rewrite: true
- name: localhost public should not match
host: localhost
path: /public
expected_rewrite: false
- name: loopback admin should match
host: 127.0.0.1
path: /admin
expected_rewrite: true
- name: external admin should not match
host: example.com
path: /admin
expected_rewrite: false
You can drive those cases with curl, an integration test, or a proxy-based test harness. The important part is that the negative cases are first-class tests, not informal manual checks.
Related Tomcat CVEs that help frame the risk
CVE-2026-53404 was disclosed in a crowded Tomcat security period. It is useful to compare it with nearby Tomcat issues because the biggest mistake defenders make is treating all Tomcat CVEs as one generic “server is vulnerable” bucket.
| CVE | Zone | Why it is relevant | Main exposure condition | Fix or mitigation |
|---|---|---|---|---|
| CVE-2026-53404 | RewriteValve ornext logique | Shows how rewrite condition evaluation can break routing or policy assumptions | RewriteValve enabled with OR-chain rules followed by mandatory non-OR checks | Upgrade to 11.0.23, 10.1.56, 9.0.119 or later; review rewrite rules |
| CVE-2026-55956 | Default servlet method constraints | Another configuration-sensitive authorization issue in Tomcat | Security constraints for the default servlet using method or method omission logic | Upgrade to fixed Tomcat versions; test method-level authorization |
| CVE-2026-55957 | JNDIRealm GSSAPI authentication | Higher-impact auth bypass in a specific Realm configuration path | JNDIRealm configured to authenticate binds using GSSAPI | Upgrade to versions containing the fix; audit Realm configuration |
| CVE-2026-53434 | FFM connector CRL handling | Shows certificate trust can fail when error handling is wrong | FFM connector configured with invalid CRLs where client cert validation matters | Upgrade; validate CRL behavior in mTLS paths |
| CVE-2025-24813 | Default servlet path equivalence | Shows Tomcat impact can change dramatically with deployment prerequisites | Write-enabled default servlet, partial PUT, file-based session persistence, and deserialization-capable library for RCE case | Upgrade to fixed versions; keep default servlet writes disabled unless explicitly required |
CVE-2026-55956 is especially relevant because it also teaches configuration-aware triage. A default servlet authorization bug is not the same as a RewriteValve bug, but both punish shallow analysis. In one case, the risky question is whether method-based constraints exist around the default servlet. In the other, the question is whether RewriteValve OR chains sit in front of meaningful non-OR conditions. Penligent’s related Tomcat analysis of CVE-2026-55956 frames that kind of configuration-specific validation in a practical way, but the vulnerability facts for CVE-2026-53404 should still be anchored in Apache and NVD rather than any secondary write-up. (Penligent)
CVE-2026-55957 is more severe in the usual sense because it is an authentication bypass tied to JNDIRealm configured for GSSAPI authenticated bind. Its relevance here is not technical similarity; it is prioritization discipline. A Tomcat host may have several CVEs at once, but the most urgent one depends on the configured component. RewriteValve rules, JNDIRealm, clustering interceptors, FFM connectors, and example webapps do not have the same exposure profile. HeroDevs’ June 2026 Tomcat roundup makes the same grouping point: the June 29 disclosures spanned JNDIRealm, default servlet constraints, EncryptInterceptor, RewriteValve, FFM connector, examples webapp, and effective web.xml logging. (HeroDevs)
CVE-2026-53434 is useful as a contrast. It involves invalid CRL handling in Tomcat’s FFM connector path, where invalid CRLs could be ignored and certificates that should have been rejected could be accepted. That is not a rewrite bug. But it has the same operational shape: a security boundary depends on a feature being configured, and the dangerous outcome is that a control silently does less than operators believe. Apache lists the Tomcat 9 affected range for that issue as 9.0.83 to 9.0.118 and says it was fixed with the relevant 9.0.119 commits. (Apache Tomcat)
CVE-2025-24813 is worth mentioning because it shows why Tomcat vulnerability summaries must preserve prerequisites. NVD’s description says the issue could lead to remote code execution, information disclosure, or malicious content being added to uploaded files via a write-enabled Default Servlet. For the RCE case, NVD lists multiple required conditions, including writes enabled for the default servlet, partial PUT support, file-based session persistence with the default storage location, and a deserialization-capable library. (NVD)
That is the same discipline CVE-2026-53404 needs. Do not call it RCE. Do not call it harmless. State the version, component, configuration, rule shape, reachable paths, observed behavior, and fix.
Supply chain and embedded Tomcat pitfalls
Many teams do not install Tomcat by hand anymore. They inherit it.
A Java service may embed Tomcat through a framework. A vendor product may bundle Tomcat behind a management UI. A container image may include Tomcat libraries copied from a base image that the application team never inspects. A Linux distribution may backport fixes without changing the upstream-looking version string. A scanner may flag the version but not understand the packaging policy. A team may patch the OS and forget the application image. Another team may patch the image and forget a sidecar or old management node.
For CVE-2026-53404, that matters because exposure requires both code and configuration. You need to know whether the runtime has an affected Tomcat build and whether RewriteValve is actually used.
For Maven projects:
mvn -q dependency:tree -Dincludes=org.apache.tomcat.embed:tomcat-embed-core
For Gradle projects:
./gradlew dependencyInsight \
--dependency tomcat-embed-core \
--configuration runtimeClasspath
For SBOM-based workflows, search for:
org.apache.tomcat.embed:tomcat-embed-core
org.apache.tomcat:tomcat-catalina
org.apache.tomcat:tomcat-util
apache:tomcat
For container images:
syft your-image:tag | grep -i tomcat
grype your-image:tag | grep -i CVE-2026-53404
For live hosts:
ps aux | grep -i '[o]rg.apache.catalina.startup.Bootstrap'
lsof -p "$(pgrep -f 'org.apache.catalina.startup.Bootstrap' | head -1)" | grep -i tomcat
For application repositories:
grep -RInE 'RewriteValve|rewrite.config|RewriteCond|RewriteRule|\[OR\]|\bornext\b' \
app/ config/ deploy/ docker/ charts/ 2>/dev/null
The best vulnerability management record for this issue should include:
Asset:
Tomcat runtime:
Tomcat version:
Tomcat source:
Deployment type:
RewriteValve enabled:
rewrite.config location:
OR-chain rules found:
Security-sensitive rules:
Behavioral test completed:
Fixed version:
Post-fix negative tests passed:
Residual risk:
Owner:
That structure prevents two common failures: closing the ticket because “Tomcat was upgraded” without testing the rule, and escalating the ticket because “scanner says High” without checking whether RewriteValve is present.
What to do if you cannot upgrade immediately
The right fix is to upgrade. But production reality often has a gap between “known fix” and “deployed fix.” During that gap, reduce the specific risk.
First, identify RewriteValve rules with OR chains and security meaning. You do not need to rewrite every redirect in the estate before the maintenance window. Prioritize rules that involve admin paths, internal paths, upload paths, tenant routing, authentication flows, method checks, host checks, and reverse-proxy normalization.
Second, split dangerous OR chains into duplicated explicit rules. This is not elegant, but it is easy to reason about. If the risk is that an OR group skips a later condition, duplication removes the OR group.
Before:
RewriteCond %{HTTP_HOST} ^admin\.example\.com$ [OR]
RewriteCond %{HTTP_HOST} ^admin-internal\.example\.com$
RewriteCond %{REQUEST_URI} ^/console
RewriteRule ^(.*)$ /internal-console$1 [L]
Temporary mitigation:
RewriteCond %{HTTP_HOST} ^admin\.example\.com$
RewriteCond %{REQUEST_URI} ^/console
RewriteRule ^(.*)$ /internal-console$1 [L]
RewriteCond %{HTTP_HOST} ^admin-internal\.example\.com$
RewriteCond %{REQUEST_URI} ^/console
RewriteRule ^(.*)$ /internal-console$1 [L]
Third, move security enforcement out of rewrite logic where possible. RewriteValve is useful, but it should not be the only layer protecting a sensitive route. Use application authorization, proxy ACLs, network policy, mTLS, identity-aware access proxies, or servlet security constraints where appropriate. Defense-in-depth matters because rewrite behavior, proxy behavior, framework routing, and application authorization are separate layers that can drift.
Fourth, add temporary monitoring around the affected paths. If you know the rewrite rule protects /console, /admin, /internal, /tenantou /uploads, monitor those paths with Host, method, URI, status, and upstream route context.
Fifth, document the exception. A temporary rewrite change without documentation becomes tomorrow’s unknown behavior.
Automated validation, evidence, and AI-assisted workflows
A safe validation workflow for CVE-2026-53404 is not about generating a more clever payload. It is about preserving evidence: version, configuration, rule intent, negative test cases, observed behavior before the fix, observed behavior after the fix, and the final remediation decision. That is the part many teams still do manually in scattered notes, tickets, shell history, screenshots, and partial scanner exports.
For authorized security testing, an AI-assisted workflow can help organize that evidence without replacing human judgment. A tool such as Penligent is most relevant here when the task is scoped to approved assets and the goal is repeatable validation: map reachable web surfaces, collect request and response evidence, keep human review in the loop, reduce false positives through independent verification, and turn a configuration-sensitive finding into a report that another engineer can reproduce. The important constraint is the same as with any pentest tool: do not test assets you do not own or have explicit permission to assess. (Penligent)
That matters because CVE-2026-53404 is easy to mishandle in both directions. A vague scanner ticket can create unnecessary panic. A vague “low severity” dismissal can miss a real rewrite-policy bypass. The difference is evidence.
Reporting template for security teams
A good internal or client-facing report should be boring, specific, and reproducible. Avoid saying “Tomcat vulnerable” without context. Write down exactly what was found.
Exemple :
Finding:
Apache Tomcat instance app-gateway-03 runs Tomcat 9.0.118 and enables
org.apache.catalina.valves.rewrite.RewriteValve at Host scope.
Affected component:
RewriteValve, CVE-2026-53404.
Configuration:
$CATALINA_BASE/conf/Catalina/example.com/rewrite.config contains an OR-chained
RewriteCond block followed by a non-OR REQUEST_URI condition for /admin.
Risk:
The rule was intended to apply only when (host A OR host B) AND URI starts
with /admin. In the affected version, a request satisfying the first OR
condition may skip the later non-OR condition and trigger the rewrite.
Validation:
A staging test using the production rewrite.config showed that Host A with
/public triggered the rewrite before patching. The same test did not trigger
the rewrite after upgrade to Tomcat 9.0.119.
Remediation:
Upgraded Tomcat to 9.0.119. Split the OR chain into two explicit rules for
readability. Added regression tests for Host A /public, Host A /admin, Host B
/public, Host B /admin, and external host /admin.
Residual risk:
No known remaining RewriteValve OR-chain rules protect sensitive paths.
That format has enough detail for engineering, security, audit, and retest. It also avoids overstating the vulnerability.
Common mistakes
The first mistake is treating CVE-2026-53404 as a generic Tomcat RCE. Public Apache and NVD descriptions do not describe it that way. It is a RewriteValve control-flow issue.
The second mistake is treating Apache’s Low severity as “ignore.” If RewriteValve is part of an access boundary, a low-rated component bug can still create a meaningful exposure in your deployment.
The third mistake is closing the ticket after a version scan. A fixed version is necessary, but a configuration-sensitive bug also deserves a behavioral test for the rules that mattered.
The fourth mistake is testing production first. Recreate the rule in staging or a local lab. Preserve production only for carefully approved validation.
The fifth mistake is assuming RewriteValve rules are owned by the web server team. In many organizations, those rules are shipped by application teams, vendor products, Helm charts, or old migration scripts.
The sixth mistake is leaving Tomcat 8.5 in place because it still “works.” It may still run applications, but upstream security support ended in 2024. That changes the risk model for every new Tomcat CVE that also affects 8.5.
The seventh mistake is rewriting the rule without tests. A hand-edited rewrite rule can fix CVE exposure and introduce a new outage. Negative tests are cheaper than incident calls.
FAQ
What is CVE-2026-53404?
- CVE-2026-53404 is an Apache Tomcat RewriteValve logic flaw involving
ornext|ORcondition handling. - In affected versions, if the first condition in an OR chain matched, later non-OR conditions could be skipped and the rewrite could succeed.
- The issue is classified as CWE-670, Always-Incorrect Control Flow Implementation.
- Apache fixed it in Tomcat 11.0.23, 10.1.56, and 9.0.119.
Is CVE-2026-53404 remote code execution?
- No, Apache and NVD do not describe CVE-2026-53404 as direct remote code execution.
- The realistic risk is unexpected rewrite behavior, which may become a security bypass if RewriteValve rules enforce access, routing, tenant isolation, or admin path controls.
- Do not label it RCE unless a separate, deployment-specific chain proves code execution.
- Treat it as a configuration-sensitive policy bypass risk.
Who is affected by CVE-2026-53404?
- Affected versions include Tomcat 11.0.0-M1 through 11.0.22, 10.1.0-M1 through 10.1.55, 9.0.0.M1 through 9.0.118, and 8.5.0 through 8.5.100.
- Practical exposure requires RewriteValve to be enabled.
- The risky rule pattern uses OR-chained
RewriteConddirectives followed by non-OR conditions that should still restrict the rewrite. - Tomcat 8.5 users have a larger operational problem because the 8.5 branch is end-of-life.
How do I check whether my application uses RewriteValve?
- Search Tomcat configuration for
org.apache.catalina.valves.rewrite.RewriteValve. - Check Host-level configuration and webapp-level
context.xml. - Search for
rewrite.configunder Host configuration directories andWEB-INF. - Search rule files for
[OR],[ornext],RewriteCondetRewriteRule. - For embedded Tomcat, also inspect Maven, Gradle, container images, and SBOMs.
Why does one source call it Low while another score looks High?
- Apache lists CVE-2026-53404 as Low on the Tomcat security pages.
- NVD shows no NVD-assigned CVSS score at the time reviewed, but it includes a CISA-ADP CVSS 3.1 score of 7.3 High.
- The difference reflects assumptions: a component owner may weigh feature specificity, while a CVSS assessment may model remote unauthenticated impact if the rule protects something important.
- Use both signals, then decide priority based on your actual RewriteValve configuration.
Can I mitigate by editing rewrite.config instead of upgrading?
- Editing risky OR chains can reduce exposure temporarily, especially if you split OR logic into explicit duplicated rules.
- That is not the primary fix. The primary fix is upgrading to Tomcat 11.0.23, 10.1.56, 9.0.119, or later.
- A rewrite-only mitigation may miss other Tomcat vulnerabilities fixed in the same release line.
- Any rewrite change should be tested with positive and negative request cases.
Are there known indicators of compromise for CVE-2026-53404?
- There is no universal IOC for this CVE.
- Useful signals depend on your rules: unusual Host headers, sensitive paths, unexpected redirects, internal route access from public-looking paths, and mismatches between intended and observed rewrite behavior.
- Logs should preserve the original Host, URI, method, status, redirect target, and application route where possible.
- Absence of a known IOC does not prove absence of exposure.
What should Tomcat 8.5 users do?
- Plan a migration to a supported Tomcat branch.
- Apache support for Tomcat 8.5.x ended on March 31, 2024, and upstream security fixes are not expected for that branch.
- If migration cannot happen immediately, identify and reduce the specific RewriteValve OR-chain exposure, restrict access to sensitive routes, and document the temporary risk.
- Treat continued Tomcat 8.5 operation as a broader lifecycle risk, not only a CVE-2026-53404 issue.
Fermeture
CVE-2026-53404 is not the loudest Tomcat vulnerability of 2026, but it is the kind that exposes weak assumptions. Rewrite rules are easy to treat as plumbing until they decide who reaches an admin path, which host maps to which tenant, or whether a request should be redirected away from a sensitive route.
Patch first. Then read the rules. Look for OR chains. Test the negative cases. Preserve the evidence. The technical fix is a Tomcat upgrade; the security fix is proving that the paths you intended to protect are still protected after the rewrite layer does its work.

