Saltar al contenido principal
Firecrawl firma todas las solicitudes de webhook mediante HMAC-SHA256. Verificar estas firmas garantiza que las solicitudes sean auténticas y no hayan sido manipuladas.

Clave secreta

Tu secreto de webhook está disponible en la pestaña Advanced de la configuración de tu cuenta. Cada cuenta tiene un secreto único que se utiliza para firmar todas las solicitudes de webhook.
Mantén tu secreto de webhook seguro y nunca lo expongas públicamente. Si crees que tu secreto se ha visto comprometido, regénéralo de inmediato desde la configuración de tu cuenta.

Verificación de firmas

Cada solicitud de webhook incluye un encabezado X-Firecrawl-Signature:
X-Firecrawl-Signature: sha256=abc123def456...

Cómo verificar

  1. Extrae la firma del encabezado X-Firecrawl-Signature
  2. Obtén el cuerpo sin procesar de la solicitud (antes de analizarlo)
  3. Calcula el HMAC-SHA256 usando tu clave secreta
  4. Compara las firmas usando una función de comparación segura frente al tiempo

Implementación

import crypto from 'crypto';
import express from 'express';

const app = express();

// Usa el analizador de cuerpo en bruto para verificar la firma
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('No autorizado');
  }
  
  // Extrae el hash del encabezado de la firma
  const [algorithm, hash] = signature.split('=');
  if (algorithm !== 'sha256') {
    return res.status(401).send('Algoritmo de firma no válido');
  }
  
  // Calcula la firma esperada
  const expectedSignature = crypto
    .createHmac('sha256', webhookSecret)
    .update(req.body)
    .digest('hex');
  
  // Verifica la firma usando una comparación segura contra ataques de temporización
  if (!crypto.timingSafeEqual(Buffer.from(hash, 'hex'), Buffer.from(expectedSignature, 'hex'))) {
    return res.status(401).send('Firma no válida');
  }
  
  // Analiza y procesa el webhook verificado
  const event = JSON.parse(req.body);
  console.log('Webhook de Firecrawl verificado:', event);
  
  res.status(200).send('ok');
});

app.listen(3000, () => console.log('Escuchando en el puerto 3000'));

Prácticas recomendadas

Valida siempre las firmas

Nunca proceses un webhook sin verificar primero su firma:
app.post('/webhook', (req, res) => {
  if (!verifySignature(req)) {
    return res.status(401).send('No autorizado');
  }
  processWebhook(req.body);
  res.status(200).send('OK');
});

Usa comparaciones seguras en tiempo constante

Las comparaciones de cadenas estándar pueden filtrar información por temporización. Usa crypto.timingSafeEqual() en Node.js o hmac.compare_digest() en Python.

Usa HTTPS

Usa siempre un endpoint HTTPS para tu webhook para garantizar que los datos estén cifrados en tránsito.