Thanks to visit codestin.com
Credit goes to github.com

Skip to content

fix(site/src): prevent protocol-relative login redirects - #27363

Merged
ThomasK33 merged 2 commits into
mainfrom
tk/codagt-783-remediate-cdm-02-001-login-redirect-sanitization-bypass
Aug 10, 2026
Merged

fix(site/src): prevent protocol-relative login redirects#27363
ThomasK33 merged 2 commits into
mainfrom
tk/codagt-783-remediate-cdm-02-001-login-redirect-sanitization-bypass

Conversation

@ThomasK33

@ThomasK33 ThomasK33 commented Jul 21, 2026

Copy link
Copy Markdown
Member

Summary

Hardens sanitizeRedirect in site/src/utils/redirect.ts against open redirects and adds regression coverage for Cure53 finding CDM-02-001 (coder/security-disclosures#164), a bypass of the prior fix for GHSA-wcx9-ccpj-hx3c.

Problem

sanitizeRedirect returned URL.pathname + URL.search and assumed a pathname is always a safe same-origin relative path. A parsed URL's pathname can itself start with // (via a percent-encoded slash, backslashes, or dot-segment normalization), and a string starting with // is a protocol-relative URL when assigned to location.href. The reported PoC /login?redirect=https://cure53.de/%2fcure53.de decodes once in retrieveRedirect, yields pathname //cure53.de, and redirects a password-authenticating user to an attacker origin. A dot-segment variant (redirect=/api/v2/../../..//evil.com) also passed the /api/v2 prefix check and redirected already-signed-in users on page load.

Fix

  • sanitizeRedirect now re-parses the candidate pathname + search against location.origin and falls back to / whenever the result would resolve to a different origin (verify-after-build instead of enumerating bad shapes). Unparsable URLs also fall back to / instead of throwing.
  • The signed-in <Navigate> fallback in LoginPage now goes through sanitizeRedirect as defense in depth.
  • Regression tests: utility-level matrix (encoded-slash PoC, /.//evil.com, tab stripping, dot-segment traversal, pinned already-safe shapes, invalid URLs) plus a LoginPage component test driving the full PoC through password sign-in.

Verification

  • pnpm test src/utils/redirect.test.ts src/pages/LoginPage/LoginPage.test.tsx: 23/23 passing on the rebased branch.
  • pnpm check and full pnpm lint (Biome, tsc, circular deps, React compiler, knip): clean.
  • Live browser verification against the Vite-rendered login page on the rebased HEAD:
    • PoC ?redirect=https://cure53.de/%2fcure53.de after password login lands on / (same origin), never cure53.de.
    • Signed-in ?redirect=/api/v2/../../..//evil.com lands on /, never evil.com.
    • Legitimate ?redirect=/workspaces still reaches /workspaces after login.

Refs: CODAGT-783, coder/security-disclosures#164, coder/security-disclosures#164


Generated with mux • Model: anthropic:claude-fable-5 • Thinking: max

Re-parse sanitized redirect paths against the deployment origin before
returning them. This rejects encoded and normalized paths that would be
interpreted as protocol-relative URLs when assigned to location.href.

Add utility and LoginPage regression coverage for Cure53 CDM-02-001,
including the reported encoded-slash PoC and related normalization
variants. Sanitize the React Router navigation sink as defense in depth.

---
_Generated with [`mux`](https://github.com/coder/mux) • Model: `anthropic:claude-mythos-5` • Thinking: `max`_
@ThomasK33 ThomasK33 added the experimental Changes that might not necessarily be merged, until its approved to proceed with. label Jul 21, 2026
@linear-code

linear-code Bot commented Jul 21, 2026

Copy link
Copy Markdown

CODAGT-783

SEC-263

@github-actions github-actions Bot added the stale This issue is like stale bread. label Aug 5, 2026
@github-actions github-actions Bot closed this Aug 9, 2026
@ThomasK33 ThomasK33 reopened this Aug 10, 2026
…te-cdm-02-001-login-redirect-sanitization-bypass

ThomasK33 commented Aug 10, 2026

Copy link
Copy Markdown
Member Author

Reopened after the stale-bot auto-close and brought the branch up to date with main (via merge, no history rewrite; the reviewed fix commit c9358dc is unchanged).

Revalidation on the updated branch (main @ cfeae56):

  • vitest run src/utils/redirect.test.ts src/pages/LoginPage/LoginPage.test.tsx: 23/23 passing
  • biome check --error-on-warnings .: clean (1899 files)
  • tsc -b: clean
  • Re-audited all location.href / redirect sinks under site/src on the updated tree: redirect-parameter consumption is still confined to LoginPage, and every sink goes through sanitizeRedirect
  • Extended attack matrix (34 hostile inputs: the reported PoC, protocol-relative //, \ variants, dot-segment traversal, encoded/tab/null-byte forms, opaque schemes like javascript:/data:, userinfo tricks) all resolve same-origin; 6 legitimate redirect shapes (including the /api/v2 and /oauth2/authorize flows) are preserved byte-for-byte

Also re-verified main still ships the vulnerable sanitizeRedirect, so this fix remains required.


Generated with mux • Model: anthropic:claude-fable-5 • Thinking: max

@ThomasK33
ThomasK33 marked this pull request as ready for review August 10, 2026 12:34
@ThomasK33 ThomasK33 removed experimental Changes that might not necessarily be merged, until its approved to proceed with. stale This issue is like stale bread. labels Aug 10, 2026
@ThomasK33
ThomasK33 merged commit 84f4a8b into main Aug 10, 2026
35 checks passed
@ThomasK33
ThomasK33 deleted the tk/codagt-783-remediate-cdm-02-001-login-redirect-sanitization-bypass branch August 10, 2026 13:35
@github-actions github-actions Bot locked and limited conversation to collaborators Aug 10, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants