Structured security audit for Node.js HTTP servers and web applications.
Hardcoded Secrets
grep -rn "password\|secret\|token\|apikey\|api_key" --include=".js" --include=".ts" | grep -v node_modules | grep -v "process.env\|\.env"if (!process.env.SECRET) process.exit(1);XSS in Dynamic Content
innerHTML, template literals injected into DOM, unsanitized user input in responsestextContent, or escape: str.replace(/[&<>"']/g, c => ({'&':'&','<':'<','>':'>','"':'"',"'":"'"}[c]))SQL/NoSQL Injection
eval(), Function() with user inputCORS Misconfiguration
Access-Control-Allow-Origin: *const origin = ALLOWED.has(req.headers.origin) ? req.headers.origin : ALLOWED.values().next().valueAuth Bypass
Path Traversal
path.normalize() + startsWith(allowedDir) on all file-serving routesfs.realpathSync() and re-checkSecurity Headers
const HEADERS = {
'X-Frame-Options': 'SAMEORIGIN',
'X-Content-Type-Options': 'nosniff',
'Referrer-Policy': 'strict-origin-when-cross-origin',
'Permissions-Policy': 'camera=(), microphone=(), geolocation=()',
};
// Apply to all responses
Rate Limiting
const attempts = new Map(); // ip -> { count, resetAt }
const LIMIT = 5, WINDOW = 60000;
function isLimited(ip) {
const now = Date.now(), e = attempts.get(ip);
if (!e || now > e.resetAt) { attempts.set(ip, {count:1, resetAt:now+WINDOW}); return false; }
return ++e.count > LIMIT;
}
Input Validation
if (bodySize > 1048576) { req.destroy(); return; }Dependency Audit: npm audit
Error Leakage: Don't send stack traces to clients in production
Cookie Security: HttpOnly; Secure; SameSite=Strict
## Security Audit: [filename]
### Critical
1. **[Category]** Description — File:Line — Fix: ...
### High
...
### Medium
...
### Low
...
### Summary
X critical, X high, X medium, X low
共 1 个版本