Visão geral: por que segurança importa em WebSockets
WebSockets oferece comunicação bidirecional persistente entre cliente e servidor. Em aplicações críticas,
poucos minutos de indisponibilidade ou manipulação de mensagens podem causar impactos significativos.
Este post aborda práticas essenciais para autenticação, integridade, transporte seguro e operação estável
de websockets em produção.
1) Autenticação, autorização e checagem de origem
- Use autenticação robusta no handshake: inclua tokens de sessão (JWT ou cookies HttpOnly) no query string ou no header do handshake, com validação no servidor.
- Implemente autorização baseada em recurso: garanta que o usuário conectado tenha permissão para operações específicas antes de aceitar mensagens.
- Valide a origem: permita apenas origens confiáveis para evitar ataques Cross-Site WebSocket Hijacking (CWSH). Combine checagem de origem com políticas de CORS onde aplicável.
- Verifique o subprotocolo negociado e, se possível, utilize subprotocolos explícitos para separar fluxos de mensagens por finalidade (por exemplo, “chat”, “notifications”).
2) Transporte seguro e configuração prática
Utilize WebSockets sobre TLS (wss://) para proteger a confidencialidade e a integridade dos dados em trânsito. Considere as seguintes práticas:
- TLS com configuração atualizada, com cipher suites fortes e suporte a TLS 1.2+.
- Terminação TLS segura no edge, sem decodificação desnecessária no caminho de dados.
- Valide certificados no cliente e no servidor; ative pinning quando possível em clientes nativos.
- Implemente um tempo de vida de sessão e renovação de tokens para minimizar reutilização de credenciais.
// Exemplo de servidor WebSocket com verificação de origem e heartbeat
// Requer: npm i ws
const WebSocket = require('ws');
const allowedOrigins = new Set(['https://meu-dominio.com', 'https://app.segura.local']);
function verifyOrigin(info) {
const origin = info.origin || '';
if (!allowedOrigins.has(origin)) return false;
// Opcional: verifique token no query string
// const url = new URL(info.req.url, 'https://dummy');
// const token = url.searchParams.get('token');
// return !!token && validateToken(token);
return true;
}
const wss = new WebSocket.Server({ port: 8080, verifyClient: (info, done) => {
if (verifyOrigin(info)) return done(true);
return done(false, 403, 'Origin não permitido');
}});
wss.on('connection', (ws) => {
ws.isAlive = true;
ws.on('pong', () => { ws.isAlive = true; });
ws.on('message', (msg) => {
// Valide e processe a mensagem conforme o contrato da sua aplicação
console.log('mensagem recebida:', msg.toString());
// ...
});
});
// Keep-alive: detectar clientes mortos
setInterval(() => {
wss.clients.forEach((ws) => {
if (ws.isAlive === false) return ws.terminate();
ws.isAlive = false;
ws.ping(() => {});
});
}, 30000);
// Função fictícia de validação de token
function validateToken(token){
// Implementar validação real com seu provedor de identidade
return Boolean(token);
}
3) Integridade de mensagens e proteção contra replay
- Inclua timestamps e nonces em payloads sensíveis; valide o intervalo de tempo para evitar replay attacks.
- Assine mensagens quando possível: utilize HMAC ou assinatura digital para verificar integridade e autenticidade.
- Avalie a necessidade de seqüências de mensagens para detectar duplicatas, especialmente em cenários de retry.
- Implemente políticas de compactação e validação de formato para reduzir superfície de ataque por payloads maliciosos.
4) Observabilidade, operação segura e implantação
- Monitore métricas de conexão: total de clientes, taxa de mensagens, latência e tempo de ping/pong.
- Implemente limites de taxa (rate limiting) para canais WebSocket e estratégias de backpressure.
- Logue eventos relevantes com níveis adequados (info, warning, error) sem expor dados sensíveis.
- Planeje failover e disponibilidade: use múltiplas réplicas, balanceamento inteligente e health checks.
Gostou? Amplie seu conhecimento
Explore conteúdos relacionados para aprofundar sua prática de segurança em aplicações em tempo real.
Sou Apaixonado pela programação e estou trilhando o caminho de ter cada diz mais conhecimento e trazer toda minha experiência vinda do Design para a programação resultando em layouts incríveis e idéias inovadoras! Conecte-se Comigo!