Merge pull request #21700 from hvitved/js/fastify-per-route-rate-limiting

JS: Recognize Fastify per-route rate limiting
This commit is contained in:
Tom Hvitved
2026-04-13 17:28:34 +02:00
committed by GitHub
4 changed files with 46 additions and 0 deletions

View File

@@ -191,3 +191,21 @@ class RouteHandlerLimitedByRateLimiterFlexible extends RateLimitingMiddleware in
private class FastifyRateLimiter extends RateLimitingMiddleware {
FastifyRateLimiter() { this = DataFlow::moduleImport("fastify-rate-limit") }
}
/**
* An options object with a `rateLimit` config passed to a Fastify shorthand route method,
* such as `fastify.post('/path', { config: { rateLimit: { ... } } }, handler)`.
*/
private class FastifyPerRouteRateLimit extends RateLimitingMiddleware {
FastifyPerRouteRateLimit() {
exists(Fastify::RouteSetup setup |
not setup.getMethodName() = ["route", "addHook"] and
setup.getNumArgument() >= 3 and
this.flowsTo(setup.getArgument(1))
|
exists(this.getAPropertySource("config").getAPropertySource("rateLimit"))
or
exists(this.getAPropertySource("rateLimit"))
)
}
}

View File

@@ -0,0 +1,5 @@
---
category: minorAnalysis
---
* The query `js/missing-rate-limiting` now takes Fastify per-route
rate limiting into account.

View File

@@ -9,3 +9,4 @@
| tst.js:64:25:64:63 | functio ... req); } | This route handler performs $@, but is not rate-limited. | tst.js:64:46:64:60 | verifyUser(req) | authorization |
| tst.js:76:25:76:53 | catchAs ... ndler1) | This route handler performs $@, but is not rate-limited. | tst.js:14:40:14:46 | login() | authorization |
| tst.js:88:24:88:40 | expensiveHandler1 | This route handler performs $@, but is not rate-limited. | tst.js:14:40:14:46 | login() | authorization |
| tst.js:112:28:112:44 | expensiveHandler1 | This route handler performs $@, but is not rate-limited. | tst.js:14:40:14:46 | login() | authorization |

View File

@@ -88,3 +88,25 @@ const fastifyApp = require('fastify')();
fastifyApp.get('/foo', expensiveHandler1); // $ Alert
fastifyApp.register(require('fastify-rate-limit'));
fastifyApp.get('/bar', expensiveHandler1);
// Fastify per-route rate limiting via config.rateLimit
const fastifyApp2 = require('fastify')();
fastifyApp2.register(require('@fastify/rate-limit'));
fastifyApp2.post('/login', {
config: {
rateLimit: {
max: 3,
timeWindow: '1 minute'
}
}
}, expensiveHandler1); // OK - has per-route rateLimit config
fastifyApp2.post('/signup', {
rateLimit: {
max: 5,
timeWindow: '1 minute'
}
}, expensiveHandler1); // OK - has per-route rateLimit directly in options
fastifyApp2.post('/other', expensiveHandler1); // $ Alert - no rate limiting