React Router: Potential CSRF via PUT/PATCH/DELETE document requests
Description
React Router v7 Framework Mode insufficient CSRF checks allowed bypass on PUT/PATCH/DELETE, but modern browser protections mitigate the risk.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
React Router v7 Framework Mode insufficient CSRF checks allowed bypass on PUT/PATCH/DELETE, but modern browser protections mitigate the risk.
Vulnerability
In React Router v7 Framework Mode, CSRF checks were implemented only for POST requests, leaving PUT, PATCH, and DELETE requests unchecked [1]. This affects packages @remix-run/server-runtime versions >=2.17.3 and <2.17.5 [1]. The vulnerability is limited to Framework Mode; Declarative Mode and Data Mode are not impacted [1][2].
Exploitation
An attacker would need to craft a cross-origin request using PUT, PATCH, or DELETE to trigger a state-changing action on behalf of an authenticated user. However, modern browser protections such as CORS preflight and SameSite cookies block cross-origin requests that would otherwise be eligible for this attack [1][2]. As a result, the missing CSRF check is effectively redundant in typical browser environments, making exploitation highly unlikely under normal conditions.
Impact
If an attacker could bypass browser protections (e.g., via misconfigured CORS, disabled SameSite cookies, or non-browser clients), they could perform actions on behalf of the victim without proper CSRF validation. The impact is limited to state-changing operations (e.g., updating or deleting resources) that would normally be gated by the missing check [1]. The vulnerability is rated low severity because the browser-level defenses already block the attack vector [1][2].
Mitigation
The issue is fixed in React Router version 2.17.5 [1]. Users running Framework Mode with affected versions should upgrade to 2.17.5 or later. No workarounds are necessary for browser-based usage, as existing browser protections already mitigate the risk [1][2]. The vulnerability is not listed in the CISA Known Exploited Vulnerabilities catalog.
AI Insight generated on Jun 15, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected products
3- Range: >= 2.17.3, < 2.17.5
- ghsa-coords2 versions
>= 2.17.3, < 2.17.5+ 1 more
- (no CPE)range: >= 2.17.3, < 2.17.5
- (no CPE)range: >= 7.12.0, < 7.15.1
Patches
1aabd30c8d17fUse shared isMutationMethod check (#15033)
3 files changed · +23 −22
packages/react-router/.changes/patch.shared-mutation-check.md+1 −0 added@@ -0,0 +1 @@ +Internal refactor to consolidate mutation request detection through shared utility
packages/react-router/lib/rsc/server.rsc.ts+1 −1 modified@@ -850,7 +850,7 @@ async function generateRenderResponse( let formState: unknown; let skipRevalidation = false; let potentialCSRFAttackError: unknown | undefined; - if (request.method === "POST") { + if (isMutationMethod(request.method)) { try { throwIfPotentialCSRFAttack(request.headers, allowedActionOrigins);
packages/react-router/lib/server-runtime/server.ts+21 −21 modified@@ -15,6 +15,7 @@ import { createStaticHandler, isRedirectResponse, isResponse, + isMutationMethod, } from "../router/router"; import type { AppLoadContext } from "./data"; import type { HandleErrorFunction, ServerBuild } from "./build"; @@ -446,26 +447,25 @@ async function handleSingleFetchRequest( let handlerUrl = new URL(request.url); handlerUrl.pathname = normalizedPath; - let response = - request.method !== "GET" - ? await singleFetchAction( - build, - serverMode, - staticHandler, - request, - handlerUrl, - loadContext, - handleError, - ) - : await singleFetchLoaders( - build, - serverMode, - staticHandler, - request, - handlerUrl, - loadContext, - handleError, - ); + let response = isMutationMethod(request.method) + ? await singleFetchAction( + build, + serverMode, + staticHandler, + request, + handlerUrl, + loadContext, + handleError, + ) + : await singleFetchLoaders( + build, + serverMode, + staticHandler, + request, + handlerUrl, + loadContext, + handleError, + ); return response; } @@ -481,7 +481,7 @@ async function handleDocumentRequest( criticalCss?: CriticalCss, ) { try { - if (request.method === "POST") { + if (isMutationMethod(request.method)) { try { throwIfPotentialCSRFAttack( request.headers,
Vulnerability mechanics
Root cause
"CSRF protection was only applied to POST requests, leaving PUT, PATCH, and DELETE requests unguarded."
Attack vector
An attacker could craft a cross-origin `PUT`, `PATCH`, or `DELETE` request to a React Router v7 Framework Mode endpoint that performs state-changing actions. Because the CSRF validation (`throwIfPotentialCSRFAttack`) was only invoked for `POST` requests, these other mutation methods bypassed the check entirely [patch_id=6089177]. In practice, modern browser protections such as CORS preflight and SameSite cookies already block most cross-origin attack vectors, which is why this is rated low severity. The advisory notes that applications using Declarative Mode (`<BrowserRouter>`) or Data Mode (`createBrowserRouter`/`<RouterProvider>`) are not affected.
Affected code
The vulnerability exists in React Router v7 Framework Mode's server-side request handling. The files `packages/react-router/lib/server-runtime/server.ts` and `packages/react-router/lib/rsc/server.rsc.ts` previously only performed CSRF checks on `POST` requests, leaving `PUT`, `PATCH`, and `DELETE` requests unchecked. The patch replaces the `request.method === "POST"` check with a call to the shared `isMutationMethod()` utility, which correctly identifies all mutation HTTP methods.
What the fix does
The patch replaces the hard-coded `request.method === "POST"` check with the shared `isMutationMethod(request.method)` utility function in two locations: `handleSingleFetchRequest` and `handleDocumentRequest` in `server.ts`, and the RSC render response in `server.rsc.ts` [patch_id=6089177]. The `isMutationMethod` function returns `true` for `POST`, `PUT`, `PATCH`, and `DELETE`, ensuring that the CSRF guard (`throwIfPotentialCSRFAttack`) is now applied to all mutation HTTP methods rather than only `POST`. The commit message describes this as an internal refactor to consolidate mutation request detection.
Preconditions
- configThe application must be running in React Router v7 Framework Mode (not Declarative or Data Mode).
- networkThe attacker must be able to deliver a cross-origin request to a state-changing endpoint using PUT, PATCH, or DELETE.
Generated on Jun 15, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
2News mentions
0No linked articles in our index yet.