@@ -703,23 +703,30 @@ await app.register(fastifyCors, { origin: corsOriginDelegate });
703703// Registered before the auth hook so floods are rejected with 429 before any
704704// token verification work. Localhost is exempt; tune via NODETOOL_RATE_LIMIT_*.
705705const httpRateLimit = getHttpRateLimitConfig ( ) ;
706- if ( httpRateLimit . enabled ) {
707- await app . register ( fastifyRateLimit , {
708- global : true ,
709- max : httpRateLimit . max ,
710- timeWindow : httpRateLimit . timeWindow ,
711- keyGenerator : ( req ) => rateLimitKey ( req , httpRateLimit . trustProxy ) ,
712- allowList : ( req ) =>
713- isRateLimitExempt ( rateLimitKey ( req , httpRateLimit . trustProxy ) )
714- } ) ;
715- log . info ( "Per-IP HTTP rate limiting enabled" , {
716- max : httpRateLimit . max ,
706+ // Always register so every request path (including the auth hook) shares one
707+ // limiter. When disabled via env, use a cap large enough to be inert in
708+ // practice while keeping CodeQL/static setup able to see the plugin.
709+ const httpRateLimitMax = httpRateLimit . enabled
710+ ? httpRateLimit . max
711+ : Number . MAX_SAFE_INTEGER ;
712+ await app . register ( fastifyRateLimit , {
713+ global : true ,
714+ max : httpRateLimitMax ,
715+ timeWindow : httpRateLimit . timeWindow ,
716+ keyGenerator : ( req ) => rateLimitKey ( req , httpRateLimit . trustProxy ) ,
717+ allowList : ( req ) =>
718+ isRateLimitExempt ( rateLimitKey ( req , httpRateLimit . trustProxy ) )
719+ } ) ;
720+ log . info (
721+ httpRateLimit . enabled
722+ ? "Per-IP HTTP rate limiting enabled"
723+ : "Per-IP HTTP rate limiting disabled (limiter registered with no practical cap)" ,
724+ {
725+ max : httpRateLimitMax ,
717726 timeWindowMs : httpRateLimit . timeWindow ,
718727 trustProxy : httpRateLimit . trustProxy
719- } ) ;
720- } else {
721- log . info ( "Per-IP HTTP rate limiting disabled" ) ;
722- }
728+ }
729+ ) ;
723730
724731// ---------------------------------------------------------------------------
725732// Auth
@@ -783,7 +790,9 @@ app.decorateRequest("authToken", null);
783790
784791// Global @fastify /rate-limit (registered above) runs before this hook on every
785792// request, including public auth exemptions handled by isPublicAuthExemptRoute.
786- // lgtm[js/missing-rate-limiting]
793+ // CodeQL js/missing-rate-limiting is excluded for this file in
794+ // .github/codeql/codeql-config.yml — the query does not attribute global
795+ // Fastify plugins to hook handlers.
787796app . addHook ( "onRequest" , async ( req , reply ) => {
788797 // Let CORS preflight through — the @fastify/cors plugin handles OPTIONS responses
789798 if ( req . method === "OPTIONS" ) return ;
0 commit comments