Introduction
In the frontend dependency tree of this application, a high-severity Denial of Service vulnerability lurked in react-router version 7.16.0. CVE-2026-55685 exposes a critical flaw: the server-side manifest endpoint in React Router accepts unauthenticated requests and processes them through an inefficient route matching algorithm. An attacker doesn't need credentials—just a carefully crafted HTTP request—to pin the server's CPU at 100% and render the application unavailable to all users.
The vulnerability was flagged by Trivy in frontend/package-lock.json, specifically targeting the react-router dependency and its transitive dependency chain including cookie and set-cookie-parser. The fix involves a major version upgrade that restructures how React Router handles manifest requests internally.
The Vulnerability Explained
What's the Manifest Endpoint?
React Router's server-side rendering (SSR) mode exposes an internal manifest endpoint that clients use to fetch route metadata for client-side navigation. This endpoint is, by design, unauthenticated—it needs to be accessible to any browser loading the application.
The Algorithmic Problem
In react-router 7.16.0, the manifest endpoint processes incoming route patterns through a matching algorithm with poor worst-case complexity. When an attacker sends a request with a specially crafted URL path containing nested or repetitive segments, the route matcher enters a pathological case where it performs exponential backtracking—similar to ReDoS (Regular Expression Denial of Service) but at the route matching level.
The vulnerable version's dependency tree looked like this:
"node_modules/react-router": {
"version": "7.16.0",
"dependencies": {
"cookie": "^1.0.1",
"set-cookie-parser": "^2.6.0"
},
"engines": {
"node": ">=20.0.0"
},
"peerDependencies": {
"react": ">=18",
"react-dom": ">=18"
}
}
The set-cookie-parser dependency was part of the server-runtime handling that processed these manifest requests, parsing cookies from incoming requests before route matching occurred—meaning the vulnerable code path was reachable without any authentication check.
Attack Scenario
An attacker could exploit this vulnerability with a simple script:
# Repeated crafted requests to the manifest endpoint
for i in $(seq 1 100); do
curl -s "https://target-app/__manifest?path=/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a" &
done
Each request triggers the inefficient route matching, and because the endpoint is unauthenticated, there's no barrier to sending thousands of these requests. Even a modest number of concurrent requests could saturate the server's CPU, causing:
- Complete application unavailability for legitimate users
- Cascading failures in microservice architectures where the frontend server becomes unresponsive
- Potential infrastructure costs from auto-scaling triggered by the CPU spike
The Fix
The fix upgrades react-router from version 7.16.0 to 8.3.0, which includes the patch for CVE-2026-55685. This isn't just a minor patch—it's a significant restructuring of how React Router handles server-side requests.
Before (Vulnerable)
"node_modules/react-router": {
"version": "7.16.0",
"resolved": "https://registry.npmjs.org/react-router/-/react-router-7.16.0.tgz",
"dependencies": {
"cookie": "^1.0.1",
"set-cookie-parser": "^2.6.0"
},
"engines": {
"node": ">=20.0.0"
},
"peerDependencies": {
"react": ">=18",
"react-dom": ">=18"
}
}
After (Fixed)
"node_modules/react-router": {
"version": "8.3.0",
"resolved": "https://registry.npmjs.org/react-router/-/react-router-8.3.0.tgz",
"dependencies": {
"cookie-es": "^3.1.1"
},
"engines": {
"node": ">=22.22.0"
},
"peerDependencies": {
"react": ">=19.2.7",
"react-dom": ">=19.2.7"
}
}
Key Changes
-
set-cookie-parserremoved entirely: The vulnerable request processing pipeline that includedset-cookie-parserhas been eliminated. The new version no longer needs this dependency, reducing the attack surface. -
cookiereplaced withcookie-es: Thecookiepackage (v1.1.1) was replaced withcookie-es(v3.1.1), a more modern, ESM-native cookie handling library. This change is part of the broader refactoring that fixed the manifest endpoint handling. -
Engine requirement bumped to Node.js ≥22.22.0: The new version leverages more recent Node.js features for efficient request processing, indicating the route matching internals were significantly rewritten.
-
React peer dependency updated to ≥19.2.7: The fix is part of a broader modernization that ensures compatibility with the latest React features for server-side rendering.
The cookie dependency change from cookie to cookie-es is particularly telling:
// REMOVED
"node_modules/cookie": {
"version": "1.1.1",
"engines": { "node": ">=18" }
}
// ADDED
"node_modules/cookie-es": {
"version": "3.1.1"
}
The cookie-es library is lighter and doesn't carry the same server-runtime baggage that was part of the vulnerable code path.
Prevention & Best Practices
1. Monitor Dependencies Continuously
This vulnerability existed in a transitive dependency chain. The application didn't directly call the vulnerable code—React Router's internal server-side handling did. Continuous scanning with tools like Trivy catches these issues before they're exploited.
2. Rate Limit All Endpoints
Even internal endpoints like /__manifest should have rate limiting. While this doesn't fix the root cause, it provides defense-in-depth:
// Example: Rate limiting the manifest endpoint
app.use('/__manifest', rateLimit({
windowMs: 1000,
max: 10,
message: 'Too many requests'
}));
3. Pin and Audit Major Dependencies
React Router is a core routing dependency. Pin it to specific versions and audit upgrades:
// package.json - pin exact version
"react-router": "8.3.0"
4. Use Lockfile Scanning in CI/CD
Add dependency scanning to your CI pipeline to catch vulnerable packages before they reach production:
# Example CI step
- name: Scan dependencies
run: trivy fs --scanners vuln frontend/package-lock.json
5. Understand Your Attack Surface
Unauthenticated endpoints are prime targets. Audit which endpoints in your SSR framework are publicly accessible and ensure they have appropriate protections against abuse.
Key Takeaways
- React Router's manifest endpoint is unauthenticated by design, making algorithmic inefficiency in route matching a direct DoS vector—always consider the authentication context of framework-internal endpoints.
- The
set-cookie-parserdependency removal indicates the fix restructured the entire request processing pipeline, not just patched the route matching—sometimes the best fix is architectural. - Transitive dependencies (
cookie,set-cookie-parser) contributed to the vulnerable code path even though the application never directly imported them—lockfile scanning is essential. - The Node.js engine requirement jump from ≥20.0.0 to ≥22.22.0 signals significant internal changes—verify your deployment environment supports the new requirements before upgrading.
- Even "internal" framework endpoints like
/__manifestneed DoS protection—attackers don't respect the boundary between "public" and "internal" URLs.
How Orbis AppSec Detected This
- Source: Unauthenticated HTTP requests to the React Router server-side manifest endpoint (
/__manifest) - Sink: Inefficient route matching algorithm in
react-router@7.16.0's server runtime, processing attacker-controlled URL path segments - Missing control: No computational complexity bounds on route matching for unauthenticated manifest requests; no rate limiting or input length validation on the path parameter
- CWE: CWE-400 (Uncontrolled Resource Consumption)
- Fix: Upgraded
react-routerfrom 7.16.0 to 8.3.0 infrontend/package-lock.json, which replaces the inefficient route matching implementation and removes theset-cookie-parserdependency from the vulnerable code path.
Orbis AppSec automatically detected this vulnerability and opened a pull request with the fix. Try Orbis AppSec on your repositories to find and fix issues like this automatically.
Conclusion
CVE-2026-55685 is a stark reminder that Denial of Service vulnerabilities don't require authentication bypass or data exfiltration to be severe. A single unauthenticated endpoint with inefficient algorithmic behavior can bring down an entire application. The fix—upgrading from react-router 7.16.0 to 8.3.0—eliminates the vulnerable code path entirely by restructuring how manifest requests are processed and removing unnecessary dependencies like set-cookie-parser.
For teams using React Router with server-side rendering, this upgrade should be prioritized. The change in peer dependencies (React ≥19.2.7) and engine requirements (Node.js ≥22.22.0) means this isn't a drop-in patch, but the security improvement justifies the migration effort. Always scan your lockfiles, understand which endpoints are unauthenticated, and treat algorithmic complexity as a security concern.