CVE-2026-33245 - React Router RSC redirect XSS

React Router v7 applications using the unstable React Server Components (RSC) APIs can expose client-side XSS when redirect targets are influenced by untrusted input. The affected range is narrow, but the exposure check is not: reviewers need to prove both the resolved package version and whether the app uses unstable RSC redirect handling with user-controlled return, next, callback, or continuation URLs.

The fix is to upgrade React Router. The recipe also asks for app-level redirect validation because future routing or framework changes should not make javascript:, data:, protocol-relative, or cross-origin redirect targets safe by accident.

When to use it

  • A repository deploys React Router v7 with unstable RSC APIs, server routes, server functions, loaders, actions, or redirect helpers.
  • Redirect targets can come from query parameters, forms, headers, cookies, identity-provider state, tenant config, CMS content, invite links, or payment callbacks.
  • Package locks, images, SBOMs, or generated reports may resolve react-router >=7.7.0, <7.13.2.
  • You need a bounded PR or triage note that upgrades React Router and proves user-controlled redirects are normalized and validated before Location.

Inputs

  • Package manifests, lockfiles, route modules, RSC adapters, Dockerfiles, deployment artifacts, SBOMs, generated dependency reports, and redirect utility code.
  • Redirect-bearing route inventory, trusted-origin policy, auth/OAuth/SAML state handling, tenant switching, invite/payment return behavior, and temporary fixed-landing-page containment.
  • Available package install, lint/typecheck, route tests, RSC/server tests, build, E2E smoke tests, SBOM, and dependency/security scans.

Affected versions

  • Vulnerable package: react-router >=7.7.0, <7.13.2
  • Fixed package: react-router 7.13.2+
  • Affected surface: unstable React Router RSC APIs and RSC redirect handling
  • Required application condition: redirect targets are derived from untrusted input such as query parameters, form fields, headers, cookies, tenant configuration, OAuth/SAML state, invite links, or CMS content
  • Not exposed: apps that do not use React Router’s unstable RSC APIs

Indicator-of-exposure

  • The repository deploys a React Router v7 app with react-router in the affected range.
  • The app enables unstable RSC APIs, RSC server adapters, RSC routes, or framework integrations that route through React Router’s RSC redirect path.
  • Route loaders, actions, server functions, auth callbacks, onboarding flows, payment returns, tenant switching, invite handling, or preview links call redirect() or return redirect responses from values influenced by users.
  • Existing redirect validation allows javascript:, data:, vbscript:, protocol-relative URLs, absolute cross-origin URLs, encoded control characters, backslash variants, or double-encoded targets.
  • Browser tests assert only the happy path and do not check rejected redirect targets.

Quick checks:

rg -n "\"react-router\"|@react-router|unstable_.*RSC|RSCHTTP|createCallServer|redirect\\(|redirectDocument\\(|returnTo|return_to|next=|callback|continue|destination|safeRedirect|isSafeRedirect|Location" .
npm ls react-router
pnpm why react-router
yarn why react-router

Windows:

rg -n "\"react-router\"|@react-router|unstable_.*RSC|RSCHTTP|createCallServer|redirect\(|redirectDocument\(|returnTo|return_to|next=|callback|continue|destination|safeRedirect|isSafeRedirect|Location" .
npm ls react-router
pnpm why react-router
yarn why react-router

Do not place executable script URLs in shared logs, telemetry, customer-facing preview links, or live routes during triage. Use inert local test strings and assert rejection before navigation.

Remediation strategy

  • Upgrade every controlled React Router package to 7.13.2+.
  • Refresh lockfiles, generated dependency reports, SBOMs, container layers, deployment artifacts, and package-manager metadata.
  • Inventory every redirect that can be influenced by users, tenants, identity providers, commerce providers, CMS content, or browser-controlled state.
  • Add a central redirect-target validator if one does not exist. Prefer same-origin relative paths or an explicit allowlist of trusted origins.
  • Reject scriptable schemes, protocol-relative URLs, encoded control characters, backslash-normalized hosts, and nested/double-encoded redirect values.
  • Add regression tests around unstable RSC redirect handling and any route that accepts returnTo, next, callback, redirect_uri, continue, or similar parameters.
  • If upgrade is blocked, disable unstable RSC redirects from untrusted values or force those paths to a fixed same-origin landing page until patched.

The prompt

You are remediating CVE-2026-33245 / GHSA-8646-j5j9-6r62, a React Router v7
unstable RSC redirect XSS issue. Produce exactly one output:

- A reviewer-ready PR/change request that upgrades React Router, proves whether
  unstable RSC redirect handling is exposed, validates untrusted redirect
  targets, adds regression tests, refreshes generated artifacts, and documents
  operator rollout notes, or
- TRIAGE.md if this repository does not own an affected React Router v7 app or
  does not use the unstable RSC APIs.

## Rules

- Scope only CVE-2026-33245 / GHSA-8646-j5j9-6r62 and directly related React
  Router RSC redirect validation.
- Treat cookies, sessions, OAuth/SAML state, invite tokens, tenant IDs, billing
  data, customer URLs, auth callback URLs, and browser telemetry as sensitive.
- Do not use live exploitable script URLs in production, shared preview links,
  logs, screenshots, analytics, or customer-facing tests.
- Do not remove auth, CSRF, tenant, invite, or payment-return checks to make
  redirect tests pass.
- Do not mark the app not exposed only because `react-router` is transitive;
  prove whether the deployable app uses unstable RSC APIs.
- Do not auto-merge.

## Steps

1. Inventory every React Router app, workspace, package manifest, lockfile,
   Docker image, deployment artifact, SBOM, and generated dependency report
   controlled by this repository.
2. Determine every resolved `react-router` version. A target is vulnerable if
   it resolves to `>=7.7.0, <7.13.2`.
3. Search for unstable RSC usage, RSC adapters, server routes, server
   functions, route loaders/actions, and redirect helpers.
4. Identify redirect inputs from query parameters, form bodies, headers,
   cookies, OAuth/SAML/OIDC state, invite links, tenant config, CMS content,
   payment provider callbacks, support links, and browser storage.
5. If the app does not use React Router unstable RSC APIs, stop with
   `TRIAGE.md` listing checked files, resolved versions, and why the affected
   path is absent.
6. Upgrade React Router to `7.13.2+`. Refresh package-manager locks,
   generated dependency reports, SBOMs, images, and deployment output.
7. Add or harden redirect validation:
   - allow same-origin relative paths by default;
   - allow absolute URLs only through an explicit trusted-origin allowlist;
   - reject `javascript:`, `data:`, `vbscript:`, `file:`, protocol-relative
     URLs, encoded control characters, backslash host confusion, and
     double-encoded redirect targets;
   - normalize before validation and validate again before emitting the final
     `Location` value.
8. Add regression tests for each exposed route class:
   - benign same-origin redirect is allowed;
   - scriptable schemes are rejected;
   - protocol-relative and cross-origin URLs are rejected unless allowlisted;
   - encoded and double-encoded variants are rejected;
   - unstable RSC redirect paths use the same validator as ordinary loaders or
     actions.
9. Add a PR body section named `CVE-2026-33245 operator actions` that states:
   - React Router versions before and after;
   - whether unstable RSC APIs are used;
   - which redirect-bearing routes were reviewed;
   - which redirect inputs are user controlled;
   - which regression tests cover scriptable and cross-origin targets;
   - whether any temporary fixed landing-page containment remains.
10. Run relevant validation: package install, lint, typecheck, unit tests,
    route tests, RSC/server tests, build, E2E tests where available, SBOM
    refresh, and dependency/security scans.
11. Use PR title:
    `fix(sec): remediate CVE-2026-33245 in React Router redirects`.

## Stop conditions

- No controlled deployable app resolves an affected `react-router` version.
- The app does not use React Router unstable RSC APIs; document evidence and
  route checks in `TRIAGE.md`.
- The affected app is supplied by another package, platform, or vendor outside
  repository ownership.
- A safe upgrade requires a broader router/framework migration that cannot fit
  inside this PR.
- Meaningful validation would require production sessions, live identity
  provider callbacks, customer URLs, or logging sensitive browser data.
- Validation fails for unrelated pre-existing reasons; document those failures
  instead of broadening scope.

Verification - what the reviewer looks for

  • No controlled package manifest, lockfile, image, SBOM, or dependency report resolves react-router >=7.7.0, <7.13.2.
  • The PR explicitly proves whether unstable RSC APIs are used.
  • User-controlled redirect inputs are normalized and validated through a shared safe path.
  • Tests reject scriptable schemes, protocol-relative URLs, cross-origin values, and encoded variants for the RSC redirect path.
  • The change does not weaken auth callbacks, tenant switching, payment return handling, CSRF protections, or invite flows.

Output contract

  • Reviewer-ready PR upgrading React Router to 7.13.2+ with refreshed locks, images, generated dependency reports, SBOMs, and deployment output.
  • Shared redirect validation that allows same-origin relative paths by default and rejects scriptable schemes, protocol-relative values, cross-origin values without allow-list approval, control characters, and double-encoded targets.
  • Regression tests covering benign redirects and malicious redirect variants through unstable RSC redirect paths and ordinary loaders/actions.
  • TRIAGE.md when the app does not use unstable RSC APIs or the affected runtime is outside repository ownership.

Watch for

  • Treating this as a generic npm bump and skipping RSC usage checks.
  • Only testing browser navigation while server redirect responses still emit unsafe Location values.
  • Validating the first decoded value but redirecting a later decoded value.
  • Allowing cross-origin redirects from tenant or identity-provider fields without an owner-approved allowlist.
  • Forgetting generated lockfiles, deployment artifacts, Docker layers, or SBOMs.

References