Verifique se cada requisição de webhook realmente veio do Firecrawl conferindo sua assinatura HMAC-SHA256. Isso impede que invasores falsifiquem payloads e permite que você confie nos dados antes de agir com base neles.
Seu segredo de webhook está disponível na aba Advanced das configurações da sua conta. Cada conta tem um segredo exclusivo usado para assinar todas as solicitações de webhook.
Mantenha seu segredo de webhook em segurança e nunca o exponha publicamente. Se você acreditar que seu segredo foi comprometido, gere um novo imediatamente nas configurações da sua conta.
Verificação de assinatura
Cada requisição de webhook inclui um cabeçalho X-Firecrawl-Signature:
X-Firecrawl-Signature: sha256=abc123def456...
- Extraia a assinatura do cabeçalho
X-Firecrawl-Signature
- Obtenha o corpo bruto da requisição exatamente como recebido (não faça parsing antes)
- Calcule o HMAC-SHA256 usando sua chave secreta
- Compare as assinaturas usando uma função de comparação segura a timing (timing-safe)
import crypto from 'crypto';
import express from 'express';
const app = express();
// Use o parser de corpo bruto para verificar a assinatura
app.use('/webhook/firecrawl', express.raw({ type: 'application/json' }));
app.post('/webhook/firecrawl', (req, res) => {
const signature = req.get('X-Firecrawl-Signature');
const webhookSecret = process.env.FIRECRAWL_WEBHOOK_SECRET;
if (!signature || !webhookSecret) {
return res.status(401).send('Não autorizado');
}
// Extraia o hash do cabeçalho de assinatura
const [algorithm, hash] = signature.split('=');
if (algorithm !== 'sha256') {
return res.status(401).send('Algoritmo de assinatura inválido');
}
// Calcule a assinatura esperada
const expectedSignature = crypto
.createHmac('sha256', webhookSecret)
.update(req.body)
.digest('hex');
// Verifique a assinatura usando comparação com segurança temporal
if (!crypto.timingSafeEqual(Buffer.from(hash, 'hex'), Buffer.from(expectedSignature, 'hex'))) {
return res.status(401).send('Assinatura inválida');
}
// Analise e processe o webhook verificado
const event = JSON.parse(req.body);
console.log('Webhook do Firecrawl verificado:', event);
res.status(200).send('ok');
});
app.listen(3000, () => console.log('Escutando na porta 3000'));
- Verifique cada requisição. Sempre verifique a assinatura antes de processar um payload de webhook. Rejeite qualquer requisição que falhe na verificação com status
401.
- Use comparações seguras a timing. Comparações padrão de strings podem revelar informações por tempo de execução. Use
crypto.timingSafeEqual() no Node.js ou hmac.compare_digest() no Python.
- Disponibilize seu endpoint via HTTPS. Isso garante que os payloads de webhook sejam criptografados em trânsito.