# Security Review Guide Security-focused code review checklist based on OWASP Top 10 and best practices. ## Authentication & Authorization ### Authentication - [ ] Passwords hashed with strong algorithm (bcrypt, argon2) - [ ] Password complexity requirements enforced - [ ] Account lockout after failed attempts - [ ] Secure password reset flow - [ ] Multi-factor authentication for sensitive operations - [ ] Session tokens are cryptographically random - [ ] Session timeout implemented ### Authorization - [ ] Authorization checks on every request - [ ] Principle of least privilege applied - [ ] Role-based access control (RBAC) properly implemented - [ ] No privilege escalation paths - [ ] Direct object reference checks (IDOR prevention) - [ ] API endpoints protected appropriately ### JWT Security ```typescript // ❌ Insecure JWT configuration jwt.sign(payload, 'weak-secret'); // ✅ Secure JWT configuration jwt.sign(payload, process.env.JWT_SECRET, { algorithm: 'RS256', expiresIn: '15m', issuer: 'your-app', audience: 'your-api' }); // ❌ Not verifying JWT properly const decoded = jwt.decode(token); // No signature verification! // ✅ Verify signature and claims const decoded = jwt.verify(token, publicKey, { algorithms: ['RS256'], issuer: 'your-app', audience: 'your-api' }); ``` ## Input Validation ### SQL Injection Prevention ```python # ❌ Vulnerable to SQL injection query = f"SELECT * FROM users WHERE id = {user_id}" # ✅ Use parameterized queries cursor.execute("SELECT * FROM users WHERE id = %s", (user_id,)) # ✅ Use ORM with proper escaping User.objects.filter(id=user_id) ``` ### XSS Prevention ```typescript // ❌ Vulnerable to XSS element.innerHTML = userInput; // ✅ Use textContent for plain text element.textContent = userInput; // ✅ Use DOMPurify for HTML element.innerHTML = DOMPurify.sanitize(userInput); // ✅ React automatically escapes (but watch dangerouslySetInnerHTML) return
{userInput}
; // Safe return
; // Dangerous! ``` ### Command Injection Prevention ```python # ❌ Vulnerable to command injection os.system(f"convert {filename} output.png") # ✅ Use subprocess with list arguments subprocess.run(['convert', filename, 'output.png'], check=True) # ✅ Validate and sanitize input import shlex safe_filename = shlex.quote(filename) ``` ### Path Traversal Prevention ```typescript // ❌ Vulnerable to path traversal const filePath = `./uploads/${req.params.filename}`; // ✅ Validate and sanitize path const path = require('path'); const safeName = path.basename(req.params.filename); const filePath = path.join('./uploads', safeName); // Verify it's still within uploads directory if (!filePath.startsWith(path.resolve('./uploads'))) { throw new Error('Invalid path'); } ``` ## Data Protection ### Sensitive Data Handling - [ ] No secrets in source code - [ ] Secrets stored in environment variables or secret manager - [ ] Sensitive data encrypted at rest - [ ] Sensitive data encrypted in transit (HTTPS) - [ ] PII handled according to regulations (GDPR, etc.) - [ ] Sensitive data not logged - [ ] Secure data deletion when required ### Configuration Security ```yaml # ❌ Secrets in config files database: password: "super-secret-password" # ✅ Reference environment variables database: password: ${DATABASE_PASSWORD} ``` ### Error Messages ```typescript // ❌ Leaking sensitive information catch (error) { return res.status(500).json({ error: error.stack, // Exposes internal details query: sqlQuery // Exposes database structure }); } // ✅ Generic error messages catch (error) { logger.error('Database error', { error, userId }); // Log internally return res.status(500).json({ error: 'An unexpected error occurred' }); } ``` ## API Security ### Rate Limiting - [ ] Rate limiting on all public endpoints - [ ] Stricter limits on authentication endpoints - [ ] Per-user and per-IP limits - [ ] Graceful handling when limits exceeded ### CORS Configuration ```typescript // ❌ Overly permissive CORS app.use(cors({ origin: '*' })); // ✅ Restrictive CORS app.use(cors({ origin: ['https://your-app.com'], methods: ['GET', 'POST'], credentials: true })); ``` ### HTTP Headers ```typescript // Security headers to set app.use(helmet({ contentSecurityPolicy: { directives: { defaultSrc: ["'self'"], scriptSrc: ["'self'"], styleSrc: ["'self'", "'unsafe-inline'"], } }, hsts: { maxAge: 31536000, includeSubDomains: true }, noSniff: true, xssFilter: true, frameguard: { action: 'deny' } })); ``` ## Cryptography ### Secure Practices - [ ] Using well-established algorithms (AES-256, RSA-2048+) - [ ] Not implementing custom cryptography - [ ] Using cryptographically secure random number generation - [ ] Proper key management and rotation - [ ] Secure key storage (HSM, KMS) ### Common Mistakes ```typescript // ❌ Weak random generation const token = Math.random().toString(36); // ✅ Cryptographically secure random const crypto = require('crypto'); const token = crypto.randomBytes(32).toString('hex'); // ❌ MD5/SHA1 for passwords const hash = crypto.createHash('md5').update(password).digest('hex'); // ✅ Use bcrypt or argon2 const bcrypt = require('bcrypt'); const hash = await bcrypt.hash(password, 12); ``` ## Dependency Security ### Checklist - [ ] Dependencies from trusted sources only - [ ] No known vulnerabilities (npm audit, cargo audit) - [ ] Dependencies kept up to date - [ ] Lock files committed (package-lock.json, Cargo.lock) - [ ] Minimal dependency usage - [ ] License compliance verified ### Audit Commands ```bash # Node.js npm audit npm audit fix # Python pip-audit safety check # Rust cargo audit # General snyk test ``` ## Logging & Monitoring ### Secure Logging - [ ] No sensitive data in logs (passwords, tokens, PII) - [ ] Logs protected from tampering - [ ] Appropriate log retention - [ ] Security events logged (login attempts, permission changes) - [ ] Log injection prevented ```typescript // ❌ Logging sensitive data logger.info(`User login: ${email}, password: ${password}`); // ✅ Safe logging logger.info('User login attempt', { email, success: true }); ``` ## Security Review Severity Levels | Severity | Description | Action | |----------|-------------|--------| | **Critical** | Immediate exploitation possible, data breach risk | Block merge, fix immediately | | **High** | Significant vulnerability, requires specific conditions | Block merge, fix before release | | **Medium** | Moderate risk, defense in depth concern | Should fix, can merge with tracking | | **Low** | Minor issue, best practice violation | Nice to fix, non-blocking | | **Info** | Suggestion for improvement | Optional enhancement |