You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
verifyChallenge in src/modules/auth/auth.service.ts:78 compares signedChallenge !== stored.challengeToken — a plain string comparison. It never decodes a Stellar transaction envelope, never verifies a cryptographic signature against the user's public key, and never checks time bounds.
Any client that echoes back the challenge token string passes authentication without needing a Stellar private key.
Impact
Complete authentication bypass — attackers can authenticate as any user without owning their Stellar key.
File
src/modules/auth/auth.service.ts:78
Suggested Fix
Replace string comparison with proper SEP-10 verification using the Stellar SDK:
Decode the transaction envelope
Verify the signature against the claimed public key
I'd like to work on this issue.
The verifyChallenge method in src/modules/auth/auth.service.ts:78 uses a plain string comparison (signedChallenge !== stored.challengeToken) instead of proper cryptographic verification. This means any client that simply echoes back the challenge token string bypasses authentication entirely — no Stellar private key required. This is a complete authentication bypass that allows attackers to impersonate any user on the platform.
My approach
Replace the naive string comparison with proper SEP-10 signature verification using the Stellar SDK's built-in helpers. The fix will decode the transaction envelope, verify the cryptographic signature against the claimed public key, validate time bounds to prevent replay attacks, and confirm the source account matches the authenticated user.
Implementation plan
Import Stellar SDK verification utilities
Add Transaction and TransactionBuilder imports from stellar-sdk
Add Keypair import for public key verification
Add time-bound checking utilities (e.g., DateTime from luxon if already in deps, or native Date)
Replace string comparison in verifyChallenge at line 78
Decode the signed challenge using Transaction.fromEnvelopeXDR() instead of comparing raw strings
Extract the signature from the decoded transaction using tx.signatures
Verify the signature matches the user's stored public key using Keypair.fromPublicKey(publicKey).verify(tx.hash(), signature)
Remove the signedChallenge !== stored.challengeToken comparison entirely
Add time-bound validation
After decoding the transaction envelope, check tx.timeBounds.minTime and tx.timeBounds.maxTime
Reject challenges where now < minTime or now > maxTime to prevent stale/replay attacks
Use a reasonable expiration window (e.g., 5 minutes) matching SEP-10 best practices
Verify source account matches
Confirm tx.source matches stored.publicKey (or the user's Stellar address from the database)
This prevents an attacker from using a legitimately signed SEP-10 challenge issued for a different account
Update tests for the new verification logic
Add test cases for valid SEP-10 signed challenges (should pass authentication)
Add test cases for expired challenges (should be rejected)
Add test cases for challenges signed by a different key (should be rejected)
Add test cases for malformed/invalid XDR envelopes (should be rejected gracefully)
Impact
Eliminates a complete authentication bypass that allows impersonation of any user without their private key.
Aligns the auth flow with the SEP-10 specification, the industry-standard authentication protocol for Stellar-based applications.
Prevents replay attacks through time-bound validation, ensuring stale challenges cannot be reused.
Establishes proper cryptographic verification as a foundation for all future auth-related features.
I'm ready to start immediately and can have a PR up within a reasonable timeline. Happy to adjust the plan if you have preferences on any of the details.
Activity
AbelOsaretin commentedon Jun 20, 2026
I'd like to work on this issue.
The verifyChallenge method in src/modules/auth/auth.service.ts:78 uses a plain string comparison (signedChallenge !== stored.challengeToken) instead of proper cryptographic verification. This means any client that simply echoes back the challenge token string bypasses authentication entirely — no Stellar private key required. This is a complete authentication bypass that allows attackers to impersonate any user on the platform.
My approach
Replace the naive string comparison with proper SEP-10 signature verification using the Stellar SDK's built-in helpers. The fix will decode the transaction envelope, verify the cryptographic signature against the claimed public key, validate time bounds to prevent replay attacks, and confirm the source account matches the authenticated user.
Implementation plan
Impact
I'm ready to start immediately and can have a PR up within a reasonable timeline. Happy to adjust the plan if you have preferences on any of the details.
grantfox-oss commentedon Jun 20, 2026
🦊 GrantFox — @AbelOsaretin has been assigned to this issue as part of the Official Campaign campaign!
Next steps:
Closes #24)Good luck! Track your progress on GrantFox.
grantfox-oss commentedon Jun 20, 2026
🎉 This issue has been marked as completed on GrantFox as part of the Official Campaign campaign!
@AbelOsaretin's PR #39 was approved and merged by @DeFiVC.
🏆 @AbelOsaretin: You earned 35 FoxPoints for this contribution! Your current tier: Explorer (223 total points). Track your full progress on GrantFox.
👏 Great work, @AbelOsaretin! Keep contributing to ChainLearnOfficial.