fix(auth): fail closed on unparseable SIWE Not Before / Expiration - #8875
Conversation
Invalid Date comparisons are always false in JS, so unparseable invalid_before / expiration_time previously skipped time bounds while signature verification still ran. Signed-off-by: Sasha Mitchell <sash.t.mitchell@gmail.com>
🦋 Changeset detectedLatest commit: 0e5b6b3 The changes in this PR will be included in the next version bump. This PR includes changesets to release 4 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
|
@SashaMIT is attempting to deploy a commit to the thirdweb Team on Vercel. A member of the Team first needs to authorize it. |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
WalkthroughLogin payload verification now rejects unparseable ChangesLogin payload validation
Estimated code review effort: 2 (Simple) | ~10 minutes Mergeability Score: ⚪ Minimal · up to The change rejects unparseable SIWE time bounds instead of allowing them to bypass validation; no actionable merge-blocking risk remains after normal checks and review. 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches 💡 1🛠️ Fix failing CI checks 💡
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
* fix(siwe): reject unparseable expirationTime and notBefore Invalid Date values from parseSiweMessage (e.g. Expiration Time: never) are truthy, so comparisons like `time >= expirationTime` are always false and lifetime / nbf checks were skipped. Fail closed when either field is present but not a real date (sibling of thirdweb-dev/js#8875 / supabase/auth#2688). * fix(siwe): require EIP-4361 date-time strings and reject invalid time Validate raw SIWE timestamps against the RFC 3339 profile before Date coercion, and fail closed when the caller-supplied time is invalid so lifetime comparisons cannot be skipped. * fix(siwe): inline date validation --------- Co-authored-by: jxom <7336481+jxom@users.noreply.github.com>
* feat: add block header watcher (#4999) * fix: complete block header watcher integration (#5001) * chore: version package (#5000) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> * fix(tempo): bind encrypted deposits to sender (#5002) * fix(tempo): bind encrypted deposits to sender Co-authored-by: Derek Cofausper <256792747+decofe@users.noreply.github.com> * ci: test sender-bound zone deposits * ci: align Tempo and Zone fixtures * test(tempo): routed T10 fixtures through encrypted deposits * chore: logged local Zone provisioning stall * chore: ignored unpatched extract-zip advisory * fix(tempo): defaulted encrypted deposit sender * ci: skipped Wagmi verification * chore: remove friction log --------- Co-authored-by: 0xrusowsky <90208954+0xrusowsky@users.noreply.github.com> Co-authored-by: Derek Cofausper <256792747+decofe@users.noreply.github.com> Co-authored-by: Steven Truong <struong@users.noreply.github.com> Co-authored-by: jxom <7336481+jxom@users.noreply.github.com> * chore: version package (#5003) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> * fix(siwe): reject unparseable expirationTime and notBefore (#4990) * fix(siwe): reject unparseable expirationTime and notBefore Invalid Date values from parseSiweMessage (e.g. Expiration Time: never) are truthy, so comparisons like `time >= expirationTime` are always false and lifetime / nbf checks were skipped. Fail closed when either field is present but not a real date (sibling of thirdweb-dev/js#8875 / supabase/auth#2688). * fix(siwe): require EIP-4361 date-time strings and reject invalid time Validate raw SIWE timestamps against the RFC 3339 profile before Date coercion, and fail closed when the caller-supplied time is invalid so lifetime comparisons cannot be skipped. * fix(siwe): inline date validation --------- Co-authored-by: jxom <7336481+jxom@users.noreply.github.com> * fix: asset discovery in `simulateCalls` (#4997) * fix(simulateCalls): discover assets from simulated logs * refactor(simulateCalls): align asset discovery with repo conventions * fix(simulateCalls): pin both asset-tracing passes to one base block * test(simulateCalls): skip asset tracing on the pinned Anvil * chore: update accessListHints comment * fix(simulateCalls): preserve block tags and request errors * fix(simulateCalls): harden asset trace discovery * test: use reth for mainnet forks * test(simulateCalls): run asset tracing against reth * fix(simulateCalls): align asset trace simulations * fix(simulateCalls): stabilize asset tracing * chore: add static call source * fix(simulateCalls): simplify asset tracing * fix(simulateCalls): isolate asset balance probes * fix(simulateCalls): align asset probe callers * fix(simulateCalls): preserve pending block tag * fix(simulateCalls): normalize transfer topics * refactor(simulateCalls): remove redundant asset deduplication * test(simulateCalls): cover asset tracing edge cases * docs(simulateCalls): describe pending asset tracing --------- Co-authored-by: jxom <7336481+jxom@users.noreply.github.com> * fix: update nanoid security override * fix: increase package size limits * ci: remove docs deployment --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: struong <steven@tempo.xyz> Co-authored-by: 0xrusowsky <90208954+0xrusowsky@users.noreply.github.com> Co-authored-by: Derek Cofausper <256792747+decofe@users.noreply.github.com> Co-authored-by: Steven Truong <struong@users.noreply.github.com> Co-authored-by: Sash <sash@ela.city> Co-authored-by: Ghadi <92851745+Ghadi8@users.noreply.github.com>
Summary
verifyLoginPayloadcomparedcurrentDatetonew Date(invalid_before)/new Date(expiration_time).Invalid Dateare always false, so unparseable times skipped Not Before / Expiration checks while signature verification still ran.Number.isNaN(date.getTime()).Test plan
pnpm exec vitest run src/auth/core/verify-login-payload.test.ts(5 passed), including unparseablenever/ empty string casesMade with Cursor
PR-Codex overview
This PR focuses on enhancing the validation of SIWE login payloads by rejecting those with unparseable
Not BeforeorExpiration Timevalues, ensuring stricter adherence to time-bound checks.Detailed summary
invalid_beforeandexpiration_timeinverify-login-payload.ts.expiration_timeandinvalid_beforeinverify-login-payload.test.ts.Summary by CodeRabbit
Bug Fixes
Tests