Skip to content

fix: close open redirect, JWT cache leak, wallet banner, and security headers - #669

Merged
DeFiVC merged 5 commits into
ChainLearnOfficial:mainfrom
trustosaretin:fix/stellar-wave-540-541-542-544
Oct 23, 2026
Merged

DeFiVC merged 5 commits into
ChainLearnOfficial:mainfrom
trustosaretin:fix/stellar-wave-540-541-542-544

Conversation

@trustosaretin

Copy link
Copy Markdown
Contributor

Closes #540, Closes #541, Closes #542, Closes #544

Type of Change

  • Bug fix (non-breaking change that fixes an issue)
  • New feature (non-breaking change that adds functionality)

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

Closes #540, Closes #541, Closes #542, Closes #544

Changes

Issue File Change
#541 src/middleware.ts Added isSafeRedirectPath — only same-origin relative paths (/…, no //, no ://, no \) are honoured; anything else falls back to /dashboard.
#541 src/middleware.test.ts Tests for absolute http/https, protocol-relative, backslash, empty, and safe relative redirect values.
#542 src/lib/api/client.ts hashJwtForCacheKey (dual FNV-1a, 64-bit) replaces the raw JWT in cacheKey. Exported for tests.
#542 src/lib/api/client.test.ts Asserts the raw token is absent from the digest, hashing is deterministic, and per-token cache hit/miss is unchanged.
#544 next.config.mjs Added Cross-Origin-Opener-Policy: same-origin, Cross-Origin-Embedder-Policy: credentialless, Cross-Origin-Resource-Policy: same-origin, and production-only Strict-Transport-Security: max-age=63072000; includeSubDomains; preload.
#540 src/components/shared/wallet-error-banner.tsx Resolves the selected wallet via getSelectedWalletId() and links to Freighter, LOBSTR, or Rabet install pages; unknown/null selection lists all three.

Testing

  • New unit tests added in src/middleware.test.ts (6 cases) and src/lib/api/client.test.ts (4 cases).
  • Coverage: malicious redirect values (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.
  • CI (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

Out of scope

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
@netlify

netlify Bot commented Oct 23, 2026 •

Copy link
Copy Markdown

❌ Deploy Preview for chainlearn failed.

Name Link
🔨 Latest commit dc56af1
🔍 Latest deploy log https://app.netlify.com/projects/chainlearn/deploys/6adbab8bbdee1cd79aa9d7f8

@DeFiVC
DeFiVC merged commit 9dde26f into ChainLearnOfficial:main Oct 23, 2026
0 of 3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants