fix(auth): implement real SEP-10 Ed25519 signature verification#1
Open
Iceeyyou2 wants to merge 1 commit into
Open
fix(auth): implement real SEP-10 Ed25519 signature verification#1Iceeyyou2 wants to merge 1 commit into
Iceeyyou2 wants to merge 1 commit into
Conversation
Closes #1 - challenge/route.ts: validate public key format (StrKey), generate nonce-based challenge, store server-side with 5-min TTL - verify/route.ts: consume stored challenge (TTL + replay protection), verify Ed25519 sig via Keypair.verify(), issue signed HS256 JWT - me/route.ts: validate JWT signature + expiry via verifyJwt() instead of only checking header presence - src/lib/auth/challenge-store.ts: in-process Map store with TTL and used-flag replay protection; _clearStore() for tests - src/lib/auth/jwt.ts: HS256 JWT sign/verify using Node crypto HMAC-SHA256 with timing-safe comparison; 24h token lifetime - 21 passing tests: challenge-store, jwt unit tests, SEP-10 integration tests covering valid sig, wrong keypair, bogus sig, replay, TTL expiry, tampered JWT, and expired JWT
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.
Summary
Fixes Issue #1 — the
/api/auth/verifyroute was issuing tokens for any public key without performing any cryptographic validation, allowing full account impersonation.Changes
src/lib/auth/challenge-store.ts(new)Server-side in-process challenge registry with:
usedflag; a secondconsumeChallenge()call returnsalready_used_clearStore()helper for deterministic test teardownsrc/lib/auth/jwt.ts(new)Minimal standards-compliant HS256 JWT implementation on top of Node's
cryptomodule (no external JWT library required):signJwt(publicKey)— produces a 24-hour token withsub,iat,expverifyJwt(token)— validates signature with timing-safe comparison, checks expiry, returns typed resultJWT_SECRETenv var (enforced in production; dev fallback supplied)src/app/api/auth/challenge/route.tsStrKey.isValidEd25519PublicKey()crypto.randomBytes(32)nonce-based challenge stringstoreChallenge()before returning it to the clienttokenfield from the responsesrc/app/api/auth/verify/route.tsBefore: issued a Base64 token from raw input with no verification.
After:
consumeChallenge()— rejects expired or already-used challengessignedChallengeand callsKeypair.verify(challengeBuffer, signatureBuffer)src/app/api/auth/me/route.tsBefore: returned hardcoded data as long as any
Authorizationheader was present.After: calls
verifyJwt()— rejects malformed, tampered, or expired tokens with the appropriate 401 message; extractssub(public key) from the verified payload.Tests (21 passing)
challenge-store.test.tsjwt.test.tssep10-auth.integration.test.tsAcceptance Criteria
verifyvalidates Ed25519 signature against stored challengeauth/mevalidates JWT signature, not just header presenceSecurity Notes
JWT_SECRETmust be set to a ≥ 32-character random value in production; the server throws at startup if it's missing or too short