{"id":"GHSA-f46r-rw29-r322","summary":"React Router allows a DoS via cache poisoning by forcing SPA mode","details":"## Summary\nAfter some research, it turns out that it is possible to force an application to switch to SPA mode by adding a header to the request. If the application uses SSR and is forced to switch to SPA, this causes an error that completely corrupts the page. If a cache system is in place, this allows the response containing the error to be cached, resulting in a cache poisoning that strongly impacts the availability of the application.\n\n## Details\nThe vulnerable header is `X-React-Router-SPA-Mode`; adding it to a request sent to a page/endpoint using a loader throws an error. Here is [the vulnerable code](https://github.com/remix-run/react-router/blob/e6c53a0130559b4a9bd47f9cf76ea5b08a69868a/packages/react-router/lib/server-runtime/server.ts#L407) :\n\n\u003cimg width=\"672\" alt=\"Capture d’écran 2025-04-07 à 08 28 20\" src=\"https://github.com/user-attachments/assets/0a0e9c41-70fd-4dba-9061-892dd6797291\" /\u003e\n\nTo use the header, React-router must be used in Framework mode, and for the attack to be possible the target page must use a loader.\n\n## Steps to reproduce \nVersions used for our PoC: \n- \"@react-router/node\": \"^7.5.0\",\n- \"@react-router/serve\": \"^7.5.0\",\n- \"react\": \"^19.0.0\"\n- \"react-dom\": \"^19.0.0\"\n- \"react-router\": \"^7.5.0\"\n\n1. Install React-Router with its default configuration in Framework mode (https://reactrouter.com/start/framework/installation)\n2. Add a simple page using a loader (example: `routes/ssr`)\n\n![image](https://github.com/user-attachments/assets/d7d04e86-c549-4f4a-9200-2d1b6ac96aad)\n\n3. Send a request to the endpoint using the loader (`/ssr` in our case) adding the following header:\n```\nX-React-Router-SPA-Mode: yes\n```\n\nNotice the difference between a request with and without the header;\n\n**Normal request**\n![Capture d’écran 2025-04-07 à 08 36 27](https://github.com/user-attachments/assets/da372b70-7c68-41c1-aac1-e5be94f22526)\n\n**With the header**\n![Capture d’écran 2025-04-07 à 08 37 01](https://github.com/user-attachments/assets/98101720-cb5b-44e9-bff5-463c0b4dab2a)\n![image](https://github.com/user-attachments/assets/c16a101e-688c-4757-9e05-61308ed8a2de)\n\n## Impact\nIf a system cache is in place, it is possible to poison the response by completely altering its content (*by an error message*), strongly impacting its availability, making the latter impractical via a cache-poisoning attack.\n\n## Credits\n- Rachid Allam (zhero;)\n- Yasser Allam (inzo_)","aliases":["CVE-2025-43864"],"modified":"2025-04-25T14:32:54Z","published":"2025-04-24T16:31:16Z","database_specific":{"github_reviewed":true,"github_reviewed_at":"2025-04-24T16:31:16Z","nvd_published_at":"2025-04-25T01:15:43Z","cwe_ids":["CWE-755"],"severity":"HIGH"},"references":[{"type":"WEB","url":"https://github.com/remix-run/react-router/security/advisories/GHSA-f46r-rw29-r322"},{"type":"ADVISORY","url":"https://nvd.nist.gov/vuln/detail/CVE-2025-43864"},{"type":"WEB","url":"https://github.com/remix-run/react-router/commit/c84302972a152d851cf5dd859ff332b354b70111"},{"type":"PACKAGE","url":"https://github.com/remix-run/react-router"},{"type":"WEB","url":"https://github.com/remix-run/react-router/blob/e6c53a0130559b4a9bd47f9cf76ea5b08a69868a/packages/react-router/lib/server-runtime/server.ts#L407"}],"affected":[{"package":{"name":"react-router","ecosystem":"npm","purl":"pkg:npm/react-router"},"ranges":[{"type":"SEMVER","events":[{"introduced":"7.2.0"},{"fixed":"7.5.2"}]}],"database_specific":{"last_known_affected_version_range":"\u003c= 7.5.1","source":"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2025/04/GHSA-f46r-rw29-r322/GHSA-f46r-rw29-r322.json"}}],"schema_version":"1.9.0","severity":[{"type":"CVSS_V3","score":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H"}]}