fix(security): add Helmet headers and rate limiting on auth endpoints
Helmet adds HTTP security headers (HSTS, X-Frame-Options, X-Content-Type-Options, etc.). CSP is disabled pending deployment- specific tuning. Rate limiting (10 req / 15 min per IP) is applied to POST /login and POST / (registration) to mitigate brute force and credential stuffing attacks.
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
var express = require('express'),
|
var express = require('express'),
|
||||||
session = require('express-session'),
|
session = require('express-session'),
|
||||||
cors = require('cors'),
|
cors = require('cors'),
|
||||||
|
helmet = require('helmet'),
|
||||||
errorhandler = require('errorhandler');
|
errorhandler = require('errorhandler');
|
||||||
|
|
||||||
const config = require('./config'),
|
const config = require('./config'),
|
||||||
@@ -9,6 +10,7 @@ const config = require('./config'),
|
|||||||
|
|
||||||
function createApp() {
|
function createApp() {
|
||||||
const app = express();
|
const app = express();
|
||||||
|
app.use(helmet({ contentSecurityPolicy: false }));
|
||||||
const allowedOrigins = process.env.ALLOWED_ORIGINS
|
const allowedOrigins = process.env.ALLOWED_ORIGINS
|
||||||
? process.env.ALLOWED_ORIGINS.split(',').map(o => o.trim())
|
? process.env.ALLOWED_ORIGINS.split(',').map(o => o.trim())
|
||||||
: [];
|
: [];
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
const express = require('express');
|
const express = require('express');
|
||||||
|
const rateLimit = require('express-rate-limit');
|
||||||
const {
|
const {
|
||||||
authenticate, createUser, getUser, loginAsUser,
|
authenticate, createUser, getUser, loginAsUser,
|
||||||
updateUser, updateUserEmail, updateUserPassword, updateUserRole, updateUserUsername
|
updateUser, updateUserEmail, updateUserPassword, updateUserRole, updateUserUsername
|
||||||
@@ -7,11 +8,19 @@ const auth = require('../../../middlewares/auth');
|
|||||||
|
|
||||||
const userRouter = express.Router();
|
const userRouter = express.Router();
|
||||||
|
|
||||||
|
const authLimiter = rateLimit({
|
||||||
|
windowMs: 15 * 60 * 1000,
|
||||||
|
max: 10,
|
||||||
|
standardHeaders: true,
|
||||||
|
legacyHeaders: false,
|
||||||
|
message: { errors: { 'rate limit': 'too many attempts, please try again later' } }
|
||||||
|
});
|
||||||
|
|
||||||
userRouter.get('/', auth.required, getUser);
|
userRouter.get('/', auth.required, getUser);
|
||||||
userRouter.put('/', auth.required, updateUser);
|
userRouter.put('/', auth.required, updateUser);
|
||||||
userRouter.post('/', auth.optional, createUser);
|
userRouter.post('/', authLimiter, auth.optional, createUser);
|
||||||
userRouter.get('/authenticate', auth.optional, authenticate);
|
userRouter.get('/authenticate', auth.optional, authenticate);
|
||||||
userRouter.post('/login', auth.optional, loginAsUser);
|
userRouter.post('/login', authLimiter, auth.optional, loginAsUser);
|
||||||
//userRouter.post('/register', auth.optional, createUser);
|
//userRouter.post('/register', auth.optional, createUser);
|
||||||
//userRouter.get('/users', auth.required, getAllUsers);
|
//userRouter.get('/users', auth.required, getAllUsers);
|
||||||
userRouter.put('/update/email', auth.required, updateUserEmail);
|
userRouter.put('/update/email', auth.required, updateUserEmail);
|
||||||
|
|||||||
Reference in New Issue
Block a user