add changes

This commit is contained in:
AD2025
2025-12-26 23:56:32 +02:00
parent 410c3d725f
commit e7d26bc981
127 changed files with 36162 additions and 0 deletions

155
middleware/security.js Normal file
View File

@@ -0,0 +1,155 @@
const helmet = require('helmet');
/**
* Helmet security configuration
* Helmet helps secure Express apps by setting various HTTP headers
*/
const helmetConfig = helmet({
// Content Security Policy
contentSecurityPolicy: {
directives: {
defaultSrc: ["'self'"],
styleSrc: ["'self'", "'unsafe-inline'"], // Allow inline styles for Swagger UI
scriptSrc: ["'self'", "'unsafe-inline'"], // Allow inline scripts for Swagger UI
imgSrc: ["'self'", "data:", "https:"],
connectSrc: ["'self'"],
fontSrc: ["'self'", "data:"],
objectSrc: ["'none'"],
mediaSrc: ["'self'"],
frameSrc: ["'none'"]
}
},
// Cross-Origin-Embedder-Policy
crossOriginEmbedderPolicy: false, // Disabled for API compatibility
// Cross-Origin-Opener-Policy
crossOriginOpenerPolicy: { policy: "same-origin" },
// Cross-Origin-Resource-Policy
crossOriginResourcePolicy: { policy: "cross-origin" },
// DNS Prefetch Control
dnsPrefetchControl: { allow: false },
// Expect-CT (deprecated but included for older browsers)
expectCt: { maxAge: 86400 },
// Frameguard (prevent clickjacking)
frameguard: { action: "deny" },
// Hide Powered-By header
hidePoweredBy: true,
// HTTP Strict Transport Security
hsts: {
maxAge: 31536000, // 1 year
includeSubDomains: true,
preload: true
},
// IE No Open
ieNoOpen: true,
// No Sniff (prevent MIME type sniffing)
noSniff: true,
// Origin-Agent-Cluster
originAgentCluster: true,
// Permitted Cross-Domain Policies
permittedCrossDomainPolicies: { permittedPolicies: "none" },
// Referrer Policy
referrerPolicy: { policy: "no-referrer" }
});
/**
* Custom security headers middleware
* Only adds headers not already set by Helmet
*/
const customSecurityHeaders = (req, res, next) => {
// Add Permissions-Policy (not in Helmet)
res.setHeader('Permissions-Policy', 'geolocation=(), microphone=(), camera=()');
// Prevent caching of sensitive data
if (req.path.includes('/api/auth') || req.path.includes('/api/admin') || req.path.includes('/api/users')) {
res.setHeader('Cache-Control', 'no-store, no-cache, must-revalidate, proxy-revalidate');
res.setHeader('Pragma', 'no-cache');
res.setHeader('Expires', '0');
res.setHeader('Surrogate-Control', 'no-store');
}
next();
};
/**
* CORS configuration
*/
const getCorsOptions = () => {
const allowedOrigins = process.env.ALLOWED_ORIGINS
? process.env.ALLOWED_ORIGINS.split(',')
: ['http://localhost:3000', 'http://localhost:4200', 'http://localhost:5173'];
return {
origin: (origin, callback) => {
// Allow requests with no origin (mobile apps, Postman, etc.)
if (!origin) return callback(null, true);
if (allowedOrigins.indexOf(origin) !== -1 || process.env.NODE_ENV === 'development') {
callback(null, true);
} else {
callback(new Error('Not allowed by CORS'));
}
},
credentials: true,
methods: ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS'],
allowedHeaders: ['Content-Type', 'Authorization', 'x-guest-token'],
exposedHeaders: ['RateLimit-Limit', 'RateLimit-Remaining', 'RateLimit-Reset'],
maxAge: 86400 // 24 hours
};
};
/**
* Security middleware for API routes
*/
const secureApiRoutes = (req, res, next) => {
// Log security-sensitive operations
if (req.method !== 'GET' && req.path.includes('/api/admin')) {
const logger = require('../config/logger');
logger.logSecurityEvent(`Admin ${req.method} request`, req);
}
next();
};
/**
* Prevent parameter pollution
* This middleware should be used after body parser
*/
const preventParameterPollution = (req, res, next) => {
// Whitelist of parameters that can have multiple values
const whitelist = ['category', 'difficulty', 'tags', 'keywords'];
// Check for duplicate parameters
if (req.query) {
for (const param in req.query) {
if (Array.isArray(req.query[param]) && !whitelist.includes(param)) {
return res.status(400).json({
status: 'error',
message: `Parameter pollution detected: '${param}' should not have multiple values`
});
}
}
}
next();
};
module.exports = {
helmetConfig,
customSecurityHeaders,
getCorsOptions,
secureApiRoutes,
preventParameterPollution
};