UNPKG

@ordojs/security

Version:

Security package for OrdoJS with XSS, CSRF, and injection protection

255 lines (194 loc) 6.9 kB
# CSRF Protection Module This module provides comprehensive Cross-Site Request Forgery (CSRF) protection for OrdoJS applications. It implements both session-based token validation and the double-submit cookie pattern to protect against CSRF attacks. ## Features - **Session-based CSRF tokens**: Secure token generation and validation tied to user sessions - **Double-submit cookie pattern**: Alternative protection method using matching cookie and header tokens - **Automatic token injection**: Client-side JavaScript for automatic form and AJAX request protection - **Flexible configuration**: Customizable token expiry, cookie settings, and header names - **Express.js integration**: Ready-to-use middleware for Express applications - **TypeScript support**: Full type safety with comprehensive interfaces ## Quick Start ```typescript import { CSRFManager } from '@ordojs/security'; // Initialize CSRF protection const csrfManager = new CSRFManager({ secret: 'your-secret-key-here', tokenExpiry: 60 * 60 * 1000, // 1 hour }); // Generate a token for a user session const sessionId = 'user-session-123'; const token = csrfManager.generateToken(sessionId); // Validate the token const isValid = csrfManager.validateToken(token.value, sessionId); console.log('Token valid:', isValid.valid); ``` ## Configuration ```typescript interface CSRFConfig { secret: string; // Required: Secret key for token signing tokenExpiry?: number; // Token expiration (default: 1 hour) cookieName?: string; // Cookie name (default: '__csrf-token') headerName?: string; // Header name (default: 'X-CSRF-Token') fieldName?: string; // Form field name (default: '_csrf') secureCookie?: boolean; // Use secure cookies (default: true) httpOnlyCookie?: boolean; // Use httpOnly cookies (default: true) sameSite?: 'strict' | 'lax' | 'none'; // SameSite attribute (default: 'strict') } ``` ## Usage Patterns ### 1. Session-based Protection Best for traditional server-rendered applications with user sessions: ```typescript // Generate token for user session const token = csrfManager.generateToken(sessionId); // Add to form const formHTML = ` <form method="POST" action="/submit"> ${csrfManager.generateFormField(sessionId)} <input type="text" name="data" /> <button type="submit">Submit</button> </form> `; // Validate on form submission const request = { headers: { 'X-CSRF-Token': tokenFromRequest }, sessionId: userSessionId, }; const validation = csrfManager.validateRequest(request); if (!validation.valid) { throw new Error('CSRF validation failed'); } ``` ### 2. Double-Submit Cookie Pattern Best for stateless applications or APIs: ```typescript // Set up double-submit protection const response = csrfManager.setupDoubleSubmitProtection(sessionId); // Send cookie and header to client res.cookie(response.cookies[0].name, response.cookies[0].value, response.cookies[0].options); res.header('X-CSRF-Token', response.headers['X-CSRF-Token']); // Validate matching tokens const request = { headers: { 'X-CSRF-Token': headerToken }, cookies: { '__csrf-token': cookieToken }, }; const validation = csrfManager.validateDoubleSubmit(request); ``` ### 3. Client-side Integration Automatic protection for forms and AJAX requests: ```html <!DOCTYPE html> <html> <head> <meta name="csrf-token" content="your-token-here" /> </head> <body> <!-- Forms will automatically get CSRF tokens --> <form method="POST" action="/api/data"> <input type="text" name="value" /> <button type="submit">Submit</button> </form> <script> // Include the generated client script ${csrfManager.generateClientScript(sessionId)} </script> </body> </html> ``` ### 4. Express.js Middleware ```typescript import express from 'express'; import { CSRFManager } from '@ordojs/security'; const app = express(); const csrfManager = new CSRFManager({ secret: 'your-secret' }); // CSRF protection middleware app.use((req, res, next) => { if (req.method === 'GET') return next(); const validation = csrfManager.validateRequest({ headers: req.headers, body: req.body, cookies: req.cookies, sessionId: req.session.id, }); if (!validation.valid) { return res.status(403).json({ error: validation.error }); } next(); }); // Generate token endpoint app.get('/csrf-token', (req, res) => { const token = csrfManager.generateToken(req.session.id); res.json({ token: token.value }); }); ``` ## Security Considerations ### Token Security - Tokens are cryptographically signed using HMAC-SHA256 - Constant-time comparison prevents timing attacks - Tokens include expiration timestamps - Random data prevents token prediction ### Session Management - Tokens are tied to specific sessions - Automatic cleanup of expired tokens - Session isolation prevents cross-session attacks ### Cookie Security - Secure flag for HTTPS-only transmission - HttpOnly flag prevents JavaScript access - SameSite attribute prevents cross-site requests - Configurable expiration times ## Best Practices 1. **Use HTTPS**: Always use HTTPS in production to protect tokens in transit 2. **Rotate secrets**: Regularly rotate your secret keys 3. **Short expiry**: Use reasonable token expiration times (1-2 hours) 4. **Validate origin**: Consider additional origin/referer validation 5. **Monitor failures**: Log and monitor CSRF validation failures ## API Reference ### CSRFManager #### Methods - `generateToken(sessionId: string): CSRFToken` - `validateToken(tokenValue: string, sessionId: string): CSRFValidationResult` - `setupDoubleSubmitProtection(sessionId: string): CSRFResponse` - `validateDoubleSubmit(request: CSRFRequest): CSRFValidationResult` - `validateRequest(request: CSRFRequest): CSRFValidationResult` - `generateFormField(sessionId: string): string` - `generateClientScript(sessionId?: string): string` - `consumeToken(sessionId: string, tokenValue: string): boolean` - `removeSession(sessionId: string): boolean` - `getStats(): { totalSessions: number; totalTokens: number; activeSessions: number }` - `destroy(): void` ### Types See `types.ts` for complete type definitions including: - `CSRFConfig` - `CSRFToken` - `CSRFRequest` - `CSRFResponse` - `CSRFValidationResult` - `CSRFSession` ## Testing The module includes comprehensive tests covering: - Token generation and validation - Session management - Double-submit cookie pattern - Request validation - Client script generation - Error handling - Configuration options Run tests with: ```bash npm test src/csrf/csrf-manager.test.ts ``` ## Performance - Efficient in-memory token storage - Automatic cleanup of expired tokens - Constant-time cryptographic operations - Minimal overhead for validation - Configurable cleanup intervals ## Compatibility - Node.js 16+ - Express.js 4+ - Modern browsers (ES2018+) - TypeScript 4.5+