test: add timing attack tests for bot-auth and use timingSafeEqual
Replace manual XOR loop with Node's native crypto.timingSafeEqual for constant-time secret comparison. Add tests verifying identical error messages for wrong secrets and <1ms response time variance across 100 requests. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
5bf557ba6a
commit
9de47fd760
@@ -2,7 +2,7 @@
|
||||
// Verifies bot identity via bot_id + secret (SHA256 hash comparison).
|
||||
// Supports: Authorization header or query params.
|
||||
|
||||
import { createHash } from 'crypto'
|
||||
import { createHash, timingSafeEqual } from 'crypto'
|
||||
import { db, schema } from '../db/index.js'
|
||||
import { eq } from 'drizzle-orm'
|
||||
import type { Context } from 'hono'
|
||||
@@ -55,16 +55,10 @@ export async function authenticateBot(c: Context): Promise<BotAuthContext | Resp
|
||||
return c.json({ error: 'Invalid bot_id or secret.' }, 401)
|
||||
}
|
||||
|
||||
// Constant-time comparison
|
||||
// Constant-time comparison using Node's native timingSafeEqual
|
||||
const expected = rows[0].secretHash
|
||||
if (hash.length !== expected.length) {
|
||||
return c.json({ error: 'Invalid bot_id or secret.' }, 401)
|
||||
}
|
||||
let mismatch = 0
|
||||
for (let i = 0; i < hash.length; i++) {
|
||||
mismatch |= hash.charCodeAt(i) ^ expected.charCodeAt(i)
|
||||
}
|
||||
if (mismatch !== 0) {
|
||||
if (hash.length !== expected.length ||
|
||||
!timingSafeEqual(Buffer.from(hash), Buffer.from(expected))) {
|
||||
return c.json({ error: 'Invalid bot_id or secret.' }, 401)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user