fix(auth): constant-time owner-token comparison

Owner bearer token was compared with === / !==, which short-circuits on the
first differing byte and leaks token length+prefix via response timing
(security-sweep-2026-06-01.md). New timingSafeStrEqual (crypto.timingSafeEqual
with a length pre-check so it never throws on length mismatch); wired into both
owner.js and agent_auth.js.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
root
2026-06-01 23:26:46 +10:00
parent c591b2aed1
commit 459a7749c9
4 changed files with 56 additions and 2 deletions

View File

@@ -1,3 +1,5 @@
import { timingSafeStrEqual } from './safe_compare.js';
export function ownerOnly(req, res, next) {
const expected = process.env.OWNER_TOKEN;
if (!expected) {
@@ -7,7 +9,7 @@ export function ownerOnly(req, res, next) {
}
const auth = req.headers.authorization || '';
const [scheme, token] = auth.split(' ');
if (scheme !== 'Bearer' || token !== expected) {
if (scheme !== 'Bearer' || !timingSafeStrEqual(token, expected)) {
return res.status(401).json({
error: { code: 'unauthorized', message: 'invalid token' }
});