From f548f9975a852006dd91e7f34135daebf7a7e04d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dani=C3=ABl?= <15849319+abcdan@users.noreply.github.com> Date: Sun, 9 Jun 2024 13:25:46 +0200 Subject: [PATCH] helmet, rate limit and slowdown --- controllers/file.controller.js | 21 ++++++++++++++++++ index.js | 2 ++ package-lock.json | 39 ++++++++++++++++++++++++++++++++++ package.json | 3 +++ 4 files changed, 65 insertions(+) diff --git a/controllers/file.controller.js b/controllers/file.controller.js index 51a0c9c..2814910 100644 --- a/controllers/file.controller.js +++ b/controllers/file.controller.js @@ -1,6 +1,11 @@ +const express = require("express"); +const rateLimit = require("express-rate-limit"); +const slowDown = require("express-slow-down"); const initializeLocalStorage = require("../engines/local.engine"); const initializeS3Storage = require("../engines/s3.engine"); +const app = express(); + const storageMode = process.env.STORAGE_MODE || "local"; const fileNameLength = parseInt(process.env.FILE_NAME_LENGTH, 10) || 10; const multerOptions = { @@ -47,4 +52,20 @@ const getFile = (req, res) => { storageEngine.findFile(filename, res); }; +// Rate limiting middleware +const limiter = rateLimit({ + windowMs: 15 * 60 * 1000, // 15 minutes + max: 100, // Limit each IP to 100 requests per windowMs + message: "Too many requests from this IP, please try again after 15 minutes", +}); + +// Slow down middleware +const speedLimiter = slowDown({ + windowMs: 15 * 60 * 1000, // 15 minutes + delayAfter: 50, // Allow 50 requests per 15 minutes, then start slowing down responses + delayMs: 500, // Slow down subsequent responses by 500ms per request +}); + +app.use("/u/:filename", limiter, speedLimiter, getFile); + module.exports = { uploadFile, getFile }; diff --git a/index.js b/index.js index ed8f616..cc98380 100644 --- a/index.js +++ b/index.js @@ -2,6 +2,7 @@ require("dotenv").config(); const express = require("express"); const ejs = require("ejs"); const fileRoutes = require("./routes/file.routes"); +const helmet = require("helmet"); const app = express(); const port = 3000; @@ -14,6 +15,7 @@ let totalSize = 0; app.set("view engine", "ejs"); app.use(fileRoutes); +app.use(helmet()); app.get("/", (req, res) => { res.render("index", { diff --git a/package-lock.json b/package-lock.json index d7cdbab..cdaec5e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,6 +9,9 @@ "dotenv": "^16.4.5", "ejs": "^3.1.10", "express": "^4.19.2", + "express-rate-limit": "^7.3.1", + "express-slow-down": "^2.0.3", + "helmet": "^7.1.0", "mime-types": "^2.1.35", "multer": "^1.4.5-lts.1", "nanoid": "^3.3.7" @@ -3419,6 +3422,34 @@ "node": ">= 0.10.0" } }, + "node_modules/express-rate-limit": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-7.3.1.tgz", + "integrity": "sha512-BbaryvkY4wEgDqLgD18/NSy2lDO2jTuT9Y8c1Mpx0X63Yz0sYd5zN6KPe7UvpuSVvV33T6RaE1o1IVZQjHMYgw==", + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://github.com/sponsors/express-rate-limit" + }, + "peerDependencies": { + "express": "4 || 5 || ^5.0.0-beta.1" + } + }, + "node_modules/express-slow-down": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/express-slow-down/-/express-slow-down-2.0.3.tgz", + "integrity": "sha512-vATCiFd8uQHtTeK5/Q0nLUukhZh+RV5zkcHxLQr0X5dEFVEYqzVXEe48nW23Z49fwtR+ApD9zn9sZRisTCR99w==", + "dependencies": { + "express-rate-limit": "7" + }, + "engines": { + "node": ">= 16" + }, + "peerDependencies": { + "express": "4 || 5 || ^5.0.0-beta.1" + } + }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", @@ -3759,6 +3790,14 @@ "node": ">= 0.4" } }, + "node_modules/helmet": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/helmet/-/helmet-7.1.0.tgz", + "integrity": "sha512-g+HZqgfbpXdCkme/Cd/mZkV0aV3BZZZSugecH03kl38m/Kmdx8jKjBikpDj2cr+Iynv4KpYEviojNdTJActJAg==", + "engines": { + "node": ">=16.0.0" + } + }, "node_modules/hexoid": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/hexoid/-/hexoid-1.0.0.tgz", diff --git a/package.json b/package.json index 323147c..03c5664 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,9 @@ "dotenv": "^16.4.5", "ejs": "^3.1.10", "express": "^4.19.2", + "express-rate-limit": "^7.3.1", + "express-slow-down": "^2.0.3", + "helmet": "^7.1.0", "mime-types": "^2.1.35", "multer": "^1.4.5-lts.1", "nanoid": "^3.3.7"