helmet, rate limit and slowdown

This commit is contained in:
Daniël 2024-06-09 13:25:46 +02:00
parent be25ea36f2
commit f548f9975a
4 changed files with 65 additions and 0 deletions

View file

@ -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 initializeLocalStorage = require("../engines/local.engine");
const initializeS3Storage = require("../engines/s3.engine"); const initializeS3Storage = require("../engines/s3.engine");
const app = express();
const storageMode = process.env.STORAGE_MODE || "local"; const storageMode = process.env.STORAGE_MODE || "local";
const fileNameLength = parseInt(process.env.FILE_NAME_LENGTH, 10) || 10; const fileNameLength = parseInt(process.env.FILE_NAME_LENGTH, 10) || 10;
const multerOptions = { const multerOptions = {
@ -47,4 +52,20 @@ const getFile = (req, res) => {
storageEngine.findFile(filename, 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 }; module.exports = { uploadFile, getFile };

View file

@ -2,6 +2,7 @@ require("dotenv").config();
const express = require("express"); const express = require("express");
const ejs = require("ejs"); const ejs = require("ejs");
const fileRoutes = require("./routes/file.routes"); const fileRoutes = require("./routes/file.routes");
const helmet = require("helmet");
const app = express(); const app = express();
const port = 3000; const port = 3000;
@ -14,6 +15,7 @@ let totalSize = 0;
app.set("view engine", "ejs"); app.set("view engine", "ejs");
app.use(fileRoutes); app.use(fileRoutes);
app.use(helmet());
app.get("/", (req, res) => { app.get("/", (req, res) => {
res.render("index", { res.render("index", {

39
package-lock.json generated
View file

@ -9,6 +9,9 @@
"dotenv": "^16.4.5", "dotenv": "^16.4.5",
"ejs": "^3.1.10", "ejs": "^3.1.10",
"express": "^4.19.2", "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", "mime-types": "^2.1.35",
"multer": "^1.4.5-lts.1", "multer": "^1.4.5-lts.1",
"nanoid": "^3.3.7" "nanoid": "^3.3.7"
@ -3419,6 +3422,34 @@
"node": ">= 0.10.0" "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": { "node_modules/fast-json-stable-stringify": {
"version": "2.1.0", "version": "2.1.0",
"resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", "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": ">= 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": { "node_modules/hexoid": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/hexoid/-/hexoid-1.0.0.tgz", "resolved": "https://registry.npmjs.org/hexoid/-/hexoid-1.0.0.tgz",

View file

@ -13,6 +13,9 @@
"dotenv": "^16.4.5", "dotenv": "^16.4.5",
"ejs": "^3.1.10", "ejs": "^3.1.10",
"express": "^4.19.2", "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", "mime-types": "^2.1.35",
"multer": "^1.4.5-lts.1", "multer": "^1.4.5-lts.1",
"nanoid": "^3.3.7" "nanoid": "^3.3.7"