Firecrawl assina todas as requisições de webhook usando HMAC-SHA256. Verificar essas assinaturas garante que as requisições sejam autênticas e não tenham sido adulteradas.
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'));
Sempre valide as assinaturas
Nunca processe um webhook sem verificar a assinatura antes:
app.post('/webhook', (req, res) => {
if (!verifySignature(req)) {
return res.status(401).send('Não autorizado');
}
processWebhook(req.body);
res.status(200).send('OK');
});
Use comparações seguras em termos de tempo
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.
Sempre use HTTPS no endpoint do webhook para garantir que os dados sejam criptografados em trânsito.