fix: sanitize error responses to prevent internal detail leakage

Add sanitizeError() helper that strips file paths, stack traces, SQLite
errors, and system errors from messages before returning them to clients.
Applied to all route-level catch blocks in payments, queue, fights, and
admin routes. Includes 12 tests for the sanitizer and static analysis
test verifying no route files leak raw err.message.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Dorian
2026-03-13 09:46:38 +00:00
co-authored by Claude Opus 4.6
parent 1b1f9eb2d7
commit 9b0d251d1c
8 changed files with 198 additions and 12 deletions
+6 -4
View File
@@ -4,7 +4,7 @@ import { eq } from 'drizzle-orm'
import { joinQueue, leaveQueue, getQueueSize, getQueueSnapshot } from '../engine/queue.js'
import { joinRankedQueue, getRankedQueueStatus } from '../engine/ranked-queue.js'
import { rateLimit } from '../middleware/rate-limit.js'
import { joinRankedSchema } from '../lib/validators.js'
import { joinRankedSchema, sanitizeError } from '../lib/validators.js'
export const queueRouter = new Hono()
@@ -33,8 +33,10 @@ queueRouter.post('/join/:botId', async (c) => {
const fightId = await joinQueue(botId)
return c.json({ fightId, message: 'Matched! Fight starting.' })
} catch (err: any) {
const message = err instanceof Error ? err.message : 'Queue error'
const status = message.includes('already in a fight') ? 409 : 500
const raw = err instanceof Error ? err.message : ''
const isConflict = raw.includes('already in a fight')
const message = isConflict ? raw : sanitizeError(err, 'Queue error')
const status = isConflict ? 409 : 500
return c.json({ error: message, fightId: err?.fightId || undefined }, status)
}
})
@@ -76,7 +78,7 @@ queueRouter.post('/join-ranked/:botId', async (c) => {
const fightId = await joinRankedQueue(botId, paymentId)
return c.json({ fightId, message: 'Ranked match found! Fight starting.' })
} catch (err) {
const message = err instanceof Error ? err.message : 'Ranked queue error'
const message = sanitizeError(err, 'Ranked queue error')
return c.json({ error: message }, 500)
}
})