← back to Wine Finder Next
SECURITY_IMPLEMENTATION_GUIDE.md
490 lines
# Security Implementation Guide
## Quick Start - Integrating Security Features
### 1. Protected API Endpoint Example
```typescript
// app/api/membership/protected/route.ts
import { NextRequest, NextResponse } from 'next/server';
import { verifyJWT, extractTokenFromHeader } from '@/lib/jwtAuth';
import { requireCSRF } from '@/lib/csrf';
import { verifySession } from '@/lib/sessionManagement';
import { verifyTOTP, has2FAEnabled } from '@/lib/twoFactorAuth';
import { checkRateLimit, getClientIdentifier } from '@/lib/rateLimit';
import { analyzeRequest } from '@/lib/securityMonitoring';
export async function POST(request: NextRequest) {
// 1. Rate Limiting
const clientIp = getClientIdentifier(request);
const rateLimit = checkRateLimit(clientIp, { windowMs: 60000, maxRequests: 10 });
if (!rateLimit.success) {
return NextResponse.json({ error: 'Rate limit exceeded' }, { status: 429 });
}
// 2. JWT Authentication
const authHeader = request.headers.get('authorization');
const token = extractTokenFromHeader(authHeader);
if (!token) {
return NextResponse.json({ error: 'Authentication required' }, { status: 401 });
}
const { valid, payload } = verifyJWT(token);
if (!valid) {
return NextResponse.json({ error: 'Invalid token' }, { status: 401 });
}
// 3. Session Verification
const sessionToken = request.cookies.get('session')?.value;
if (sessionToken) {
const session = verifySession(sessionToken, clientIp);
if (!session.valid) {
return NextResponse.json({ error: 'Invalid session' }, { status: 401 });
}
}
// 4. 2FA Check (for sensitive operations)
if (has2FAEnabled(payload.sub)) {
const totpCode = request.headers.get('x-totp-code');
if (!totpCode) {
return NextResponse.json({ error: '2FA code required' }, { status: 403 });
}
const { valid: totpValid } = verifyTOTP(payload.sub, totpCode, clientIp);
if (!totpValid) {
return NextResponse.json({ error: 'Invalid 2FA code' }, { status: 403 });
}
}
// 5. CSRF Protection (for state-changing operations)
const csrfCheck = requireCSRF(
{ headers: Object.fromEntries(request.headers) },
sessionToken,
clientIp
);
if (!csrfCheck.success) {
return NextResponse.json({ error: csrfCheck.error }, { status: 403 });
}
// 6. Input Validation & Threat Detection
const body = await request.json();
const analysis = analyzeRequest({
body,
headers: Object.fromEntries(request.headers),
ip: clientIp
});
if (!analysis.safe) {
return NextResponse.json({
error: 'Security threat detected',
threats: analysis.threats
}, { status: 403 });
}
// Your business logic here
return NextResponse.json({ success: true, data: 'Protected resource accessed' });
}
```
### 2. User Registration with 2FA Setup
```typescript
// app/api/auth/register/route.ts
import { userDb, validatePassword, hashPassword } from '@/lib/auth';
import { generateTOTPSecret, enableTOTP } from '@/lib/twoFactorAuth';
import { createSession } from '@/lib/sessionManagement';
import { generateCSRFToken } from '@/lib/csrf';
export async function POST(request: NextRequest) {
const { email, password } = await request.json();
// Validate password strength
const passwordCheck = validatePassword(password);
if (!passwordCheck.valid) {
return NextResponse.json({
error: 'Weak password',
requirements: passwordCheck.errors
}, { status: 400 });
}
// Create user
const user = userDb.create(email, password);
if (!user) {
return NextResponse.json({ error: 'User already exists' }, { status: 409 });
}
// Generate 2FA setup
const { secret, qrCode, backupCodes } = generateTOTPSecret(user.id);
// Create session
const clientIp = getClientIdentifier(request);
const { session, token } = createSession(
user.id,
clientIp,
request.headers.get('user-agent') || ''
);
// Generate CSRF token
const csrfToken = generateCSRFToken(session.id, clientIp);
// Create JWT
const jwtToken = createJWT(user.id, user.email, user.role);
return NextResponse.json({
success: true,
user: { id: user.id, email: user.email },
tokens: {
jwt: jwtToken,
session: token,
csrf: csrfToken
},
twoFactor: {
qrCode,
backupCodes,
setupRequired: true
}
});
}
```
### 3. High-Value Transaction with Request Signing
```typescript
// app/api/marketplace/purchase/route.ts
import { verifySignedRequest, requiresSigning } from '@/lib/requestSigning';
export async function POST(request: NextRequest) {
const body = await request.json();
const { quantity, bottleId, totalValue } = body;
// Check if request signing is required
if (requiresSigning(request.nextUrl.pathname, totalValue)) {
const headers = Object.fromEntries(request.headers);
const clientIp = getClientIdentifier(request);
const { valid, userId, error } = verifySignedRequest(
headers,
'POST',
request.nextUrl.pathname,
body,
clientIp
);
if (!valid) {
return NextResponse.json({
error: 'Request signature required',
details: error
}, { status: 403 });
}
// Process high-value transaction
// ... your purchase logic
}
// Regular transaction processing
// ... your purchase logic
}
```
### 4. API Versioning Implementation
```typescript
// app/api/v2/wines/route.ts
import { versionMiddleware, transformResponseForVersion } from '@/lib/apiVersioning';
export async function GET(request: NextRequest) {
return versionMiddleware(request, async (req, version) => {
// Version-specific logic
let data;
if (version === 'v3') {
// V3 with advanced features
data = {
wines: await getWines(),
graphqlSchema: '...',
websocketUrl: 'wss://...',
batchOperations: true
};
} else if (version === 'v2') {
// V2 standard response
data = {
wines: await getWines(),
pagination: { ... }
};
} else {
// V1 legacy format
data = await getWines();
}
return NextResponse.json({
success: true,
data,
version
});
});
}
```
### 5. Admin Endpoint with Complete Security
```typescript
// app/api/admin/users/route.ts
export async function DELETE(request: NextRequest) {
// All security checks in order of importance
// 1. Rate limiting (prevent abuse)
const clientIp = getClientIdentifier(request);
const rateLimit = checkRateLimit(clientIp, { windowMs: 60000, maxRequests: 5 });
if (!rateLimit.success) {
return NextResponse.json({ error: 'Rate limit exceeded' }, { status: 429 });
}
// 2. Authentication (who are you?)
const { valid, payload } = verifyJWT(extractTokenFromHeader(request.headers.get('authorization')));
if (!valid || payload.role !== 'admin') {
return NextResponse.json({ error: 'Admin access required' }, { status: 403 });
}
// 3. Session verification (is your session valid?)
const sessionToken = request.cookies.get('session')?.value;
const session = verifySession(sessionToken, clientIp);
if (!session.valid) {
return NextResponse.json({ error: 'Invalid session' }, { status: 401 });
}
// 4. 2FA verification (prove it's really you)
const totpCode = request.headers.get('x-totp-code');
if (!totpCode || !verifyTOTP(payload.sub, totpCode, clientIp).valid) {
return NextResponse.json({ error: '2FA verification required' }, { status: 403 });
}
// 5. CSRF protection (prevent cross-site attacks)
const csrfCheck = requireCSRF({ headers: Object.fromEntries(request.headers) }, sessionToken, clientIp);
if (!csrfCheck.success) {
return NextResponse.json({ error: csrfCheck.error }, { status: 403 });
}
// 6. Request signing (verify request integrity)
const { valid: signatureValid } = verifySignedRequest(
Object.fromEntries(request.headers),
'DELETE',
request.nextUrl.pathname,
await request.json(),
clientIp
);
if (!signatureValid) {
return NextResponse.json({ error: 'Request signature required' }, { status: 403 });
}
// Execute admin operation
const { userId } = await request.json();
// ... delete user logic
// Audit log
logAudit({
userId: payload.sub,
action: 'ADMIN_DELETE_USER',
resource: `user/${userId}`,
ipAddress: clientIp,
userAgent: request.headers.get('user-agent') || '',
success: true
});
return NextResponse.json({ success: true });
}
```
## Security Middleware Configuration
```typescript
// middleware.ts
import { comprehensiveSecurityCheck } from './lib/advancedSecurity';
import { isIPBlocked } from './lib/securityMonitoring';
import { extractAPIVersion } from './lib/apiVersioning';
export function middleware(request: NextRequest) {
const ip = getClientIdentifier(request);
// 1. Check IP blocklist
if (isIPBlocked(ip)) {
return NextResponse.json({ error: 'Access denied' }, { status: 403 });
}
// 2. Advanced security check for API routes
if (request.nextUrl.pathname.startsWith('/api/')) {
const securityCheck = comprehensiveSecurityCheck({
ip,
headers: Object.fromEntries(request.headers),
method: request.method,
path: request.nextUrl.pathname
});
if (!securityCheck.allowed) {
return NextResponse.json({
error: 'Security check failed',
reason: securityCheck.reason,
riskScore: securityCheck.riskScore
}, { status: 403 });
}
}
// 3. Add security headers
const response = NextResponse.next();
// Security headers
response.headers.set('X-Frame-Options', 'DENY');
response.headers.set('X-Content-Type-Options', 'nosniff');
response.headers.set('X-XSS-Protection', '1; mode=block');
response.headers.set('Strict-Transport-Security', 'max-age=63072000; includeSubDomains; preload');
response.headers.set('Referrer-Policy', 'strict-origin-when-cross-origin');
response.headers.set('Permissions-Policy', 'camera=(), microphone=(), geolocation=()');
// CSP for production
if (process.env.NODE_ENV === 'production') {
response.headers.set(
'Content-Security-Policy',
"default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' data:; connect-src 'self' https:; frame-ancestors 'none'; base-uri 'self'; form-action 'self'"
);
}
// API versioning headers
const { version } = extractAPIVersion(request);
response.headers.set('x-api-version', version);
return response;
}
export const config = {
matcher: [
'/((?!_next/static|_next/image|favicon.ico|.*\\.(?:svg|png|jpg|jpeg|gif|webp)$).*)',
],
};
```
## Testing Security Features
### Test Authentication Flow
```bash
# 1. Register user
curl -X POST http://localhost:3000/api/auth/register \
-H "Content-Type: application/json" \
-d '{"email":"test@example.com","password":"SecurePass123!@#"}'
# 2. Login
curl -X POST http://localhost:3000/api/auth/login \
-H "Content-Type: application/json" \
-d '{"email":"test@example.com","password":"SecurePass123!@#"}'
# 3. Access protected resource with JWT
curl http://localhost:3000/api/protected \
-H "Authorization: Bearer YOUR_JWT_TOKEN"
```
### Test CSRF Protection
```bash
# Get CSRF token
CSRF_TOKEN=$(curl -s http://localhost:3000/api/auth/csrf | jq -r .token)
# Make protected request with CSRF token
curl -X POST http://localhost:3000/api/membership/vote \
-H "Content-Type: application/json" \
-H "X-CSRF-Token: $CSRF_TOKEN" \
-d '{"voteId":"123","choice":"for"}'
```
### Test Request Signing
```javascript
// Node.js example
const crypto = require('crypto');
const apiKey = 'wdao_xxx';
const apiSecret = 'secret_xxx';
const method = 'POST';
const path = '/api/marketplace/purchase';
const body = { bottleId: '123', quantity: 1 };
const timestamp = Date.now();
const nonce = crypto.randomBytes(16).toString('hex');
const signingString = [method, path, timestamp, nonce, JSON.stringify(body)].join('\n');
const signature = crypto.createHmac('sha256', apiSecret).update(signingString).digest('hex');
fetch(`http://localhost:3000${path}`, {
method,
headers: {
'x-api-key': apiKey,
'x-signature': signature,
'x-timestamp': timestamp,
'x-nonce': nonce,
'Content-Type': 'application/json'
},
body: JSON.stringify(body)
});
```
### Test API Versioning
```bash
# Version in header (preferred)
curl http://localhost:3000/api/wines \
-H "Accept: application/vnd.winedao.v3+json"
# Version in custom header
curl http://localhost:3000/api/wines \
-H "X-API-Version: v2"
# Version in URL path
curl http://localhost:3000/api/v1/wines
# Version in query parameter
curl http://localhost:3000/api/wines?api_version=v3
```
## Security Monitoring
### Access Security Dashboard
```bash
# Get admin token first
ADMIN_TOKEN=$(curl -X POST http://localhost:3000/api/auth/login \
-H "Content-Type: application/json" \
-d '{"email":"admin@winedao.com","password":"ADMIN_PASSWORD"}' | jq -r .token)
# View security dashboard
curl http://localhost:3000/api/security/dashboard \
-H "Authorization: Bearer $ADMIN_TOKEN"
```
### Monitor Security Events
```bash
# Real-time security monitoring
curl http://localhost:3000/api/security/events/stream \
-H "Authorization: Bearer $ADMIN_TOKEN" \
-H "Accept: text/event-stream"
```
## Environment Variables
```env
# .env.production
NODE_ENV=production
JWT_SECRET=your-256-bit-secret-key
SESSION_SECRET=your-session-secret-key
ADMIN_EMAIL=admin@winedao.com
ADMIN_PASSWORD=change-this-immediately
CSRF_SECRET=your-csrf-secret-key
API_SIGNING_SECRET=your-api-signing-secret
```
## Security Checklist
- [ ] Change all default passwords and secrets
- [ ] Enable 2FA for all admin accounts
- [ ] Configure HTTPS with valid SSL certificate
- [ ] Set up monitoring and alerting
- [ ] Review and update security headers
- [ ] Implement backup and recovery procedures
- [ ] Schedule regular security audits
- [ ] Train team on security best practices
- [ ] Document incident response procedures
- [ ] Test all security features regularly