mirror of
https://github.com/tiennm99/tiennm99bot.git
synced 2026-10-13 04:15:17 +00:00
fix(security): compare API token in constant time
Length-guarded timingSafeEqual avoids leaking token information through response timing on the auth path.
This commit is contained in:
1 parent
5048fff952
commit
ccb91adef4
1 file changed
+16
-1
@@ -1,8 +1,23 @@
|
||||
import {timingSafeEqual} from 'node:crypto';
|
||||
import {ZodError} from 'zod';
|
||||
import {isRenderTimeoutError} from '../lib/render-errors.js';
|
||||
import {pickWinnerIndex} from '../lib/winner.js';
|
||||
import {parseWheelRequest} from '../schemas/wheel-request.js';
|
||||
|
||||
/**
|
||||
* Length-guarded constant-time string comparison so token checks do not leak
|
||||
* information through response timing.
|
||||
*
|
||||
* @param {string} a
|
||||
* @param {string} b
|
||||
* @returns {boolean}
|
||||
*/
|
||||
const safeEqual = (a, b) => {
|
||||
const aBuffer = Buffer.from(a);
|
||||
const bBuffer = Buffer.from(b);
|
||||
return aBuffer.length === bBuffer.length && timingSafeEqual(aBuffer, bBuffer);
|
||||
};
|
||||
|
||||
/**
|
||||
* @typedef {import('../config.js').AppConfig} AppConfig
|
||||
* @typedef {import('../schemas/wheel-request.js').WheelRenderRequest} WheelRenderRequest
|
||||
@@ -31,7 +46,7 @@ export const registerGifRoute = async (app, deps) => {
|
||||
app.post('/api/gif', async (request, reply) => {
|
||||
if (deps.config.apiToken) {
|
||||
const expected = `Bearer ${deps.config.apiToken}`;
|
||||
if (request.headers.authorization !== expected) {
|
||||
if (!safeEqual(request.headers.authorization ?? '', expected)) {
|
||||
return reply.code(401).send({error: 'unauthorized'});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user