From 01c9e13a91db13d9df469a6d8574e10885a23e28 Mon Sep 17 00:00:00 2001 From: Wouter Koch Date: Thu, 2 Apr 2026 13:32:13 +0200 Subject: [PATCH 1/2] Don't limit admin log requests --- routes/admin.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/routes/admin.js b/routes/admin.js index 400b71b..59e8f86 100644 --- a/routes/admin.js +++ b/routes/admin.js @@ -1,6 +1,6 @@ const fs = require("fs"); const path = require("path"); -const { apiLimiter, authLimiter } = require("../middleware/rateLimiters"); +const { authLimiter } = require("../middleware/rateLimiters"); const { authenticateAdminToken, getValidTokens, @@ -268,7 +268,7 @@ module.exports = (app, upload) => { } }); - app.get("/admin/logs", authLimiter, authenticateAdminToken, (req, res) => { + app.get("/admin/logs", authenticateAdminToken, (req, res) => { try { var json = []; fs.readdir(logdir, function (err, files) { @@ -287,7 +287,7 @@ module.exports = (app, upload) => { } }); - app.get("/admin/logs/*splat", authLimiter, authenticateAdminToken, (req, res) => { + app.get("/admin/logs/*splat", authenticateAdminToken, (req, res) => { try { let filename = decodeURI(req.originalUrl.replace("/admin/logs/", "")); const resolvedPath = path.resolve(logdir, filename); From 0a001280f2e265317f89f96cfcdc9347b606088f Mon Sep 17 00:00:00 2001 From: Wouter Koch Date: Thu, 2 Apr 2026 14:41:57 +0200 Subject: [PATCH 2/2] Set a (high) rate limit for admin log tasks --- middleware/rateLimiters.js | 18 +++++++++++++++++- routes/admin.js | 6 +++--- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/middleware/rateLimiters.js b/middleware/rateLimiters.js index 8161da3..82d1dc6 100644 --- a/middleware/rateLimiters.js +++ b/middleware/rateLimiters.js @@ -53,8 +53,24 @@ const authLimiter = rateLimit({ }, }); +const adminLimiter = rateLimit({ + windowMs: 1 * 60 * 1000, + max: 250, + standardHeaders: true, + legacyHeaders: false, + keyGenerator: ipKey, + handler: (request, response, next, options) => { + writeErrorLog( + `Too many admin requests`, + `IP ${getClientIP(request)}` + ); + return response.status(options.statusCode).send(options.message); + }, +}); + module.exports = { idLimiter, apiLimiter, - authLimiter + authLimiter, + adminLimiter }; diff --git a/routes/admin.js b/routes/admin.js index 59e8f86..16cbe13 100644 --- a/routes/admin.js +++ b/routes/admin.js @@ -1,6 +1,6 @@ const fs = require("fs"); const path = require("path"); -const { authLimiter } = require("../middleware/rateLimiters"); +const { authLimiter, adminLimiter } = require("../middleware/rateLimiters"); const { authenticateAdminToken, getValidTokens, @@ -268,7 +268,7 @@ module.exports = (app, upload) => { } }); - app.get("/admin/logs", authenticateAdminToken, (req, res) => { + app.get("/admin/logs", adminLimiter, authenticateAdminToken, (req, res) => { try { var json = []; fs.readdir(logdir, function (err, files) { @@ -287,7 +287,7 @@ module.exports = (app, upload) => { } }); - app.get("/admin/logs/*splat", authenticateAdminToken, (req, res) => { + app.get("/admin/logs/*splat", adminLimiter, authenticateAdminToken, (req, res) => { try { let filename = decodeURI(req.originalUrl.replace("/admin/logs/", "")); const resolvedPath = path.resolve(logdir, filename);