const crypto = require('crypto'); // Generate a random token const generateToken = () => { return crypto.randomBytes(24).toString('hex'); }; // Middleware to protect against CSRF const csrfProtection = (req, res, next) => { // Skip for GET, HEAD, OPTIONS (safe methods) if (['GET', 'HEAD', 'OPTIONS'].includes(req.method)) { return next(); } // Skip for Login endpoint if (req.path === '/api/login' || req.path === '/api/auth/login') { return next(); } // Get token from header const tokenFromHeader = req.headers['x-csrf-token']; // Get token from session const tokenFromSession = req.session.csrfToken; if (!tokenFromSession || !tokenFromHeader || tokenFromSession !== tokenFromHeader) { console.error('πŸ”’ [CSRF Security] Token Mismatch Detected'); console.error(`- Path: ${req.path}`); console.error(`- Session ID: ${req.sessionID ? req.sessionID.substring(0, 8) + '...' : 'NONE'}`); console.error(`- Session User: ${req.session?.user?.id || 'GUEST'}`); console.error(`- Token in Session: ${tokenFromSession ? 'EXISTS (' + tokenFromSession.substring(0, 5) + '...)' : 'MISSING'}`); console.error(`- Token in Header: ${tokenFromHeader ? 'EXISTS (' + tokenFromHeader.substring(0, 5) + '...)' : 'MISSING'}`); return res.status(403).json({ success: false, message: 'Invalid CSRF Token', error: 'μ„Έμ…˜ λ³΄μ•ˆ 토큰(CSRF)이 μΌμΉ˜ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. λ³΄μ•ˆ 정책에 따라 μš”μ²­μ΄ κ±°λΆ€λ˜μ—ˆμŠ΅λ‹ˆλ‹€. λ‹€μ‹œ λ‘œκ·ΈμΈν•˜κ±°λ‚˜ μƒˆλ‘œκ³ μΉ¨ ν›„ μ‹œλ„ν•΄ μ£Όμ„Έμš”.' }); } next(); }; module.exports = { generateToken, csrfProtection };