From c71b23ef82b84c0e3953ea2b3090de6a37c3be8b Mon Sep 17 00:00:00 2001 From: William Mantly Date: Thu, 16 Jul 2026 15:29:06 -0400 Subject: [PATCH] docs.js: rate-limit the doc routes (CodeQL: missing rate limiting) Public route reading from disk on every request with no throttling -- add a per-IP limiter matching the routes/auth.js/routes/host.js convention already used elsewhere in this repo. --- nodejs/routes/docs.js | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/nodejs/routes/docs.js b/nodejs/routes/docs.js index 57c0eb0..e99fa6e 100644 --- a/nodejs/routes/docs.js +++ b/nodejs/routes/docs.js @@ -3,10 +3,22 @@ const fs = require('fs'); const path = require('path'); const router = require('express').Router(); +const {rateLimit} = require('express-rate-limit'); const {marked} = require('marked'); const conf = require('@simpleworkjs/conf'); const buildInfo = require('../utils/build_info'); +// Public, unauthenticated, and reads from disk on every request -- throttle +// per IP so it can't be used to hammer the filesystem (mirrors the pattern +// in routes/auth.js/routes/host.js), generous since this is just docs. +const docsLimiter = rateLimit({ + windowMs: 60 * 1000, + max: 120, + standardHeaders: true, + legacyHeaders: false, + message: {name: 'TooManyRequests', message: 'Too many requests, please try again later.'}, +}); + const values = { title: conf.environment !== 'production' ? `dev` : '', titleIcon: conf.environment !== 'production' ? `` : '', @@ -39,6 +51,8 @@ function fixImagePaths(html) { return html.replace(/(["(])docs\/images\//g, '$1/docs/images/'); } +router.use(docsLimiter); + router.get('/', function(req, res) { res.render('docs_index', {...values, docs: docList}); });