← 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