security: fix O(n) timing attack in findByToken #52
Open
Charon
wants to merge 1 commit from
feat/fix-token-timing-attack into dev
pull from: feat/fix-token-timing-attack
merge into: core:dev
core:dev
core:feat/test-workspace-controller
core:feat/workspace-ownership-transfer
core:feat/ide-helper-annotations
core:feat/test-namespace-service
core:feat/artisan-provision-command
core:feat/workspace-activity-audit-log
core:feat/bulk-workspace-invitations
core:feat/openapi-docs
core:feat/add-infection-mutation-testing
core:feat/fix-readme-namespaces
core:feat/test-entitlement-webhook-service
core:feat/invitation-and-role-improvements
core:feat/workspace-lazy-loading
core:feat/invitation-soft-deletes
core:feat/totp-edge-case-tests
core:feat/standardise-error-responses
core:feat/entitlement-exception-hierarchy
core:feat/consolidate-user-relationships-v2
core:feat/clarify-workspace-scope-architecture
core:feat/validate-invitation-token-format
core:feat/constrain-feature-code-fk
core:feat/fix-usage-race-condition
core:feat/add-workspace-role-index
core:feat/add-phpstan-larastan
core:feat/complete-user-stats-stubs
core:feat/fix-namespace-n-plus-1
core:feat/fix-parent-feature-cascade
core:feat/namespace-cascade-delete
core:feat/pin-core-dependency
core:feat/remove-hardcoded-domain
core:feat/test-workspace-team-service
core:feat/workspace-return-types
core:main
1 commit
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
dede803632
|
security: fix O(n) timing attack in findByToken (#9)
Add a SHA-256 token_hash lookup column to workspace_invitations so that findByToken and findPendingByToken can locate the candidate row with a single indexed SQL query instead of loading up to 1000 rows and running bcrypt against each one sequentially. The bcrypt hash in the token column is still verified after the O(1) lookup, preserving the existing security guarantee while eliminating both the timing side-channel and the performance bottleneck. Changes: - Migration to add nullable indexed token_hash column - Model booted() creating/updating events compute SHA-256 alongside bcrypt - findByToken/findPendingByToken rewritten to WHERE token_hash then Hash::check - HashInvitationTokens command updated to populate token_hash for existing rows Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |