diff --git a/index.js b/index.js index 3630eab2..caa380c4 100644 --- a/index.js +++ b/index.js @@ -4,9 +4,17 @@ const dotenv = require(`dotenv`); const mongoose = require('mongoose'); const cookieParser = require("cookie-parser"); const bodyParser = require("body-parser"); - +const { rateLimit } = require("express-rate-limit"); +const mongoSanitize = require("express-mongo-sanitize"); +const hpp = require("hpp"); +const helmet = require('helmet'); const errorMiddleware = require("./middlewares/error.js"); + + + + + // dotenv.config({path : `.env`}) require('dotenv').config(); const PORT = process.env.PORT || 8080; @@ -19,6 +27,32 @@ const MONGO_URL = process.env.MONGO_URL ; const cors=require("cors"); app.use(cors()) + +const limiter = rateLimit({ + windowMs: 15 * 60 * 1000, // 15 minutes + limit: 100, // Limit each IP to 100 requests per `window` (here, per 15 minutes). + standardHeaders: "draft-7", // draft-6: `RateLimit-*` headers; draft-7: combined `RateLimit` header + legacyHeaders: false, // Disable the `X-RateLimit-*` headers. + // store: ... , // Redis, Memcached, etc. See below. +}); + +// Apply the rate limiting middleware to all requests. +app.use(limiter); + + +// Or, to sanitize data that only contains $, without .(dot) +// Can be useful for letting data pass that is meant for querying nested documents. +app.use( + mongoSanitize({ + replaceWith: "_", + }) +); + + +//Helmet helps secure Express apps by setting HTTP response headers. +app.use(helmet()); + + // Check if MONGO_URL is defined if (!MONGO_URL) { console.error("MONGO_URL is not defined in the environment variables."); @@ -42,6 +76,9 @@ app.use(express.json()); app.use(cookieParser()); app.use(bodyParser.urlencoded({ extended: true })); +//HPP puts array parameters in req.query and/or req.body aside and just selects the last parameter value. You add the middleware and you are done. +app.use(hpp()); // Make sure the body is parsed beforehand. + // Route Imports const customer = require("./routes/customerRoutes.js"); diff --git a/package-lock.json b/package-lock.json index e72811ee..1f9243d1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,6 +17,10 @@ "disposable-email-domains": "^1.0.62", "dotenv": "^16.4.5", "express": "^4.19.2", + "express-mongo-sanitize": "^2.2.0", + "express-rate-limit": "^7.2.0", + "helmet": "^7.1.0", + "hpp": "^0.2.3", "jsonwebtoken": "^9.0.2", "mongoose": "^7.6.11", "nodemailer": "^6.9.3", @@ -402,6 +406,30 @@ "node": ">= 0.10.0" } }, + "node_modules/express-mongo-sanitize": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/express-mongo-sanitize/-/express-mongo-sanitize-2.2.0.tgz", + "integrity": "sha512-PZBs5nwhD6ek9ZuP+W2xmpvcrHwXZxD5GdieX2dsjPbAbH4azOkrHbycBud2QRU+YQF1CT+pki/lZGedHgo/dQ==", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/express-rate-limit": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-7.2.0.tgz", + "integrity": "sha512-T7nul1t4TNyfZMJ7pKRKkdeVJWa2CqB8NA1P8BwYaoDI5QSBZARv5oMS43J7b7I5P+4asjVXjb7ONuwDKucahg==", + "license": "MIT", + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://github.com/sponsors/express-rate-limit" + }, + "peerDependencies": { + "express": "4 || 5 || ^5.0.0-beta.1" + } + }, "node_modules/fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", @@ -483,15 +511,13 @@ "node": ">= 6" } }, - "node_modules/gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", - "dependencies": { - "get-intrinsic": "^1.1.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node_modules/has": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.4.tgz", + "integrity": "sha512-qdSAmqLF6209RFj4VVItywPMbm3vWylknmB3nvNiUIs72xAimcM8nVYxYr7ncvZq5qzk9MKIZR8ijqD/1QuYjQ==", + "license": "MIT", + "engines": { + "node": ">= 0.4.0" } }, "node_modules/has-flag": { @@ -535,6 +561,28 @@ "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==", + "license": "MIT", + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/hpp": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/hpp/-/hpp-0.2.3.tgz", + "integrity": "sha512-4zDZypjQcxK/8pfFNR7jaON7zEUpXZxz4viyFmqjb3kWNWAHsLEUmWXcdn25c5l76ISvnD6hbOGO97cXUI3Ryw==", + "license": "ISC", + "dependencies": { + "lodash": "^4.17.12", + "type-is": "^1.6.12" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/http-errors": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", @@ -666,7 +714,6 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" }, - "node_modules/jsonwebtoken/node_modules/semver": { "version": "7.6.2", "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", @@ -705,6 +752,12 @@ "node": ">=12.0.0" } }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "license": "MIT" + }, "node_modules/lodash.includes": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", @@ -1227,22 +1280,6 @@ "node": ">= 0.8.0" } }, - "node_modules/set-function-length": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", - "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", - "dependencies": { - "define-data-property": "^1.1.4", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, "node_modules/setprototypeof": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", diff --git a/package.json b/package.json index 33f8dbae..7b7e28c7 100644 --- a/package.json +++ b/package.json @@ -19,6 +19,10 @@ "disposable-email-domains": "^1.0.62", "dotenv": "^16.4.5", "express": "^4.19.2", + "express-mongo-sanitize": "^2.2.0", + "express-rate-limit": "^7.2.0", + "helmet": "^7.1.0", + "hpp": "^0.2.3", "jsonwebtoken": "^9.0.2", "mongoose": "^7.6.11", "nodemailer": "^6.9.3",