From fef582c858b30ee7542a0d5d07a0ec0161278d09 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Mon, 13 Apr 2026 11:22:49 +0200 Subject: [PATCH] JS: Add test case for Fastify per-route rate limiting --- .../MissingRateLimiting.expected | 7 ++++++ .../Security/CWE-770/MissingRateLimit/tst.js | 22 +++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/javascript/ql/test/query-tests/Security/CWE-770/MissingRateLimit/MissingRateLimiting.expected b/javascript/ql/test/query-tests/Security/CWE-770/MissingRateLimit/MissingRateLimiting.expected index 3d7bc2954eb..95f55486600 100644 --- a/javascript/ql/test/query-tests/Security/CWE-770/MissingRateLimit/MissingRateLimiting.expected +++ b/javascript/ql/test/query-tests/Security/CWE-770/MissingRateLimit/MissingRateLimiting.expected @@ -1,3 +1,4 @@ +#select | MissingRateLimiting.js:4:19:8:1 | functio ... ath);\\n} | This route handler performs $@, but is not rate-limited. | MissingRateLimiting.js:7:5:7:22 | res.sendFile(path) | a file system access | | MissingRateLimiting.js:25:19:25:20 | f1 | This route handler performs $@, but is not rate-limited. | MissingRateLimiting.js:13:5:13:22 | res.sendFile(path) | a file system access | | MissingRateLimiting.js:25:27:25:28 | f3 | This route handler performs $@, but is not rate-limited. | MissingRateLimiting.js:22:5:22:22 | res.sendFile(path) | a file system access | @@ -9,3 +10,9 @@ | 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:103:4:103:20 | expensiveHandler1 | This route handler performs $@, but is not rate-limited. | tst.js:14:40:14:46 | login() | authorization | +| tst.js:110:4:110:20 | 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 | +testFailures +| tst.js:103:4:103:20 | This route handler performs $@, but is not rate-limited. | Unexpected result: Alert | +| tst.js:110:4:110:20 | This route handler performs $@, but is not rate-limited. | Unexpected result: Alert | diff --git a/javascript/ql/test/query-tests/Security/CWE-770/MissingRateLimit/tst.js b/javascript/ql/test/query-tests/Security/CWE-770/MissingRateLimit/tst.js index 4f778afef68..5b4312bbbe0 100644 --- a/javascript/ql/test/query-tests/Security/CWE-770/MissingRateLimit/tst.js +++ b/javascript/ql/test/query-tests/Security/CWE-770/MissingRateLimit/tst.js @@ -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