Skip to content

fix: remove early length exit from timingSafeEqStr#81

Open
bmersereau wants to merge 3 commits into
willchen96:mainfrom
bmersereau:fix/72-timing-safe-eq
Open

fix: remove early length exit from timingSafeEqStr#81
bmersereau wants to merge 3 commits into
willchen96:mainfrom
bmersereau:fix/72-timing-safe-eq

Conversation

@bmersereau
Copy link
Copy Markdown

Summary

  • timingSafeEqStr returned false immediately when string lengths differed, before calling crypto.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; timingSafeEqStr now pads the shorter buffer and runs timingSafeEqual unconditionally before length verification; exported for testability
  • backend/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

Dshamir added a commit to Dshamir/AI-Legal that referenced this pull request May 24, 2026
…email

- downloadTokens: pad buffers to equal length before timingSafeEqual
  to eliminate length-oracle side channel (PR willchen96#81)
- keyRotation: add HKDF key derivation with random 16-byte per-row
  salt; existing rows without salt decrypt via legacy SHA-256 path;
  all new encryptions use HKDF (PR willchen96#76)
- projects: use case-insensitive comparison for shared_with email
  in GET /projects/:projectId, matching access.ts pattern (PR willchen96#79)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Dshamir added a commit to Dshamir/AI-Legal that referenced this pull request May 24, 2026
…tegration

- CHANGELOG: add security hardening and feature entries for PRs willchen96#158,
  willchen96#81, willchen96#76, willchen96#79, willchen96#145, willchen96#112, willchen96#111, willchen96#110, willchen96#155, willchen96#157, willchen96#59
- ROADMAP: mark 12 new items as completed
- CLAUDE.md: add sanitize.ts, streamTimeout.ts, credits.ts to lib index,
  update test count to 40
- README: update API endpoints table (chat pagination, workflow export),
  security row (HKDF, RLS, prompt defense), encryption row

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
amal66 added a commit to amal66/mike that referenced this pull request May 25, 2026
Chapter: 04 - Runtime safety basics.

Plain-English map:
Validate required environment variables at startup, reuse Supabase and storage
clients instead of recreating them per request, and remove a timing leak from
download-token comparison.

Why it matters:
Bad configuration should be caught before users hit the app. Shared clients
avoid needless connection churn. Secret checks should not reveal clues through
response timing.

Principle:
Fail fast, reuse expensive resources, and compare secrets in constant time.

Precedent borrowed:
Upstream PRs willchen96#81, willchen96#106, and willchen96#109, which independently targeted timing-safe
comparison, env validation, and singleton client reuse.

Upstream base: willchen96/mike@d39f580.
Original local commit: c2d2a9a.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Security][Low] Timing oracle in download token verification — early length exit before constant-time compare

1 participant