Boas Práticas de Segurança para Webhooks
O que é
Este guia apresenta as melhores práticas de segurança para configurar e usar webhooks, protegendo seus dados e garantindo integridade nas integrações.
Por que é importante
Webhooks transmitem dados sensíveis entre sistemas. Sem segurança adequada:
- ❌ Dados podem ser interceptados
- ❌ Atacantes podem enviar dados falsos
- ❌ Informações de clientes podem vazar
- ❌ Sistemas podem ser comprometidos
Práticas Essenciais
1. Sempre use HTTPS
Nunca use URLs HTTP (sem S) para webhooks.
❌ http://meusite.com/webhook
✅ https://meusite.com/webhookHTTPS garante que os dados são criptografados durante a transmissão.
2. Use tokens de autenticação
Todo webhook do Deskito inclui um token único:
https://api.deskito.com/webhook?token=seu_token_secretoCuidados com o token:
- Nunca compartilhe publicamente
- Não coloque em repositórios de código
- Regenere se suspeitar de vazamento
- Use variáveis de ambiente para armazenar
3. Valide a origem das requisições
Se você está recebendo webhooks, valide que vieram do Deskito:
Verificar IP de origem
IPs permitidos do Deskito:
# Lista de IPs autorizados
# (verificar documentação atualizada)Verificar headers
O Deskito envia headers de identificação:
X-Deskito-Webhook-Id: wh_abc123
X-Deskito-Signature: sha256=abcdef...
X-Deskito-Timestamp: 17068866004. Implemente assinatura HMAC
Para webhooks de saída, o Deskito pode assinar o payload:
const crypto = require('crypto');
function verifySignature(payload, signature, secret) {
const expectedSignature = crypto
.createHmac('sha256', secret)
.update(payload)
.digest('hex');
return `sha256=${expectedSignature}` === signature;
}
// Uso
const isValid = verifySignature(
JSON.stringify(req.body),
req.headers['x-deskito-signature'],
'seu_webhook_secret'
);
if (!isValid) {
return res.status(401).json({ error: 'Invalid signature' });
}5. Valide o timestamp
Previna ataques de replay verificando a idade da requisição:
function isTimestampValid(timestamp, maxAgeSeconds = 300) {
const now = Math.floor(Date.now() / 1000);
const requestTime = parseInt(timestamp);
return Math.abs(now - requestTime) <= maxAgeSeconds;
}
// Rejeitar requisições com mais de 5 minutos
if (!isTimestampValid(req.headers['x-deskito-timestamp'])) {
return res.status(401).json({ error: 'Request too old' });
}6. Valide o payload
Antes de processar, valide a estrutura dos dados:
function validateLeadPayload(data) {
// Nome é obrigatório
if (!data.name || typeof data.name !== 'string') {
throw new Error('Nome inválido');
}
// Email deve ter formato válido (se fornecido)
if (data.email && !isValidEmail(data.email)) {
throw new Error('Email inválido');
}
// Sanitizar dados
return {
name: sanitize(data.name),
email: data.email ? sanitize(data.email) : null,
phone: data.phone ? sanitize(data.phone) : null
};
}7. Implemente rate limiting
Proteja seu endpoint contra abusos:
const rateLimit = require('express-rate-limit');
const webhookLimiter = rateLimit({
windowMs: 60 * 1000, // 1 minuto
max: 100, // máximo 100 requisições por minuto
message: { error: 'Too many requests' }
});
app.post('/webhook', webhookLimiter, handleWebhook);8. Responda rapidamente
Webhooks esperam resposta em poucos segundos:
app.post('/webhook', async (req, res) => {
// Responda imediatamente
res.status(200).json({ received: true });
// Processe em background
processWebhookAsync(req.body);
});9. Implemente retry handling
Se seu servidor falhar, o Deskito tentará novamente:
| Tentativa | Intervalo |
|---|---|
| 1ª | Imediata |
| 2ª | 1 minuto |
| 3ª | 5 minutos |
| 4ª | 30 minutos |
| 5ª | 2 horas |
Implemente idempotência para evitar duplicatas:
async function handleWebhook(payload) {
const webhookId = payload.webhook_id;
// Verificar se já processou
if (await wasProcessed(webhookId)) {
console.log('Webhook já processado, ignorando');
return;
}
// Processar
await processPayload(payload);
// Marcar como processado
await markAsProcessed(webhookId);
}10. Monitore e registre logs
Mantenha logs detalhados:
function logWebhook(req, result) {
console.log({
timestamp: new Date().toISOString(),
webhook_id: req.headers['x-deskito-webhook-id'],
ip: req.ip,
user_agent: req.headers['user-agent'],
payload_size: JSON.stringify(req.body).length,
result: result,
processing_time_ms: Date.now() - req.startTime
});
}Checklist de Segurança
Antes de colocar em produção:
- [ ] URL usa HTTPS
- [ ] Token está configurado e seguro
- [ ] Assinatura HMAC está sendo validada
- [ ] Timestamp está sendo verificado
- [ ] Payload está sendo validado
- [ ] Rate limiting está ativo
- [ ] Resposta é enviada em < 5 segundos
- [ ] Idempotência está implementada
- [ ] Logs estão configurados
- [ ] Monitoramento de erros está ativo
O que fazer se suspeitar de comprometimento
- Regenere o token imediatamente
- Revise os logs das últimas 24-48h
- Verifique dados criados por webhook
- Notifique a equipe de segurança
- Documente o incidente
Dicas e boas práticas
- Faça auditoria periódica de segurança
- Mantenha dependências atualizadas
- Use secrets managers (não hardcode)
- Teste webhooks em ambiente de staging primeiro
- Tenha plano de resposta a incidentes
Links relacionados: