diff --git a/backend/server.js b/backend/server.js index 32522fa..f2618b8 100644 --- a/backend/server.js +++ b/backend/server.js @@ -28,21 +28,55 @@ const adminAuthRoutes = require('./src/routes/adminAuth'); const app = express(); const PORT = process.env.PORT || 3000; -// Security middleware -app.use(helmet()); +// Security middleware with custom CSP +app.use(helmet({ + contentSecurityPolicy: { + directives: { + defaultSrc: ["'self'"], + scriptSrc: ["'self'", "'unsafe-inline'"], // Required for React + styleSrc: ["'self'", "'unsafe-inline'", "https:"], // Required for styled components + imgSrc: ["'self'", "data:", "https:", "blob:"], // Allow data URLs and external images + connectSrc: ["'self'"], // API connections + fontSrc: ["'self'", "https:", "data:"], // Web fonts + objectSrc: ["'none'"], // Disable plugins + mediaSrc: ["'self'"], // Audio/video + frameSrc: ["'none'"], // Disable iframes + }, + }, + hsts: { + maxAge: 31536000, // 1 year + includeSubDomains: true, + preload: true + }, + permittedCrossDomainPolicies: false, + referrerPolicy: { policy: "strict-origin-when-cross-origin" } +})); + +// Additional security headers +app.use((req, res, next) => { + // Permissions Policy (controls browser features) + res.setHeader('Permissions-Policy', 'camera=(), microphone=(), geolocation=(), payment=()'); + next(); +}); // CORS configuration const corsOptions = { origin: function (origin, callback) { const allowedOrigins = [ process.env.FRONTEND_URL || 'http://localhost:3005', - process.env.ADMIN_URL || 'http://localhost:3005', - 'http://localhost:5173', // Vite dev server - 'http://localhost:3002', // Backend server - 'http://localhost:3001', // For API testing - 'http://localhost:3000' // Direct backend access + process.env.ADMIN_URL || 'http://localhost:3005' ]; + // In development, also allow localhost origins + if (process.env.NODE_ENV === 'development') { + allowedOrigins.push( + 'http://localhost:5173', // Vite dev server + 'http://localhost:3002', // Backend server + 'http://localhost:3001', // For API testing + 'http://localhost:3000' // Direct backend access + ); + } + // Allow requests with no origin (like mobile apps or curl) if (!origin || allowedOrigins.indexOf(origin) !== -1) { callback(null, true);