Skip to content
This repository was archived by the owner on Jan 29, 2026. It is now read-only.
This repository was archived by the owner on Jan 29, 2026. It is now read-only.

[Security] Implement WebSocket Authentication #67

@coderabbitai

Description

@coderabbitai

🔒 Priority: HIGH - Security & Stability

Background

Currently, the WebSocket server at backend/src/websocket/server.js accepts connections without any authentication. This allows any client to connect to /ws and receive real-time workflow and store state updates, potentially exposing sensitive data.

Current Implementation

// backend/src/websocket/server.js (lines 51-55)
handleConnection(ws, req) {
  const clientId = `client-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
  // No authentication check!
  this.clients.set(clientId, ws);
  ws.isAlive = true;
  // ...
}

Security Risk

  • Unauthenticated access to real-time workflow data
  • Potential data leakage to unauthorized clients
  • No access control for WebSocket connections
  • Bypasses the API key authentication used in HTTP routes

Recommended Solution

Implement API key authentication for WebSocket connections by:

  1. Extract API key from query parameters or upgrade request headers
  2. Validate against existing auth middleware logic
  3. Close connection with proper status code if authentication fails
  4. Store authenticated client metadata
// Suggested implementation for backend/src/websocket/server.js
handleConnection(ws, req) {
  // Extract API key from query params
  const url = new URL(req.url, 'ws://localhost');
  const apiKey = url.searchParams.get('apiKey');
  
  // Validate API key (reuse logic from backend/src/api/middleware/auth.js)
  const DEFAULT_API_KEY = process.env.API_KEY || 'dev-api-key-change-in-production';
  
  if (!apiKey || apiKey !== DEFAULT_API_KEY) {
    console.warn(`❌ Unauthorized WebSocket connection attempt from ${req.socket.remoteAddress}`);
    ws.close(1008, 'Unauthorized'); // Policy Violation
    return;
  }
  
  // Continue with authenticated connection
  const clientId = `client-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
  this.clients.set(clientId, { ws, authenticated: true, connectedAt: Date.now() });
  // ...
}

Files to Modify

  • backend/src/websocket/server.js (handleConnection method, lines 51-72)
  • Potentially extract auth validation to shared utility in backend/src/api/middleware/auth.js

Acceptance Criteria

  • WebSocket connections require valid API key via query parameter or header
  • Unauthenticated connection attempts are rejected with status 1008
  • Authentication failures are logged with client IP
  • Authenticated client metadata is stored (auth timestamp, key hash, etc.)
  • Frontend/TUI clients updated to pass API key during connection
  • Documentation updated with WebSocket authentication requirements
  • Tests added for auth success/failure scenarios

Testing Plan

  1. Attempt connection without API key → should be rejected
  2. Attempt connection with invalid API key → should be rejected
  3. Attempt connection with valid API key → should succeed
  4. Verify existing functionality works with authenticated connections

References

Additional Context

This issue blocks production deployment and should be addressed before exposing the WebSocket endpoint to untrusted networks.

Metadata

Metadata

Labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions