highCWE-346OWASP A01:2021

WebSocket Sin Validacion de Origen

Un servidor WebSocket que no verifica el header Origin acepta conexiones de cualquier sitio web, permitiendo Cross-Site WebSocket Hijacking donde una pagina maliciosa se conecta a tu endpoint WS usando la sesion autenticada de la victima.

Cómo Funciona

A diferencia de las solicitudes HTTP, las conexiones WebSocket no estan sujetas a la politica de mismo origen. Cualquier sitio web puede abrir una conexion WebSocket a cualquier servidor. El navegador incluye las cookies del usuario en el handshake WebSocket automaticamente. Si el servidor WS no valida el header Origin, un sitio web malicioso puede establecer una conexion usando las cookies de sesion de la victima. Esto se llama Cross-Site WebSocket Hijacking (CSWSH). La pagina del atacante en evil.com abre un WebSocket hacia tu-app.com/ws, el navegador envia las cookies de auth del usuario, y el servidor acepta la conexion pensando que es legitima. El atacante puede entonces enviar y recibir mensajes como el usuario autenticado -- leyendo datos privados, enviando comandos o modificando estado en tiempo real.

Código Vulnerable
// BAD: WebSocket server accepts connections from any origin
const WebSocket = require('ws');
const server = new WebSocket.Server({ port: 8080 });

server.on('connection', (ws, req) => {
  // No origin check -- any website can connect
  // Attacker's page at evil.com can connect using victim's cookies
  ws.on('message', (data) => {
    const msg = JSON.parse(data);
    handleMessage(ws, msg); // processes attacker's commands as victim
  });
});
Código Seguro
// GOOD: validate Origin header and authenticate the connection
const WebSocket = require('ws');
const ALLOWED_ORIGINS = ['https://myapp.com', 'https://www.myapp.com'];
const server = new WebSocket.Server({
  port: 8080,
  verifyClient: (info, callback) => {
    const origin = info.origin || info.req.headers.origin;
    if (!ALLOWED_ORIGINS.includes(origin)) {
      callback(false, 403, 'Forbidden: invalid origin');
      return;
    }
    // Also verify auth token from query string or first message
    callback(true);
  }
});

server.on('connection', (ws, req) => {
  ws.on('message', (data) => {
    const msg = JSON.parse(data);
    handleMessage(ws, msg);
  });
});

Ejemplo Real

En 2018, investigadores de seguridad descubrieron que la aplicacion de escritorio de Slack tenia una vulnerabilidad de Cross-Site WebSocket Hijacking. Porque el servidor WebSocket no validaba correctamente el header Origin, un sitio web malicioso podia conectarse a la API WebSocket local de Slack, robar tokens y exfiltrar mensajes. Slack parcheo el problema despues de la divulgacion responsable, pero afecto a todos los usuarios que ejecutaban la app de escritorio.

Cómo Prevenirlo

  • Siempre valida el header Origin en el handshake WebSocket usando verifyClient y rechaza conexiones de origenes inesperados
  • No dependas solo de cookies para la autenticacion de WebSocket -- usa un token pasado en la URL de conexion o primer mensaje que se verifique del lado del servidor
  • Implementa tokens CSRF para el endpoint del handshake WebSocket inicial para prevenir la iniciacion de conexiones cross-site
  • Usa wss:// (WebSocket Secure) exclusivamente para prevenir la intercepcion man-in-the-middle del handshake y trafico WebSocket

Tecnologías Afectadas

Node.jsPythonGo

Data Hogo detecta esta vulnerabilidad automáticamente.

Escanea Tu Repo Gratis

Vulnerabilidades Relacionadas