DocsSection 8
8Section 8 of 10
Security Model
Security Model
8.1 Defense in Depth
Multiple layers of protection:
1. HTTPS (Nginx terminates SSL)
↓
2. Security Headers (CSP, HSTS, X-Frame-Options)
↓
3. Rate Limiting (prevents brute force)
↓
4. Authentication (session cookies)
↓
5. Authorization (role checks)
↓
6. Input Validation (Zod schemas)
↓
7. SQL Parameterization (prevents injection)
↓
8. Output Encoding (XSS prevention)
8.2 Security Headers
In middleware.ts:
response.headers.set('Strict-Transport-Security',
'max-age=63072000; includeSubDomains; preload');
response.headers.set('X-Frame-Options', 'DENY');
response.headers.set('X-Content-Type-Options', 'nosniff');
response.headers.set('Content-Security-Policy',
"default-src 'self'; script-src 'self' 'unsafe-inline' ...");
8.3 Rate Limiting
File: lib/rate-limit.ts
const rateLimits = new Map<string, { count: number; resetTime: number }>();
export function checkRateLimit(key: string, maxRequests: number, windowMs: number): boolean {
const now = Date.now();
const record = rateLimits.get(key);
if (!record || now > record.resetTime) {
// New window
rateLimits.set(key, { count: 1, resetTime: now + windowMs });
return true;
}
if (record.count >= maxRequests) {
return false; // Rate limited
}
record.count++;
return true;
}
// Usage in API route:
if (!checkRateLimit(ip, 5, 15 * 60 * 1000)) { // 5 requests per 15 min
return NextResponse.json({ error: 'Rate limited' }, { status: 429 });
}