Files
Kordant/tasks/web-production/30-websocket-production.md
2026-05-26 16:06:34 -04:00

2.9 KiB

30. WebSocket Production Hardening

meta: id: web-production-30 feature: web-production priority: P1 depends_on: [] tags: [security, websockets, production]

objective:

  • Harden WebSocket server for production with authentication, rate limiting, and connection management

deliverables:

  • Authenticated WebSocket connections
  • Connection rate limiting
  • Connection cleanup on logout
  • Horizontal scaling support (Redis adapter)

steps:

  1. Harden WebSocket authentication:
    • Validate JWT token in connection query param
    • Reject unauthenticated connections immediately
    • Re-authenticate periodically (every 15 minutes)
    • Close connection on token expiry
  2. Implement connection rate limiting:
    • Max 1 WebSocket connection per user
    • Max 5 reconnection attempts per minute
    • IP-based connection limits (100 per IP)
  3. Add connection management:
    • Track active connections per user
    • Close duplicate connections
    • Heartbeat with timeout (current implementation good)
    • Graceful close on server shutdown
  4. Implement horizontal scaling:
    • Use Redis adapter for ws (socket.io-redis or @socket.io/redis-adapter)
    • Or use Redis pub/sub for broadcast across instances
    • Ensure alerts reach all connected clients regardless of instance
  5. Add message validation:
    • Validate all incoming message schemas
    • Reject malformed messages
    • Limit message size (max 10KB)
    • Sanitize message content
  6. Add monitoring:
    • Track active connection count
    • Track messages per second
    • Track connection duration
    • Alert on connection spikes (possible DDoS)
  7. Secure WebSocket server:
    • Run on separate port or path
    • TLS encryption (wss://)
    • No mixed content (ws on https page)

tests:

  • Unit: Test authentication rejection
  • Integration: Test duplicate connection handling
  • Load: Test 1000 concurrent WebSocket connections
  • Security: Test unauthenticated connection rejection

acceptance_criteria:

  • All WebSocket connections authenticated with valid JWT
  • Unauthenticated connections rejected immediately
  • Max 1 connection per user (duplicates closed)
  • Heartbeat/ping-pong working with 30s interval
  • Redis adapter active for multi-instance deployment
  • Message size limited to 10KB
  • TLS encryption (wss://) in production
  • Connection metrics visible in monitoring
  • Graceful shutdown closes all connections cleanly

validation:

  • Connect without token → connection rejected
  • Connect with valid token → connection accepted
  • Open second connection → first connection closed
  • Send 20KB message → connection closed with error
  • Scale to 2 server instances → alerts broadcast to all clients
  • Check metrics → active connections, message rate visible

notes:

  • Current WebSocket in web/src/lib/websocket.ts and web/src/server/websocket.ts
  • ws library supports Redis adapter for scaling
  • Consider using Socket.io for more robust connection management
  • WebSocket auth via query params is common but consider cookie-based for security