Summary
API tokens and ingest secrets are stored as plain SHA-256 hashes without per-credential salt or a slow KDF. Secret comparisons use non-constant-time equality checks.
Severity
Medium
Context
From full-codebase security review (2026-07-11). Priority remediation item #5.
Affected areas
apps/api/src/application/auth.ts:5-11 — SHA-256 hashing
apps/api/src/application/auth.ts:39-47 — bootstrap token compared with ===
apps/api/src/application/tokens.ts:52-53 — token hash storage
apps/api/src/application/ingest.ts:349-354 — ingest secret verification via Array.find + ===
apps/api/src/application/endpoints.ts:336 — endpoint secret hashing
Risk
- Database leak enables faster offline hash comparison attacks
- Timing side channels on secret/token verification (lower practical risk with high-entropy secrets, but worth hardening)
- Bootstrap token comparison is especially sensitive if the token is weak
Recommendations
- Use a slow KDF (e.g. PBKDF2, scrypt, or Argon2 via Web Crypto) with per-record salt for stored hashes
- Compare fixed-length digests with constant-time equality (
crypto.subtle.timingSafeEqual or equivalent)
- For multiple active ingest secrets, compare all hashes in constant time without early exit
- Enforce strong bootstrap secret length/entropy; disable bootstrap in production after initial provisioning
Acceptance criteria
References
- Security review findings: unsalted SHA-256, non-constant-time comparisons
- Related spec:
requirements/barestash-backend.spec.md
Summary
API tokens and ingest secrets are stored as plain SHA-256 hashes without per-credential salt or a slow KDF. Secret comparisons use non-constant-time equality checks.
Severity
Medium
Context
From full-codebase security review (2026-07-11). Priority remediation item #5.
Affected areas
apps/api/src/application/auth.ts:5-11— SHA-256 hashingapps/api/src/application/auth.ts:39-47— bootstrap token compared with===apps/api/src/application/tokens.ts:52-53— token hash storageapps/api/src/application/ingest.ts:349-354— ingest secret verification viaArray.find+===apps/api/src/application/endpoints.ts:336— endpoint secret hashingRisk
Recommendations
crypto.subtle.timingSafeEqualor equivalent)Acceptance criteria
References
requirements/barestash-backend.spec.md