fix: remove early length exit from timingSafeEqStr
From the PR description
Summary
timingSafeEqStrreturnedfalseimmediately when string lengths differed, before callingcrypto.timingSafeEqual- violating the constant-time contract and creating a theoretical timing oracle- Fixed by always running the constant-time comparison first (on zero-padded buffers), then checking length equality afterward
- In practice, all SHA-256 base64url signatures are 43 characters so this gap has no real exploit path for standard tokens; this is a defense-in-depth fix for the pattern
Closes #72
Changes
backend/src/lib/downloadTokens.ts- early length check removed;timingSafeEqStrnow pads the shorter buffer and runstimingSafeEqualunconditionally before length verification; exported for testabilitybackend/src/lib/__tests__/timingSafeEq.test.ts- 5 unit tests
Test plan
- Unit tests: equal strings, same-length mismatch, different-length mismatch, empty strings
- Build and typecheck pass
Our analysis
Make timingSafeEqStr actually constant-time — read the full analysis →
Think the analysis missed something the PR description covers?
Capture this PR into my fork
Download a Markdown prompt that tells Claude how to port every
commit in this PR into your working tree. Run it via
claude -p < capture-pull-81.md from
inside the repo you want the changes in.