Repository navigation
fix: close open redirect, JWT cache leak, wallet banner, and security headers - #669
Merged
DeFiVC merged 5 commits intoOct 23, 2026
Conversation
Validate that the redirect query parameter is a same-origin relative path before using it as a post-login destination. Absolute URLs, protocol-relative URLs, and backslash variants now fall back to /dashboard so authenticated users cannot be phished via /connect. Closes ChainLearnOfficial#541
Cache keys previously embedded the raw JWT, so tokens could surface in heap dumps and memory snapshots. Replace the token with a 64-bit non-cryptographic digest so keying stays deterministic per token but the credential itself is no longer retained in cache key strings. Closes ChainLearnOfficial#542
Ship Strict-Transport-Security in production and isolate the browsing context with Cross-Origin-Opener-Policy, Cross-Origin-Embedder-Policy, and Cross-Origin-Resource-Policy so first-visit MITM and cross-origin process isolation gaps are closed. Closes ChainLearnOfficial#544
The error banner always linked to Freighter even when the user had chosen LOBSTR or Rabet. Resolve the selected provider and link to that wallet's install page, falling back to a generic list of Freighter, LOBSTR, and Rabet when the provider is unknown. Closes ChainLearnOfficial#540
❌ Deploy Preview for chainlearn failed.
|
4 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #540, Closes #541, Closes #542, Closes #544
Type of Change
Summary
This PR resolves four Stellar Wave issues: an open-redirect vulnerability in middleware, raw JWTs leaking into API cache keys, a wallet error banner that always linked to Freighter, and missing HSTS/COOP/COEP/CORP security headers. Each fix is scoped to the files named in its issue.
Motivation / Context
redirectwas assigned tourl.pathnameunvalidated, allowing/connect?redirect=https://evil.comto bounce signed-in users to a phishing site.cacheKeyconcatenated the full JWT, so credentials could appear in heap dumps and memory snapshots.not_installedwere sent to install Freighter.Closes #540, Closes #541, Closes #542, Closes #544
Changes
src/middleware.tsisSafeRedirectPath— only same-origin relative paths (/…, no//, no://, no\) are honoured; anything else falls back to/dashboard.src/middleware.test.tssrc/lib/api/client.tshashJwtForCacheKey(dual FNV-1a, 64-bit) replaces the raw JWT incacheKey. Exported for tests.src/lib/api/client.test.tsnext.config.mjsCross-Origin-Opener-Policy: same-origin,Cross-Origin-Embedder-Policy: credentialless,Cross-Origin-Resource-Policy: same-origin, and production-onlyStrict-Transport-Security: max-age=63072000; includeSubDomains; preload.src/components/shared/wallet-error-banner.tsxgetSelectedWalletId()and links to Freighter, LOBSTR, or Rabet install pages; unknown/null selection lists all three.Testing
src/middleware.test.ts(6 cases) andsrc/lib/api/client.test.ts(4 cases).https://evil.com,http://evil.com/phish,//evil.com,/\evil.com, empty) and safe paths; JWT absence from cache keys, hash determinism/token discrimination, and per-token hit/miss.npm run lint,npm run typecheck,npm test,npm run build) is the verification gate for this PR — tests were authored against the existing vitest patterns in those files.Tradeoffs
cacheKey.Cross-Origin-Resource-Policy: same-originin addition to the Scope headers because the issue's "What" lists it and the acceptance criteria require all listed headers. HSTS is production-only so local HTTP development keeps working.Out of scope
src/app/(auth)/connect/page.tsxalso readsredirectclient-side (router.push(redirect || "/dashboard")). Left unchanged — Fix open redirect vulnerability in middleware #541 scopes the fix tosrc/middleware.ts.use-auth.tsstill has Freighter-specific copy for the inlinenot_installedmessage. Update wallet error banner for multi-wallet support #540 scopes the change towallet-error-banner.tsx.