From 69db1d5558603aef60ad277e518f2769d8b06865 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=20Jurmanovi=C4=87?= Date: Wed, 12 Aug 2026 21:00:44 +0200 Subject: [PATCH] Harden auth hook and fix eslint config for intentional unused args - authHook: use crypto.timingSafeEqual for the bearer token comparison instead of !==, avoiding a timing side-channel on the secret key. - .eslintrc.cjs: add argsIgnorePattern for underscore-prefixed unused params, fixing false-positive no-unused-vars errors on intentional _ctx/_params placeholders used throughout the LlmTool hierarchy. --- .eslintrc.cjs | 3 +++ src/core/server/authHook.ts | 13 ++++++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/.eslintrc.cjs b/.eslintrc.cjs index 1203f23..3a840a0 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -6,4 +6,7 @@ module.exports = { env: { node: true, es2022: true }, parserOptions: { ecmaVersion: 2022, sourceType: 'module' }, ignorePatterns: ['dist', 'node_modules'], + rules: { + '@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_' }], + }, }; diff --git a/src/core/server/authHook.ts b/src/core/server/authHook.ts index b864d23..48da601 100644 --- a/src/core/server/authHook.ts +++ b/src/core/server/authHook.ts @@ -1,5 +1,15 @@ +import { timingSafeEqual } from 'node:crypto'; import type { FastifyInstance, FastifyReply, FastifyRequest } from 'fastify'; +function safeEqual(a: string, b: string): boolean { + const bufA = Buffer.from(a); + const bufB = Buffer.from(b); + if (bufA.length !== bufB.length) { + return false; + } + return timingSafeEqual(bufA, bufB); +} + export function registerAuthHook( app: FastifyInstance, secretKey: string, @@ -12,8 +22,9 @@ export function registerAuthHook( } const header = request.headers.authorization ?? ''; const token = header.startsWith('Bearer ') ? header.slice('Bearer '.length) : undefined; - if (token !== secretKey) { + if (token === undefined || !safeEqual(token, secretKey)) { reply.code(401).send({ error: 'unauthorized' }); + return; } }); }