Webhooks

Fundamentos Security Notes Jan 6, 2025 JAVASCRIPT
events real-time integration push callbacks

Definicion

Imagina que estás esperando un paquete. Podrías revisar la página de seguimiento cada hora (polling), o podrías registrarte para notificaciones de entrega que te envían un mensaje cuando el paquete llega. Los webhooks son ese sistema de notificación para APIs - en lugar de que tu aplicación pregunte constantemente “¿pasó algo?”, el otro servicio te avisa proactivamente cuando ocurre algo interesante.

En términos técnicos, un webhook es un callback HTTP: cuando ocurre un evento en un sistema, ese sistema hace una petición HTTP POST a una URL que tú especificaste, entregando datos sobre el evento. Tú registras tu URL (“llama a este endpoint cuando alguien haga un pago”), y el proveedor la llama automáticamente cuando ocurre el evento. Es lo inverso del patrón normal de API donde tú los llamas a ellos.

Este enfoque es dramáticamente más eficiente que el polling. En lugar de hacer miles de peticiones que mayormente devuelven “nope, nada nuevo,” solo procesas eventos cuando realmente ocurren. Para integraciones con procesadores de pago, servicios de notificación, pipelines CI/CD y un sinfín de otros sistemas, los webhooks son el patrón estándar. Permiten reacciones en tiempo real a eventos sin la sobrecarga de verificación constante.

Ejemplo

Notificaciones de pago: Cuando un cliente completa un pago en Stripe, Stripe envía un webhook a tu servidor con todos los detalles del pago. Usas esto para procesar pedidos, enviar emails de confirmación, y actualizar tu base de datos - todo activado automáticamente en el momento en que el pago tiene éxito.

CI/CD de GitHub: Cuando haces push de código a GitHub, un webhook notifica a tu sistema CI (Jenkins, CircleCI, etc.) para comenzar a compilar y testear. La compilación comienza inmediatamente sin que el sistema CI necesite consultar constantemente a GitHub.

Integraciones de Slack: Cuando algo pasa en tu app (nuevo registro, alerta de error, venta completada), puedes enviar un webhook a Slack para publicar un mensaje automáticamente. Esto impulsa todas esas notificaciones de “Nueva venta: 99€ de Alice!” en los canales de Slack de las empresas.

Actualizaciones de envío de e-commerce: Los transportistas como FedEx y UPS ofrecen webhooks. Cuando el estado de un paquete cambia (enviado, en tránsito, entregado), notifican a tu sistema, que luego puede notificar a tus clientes.

Analogia

La Notificación del Timbre: En lugar de verificar constantemente tu puerta principal buscando visitantes (polling), un timbre suena cuando alguien llega (webhook). Solo respondes cuando hay realmente alguien ahí. Los webhooks son timbres para tus aplicaciones.

El Sistema de Alerta de Emergencia: Tu teléfono no verifica alertas de emergencia cada segundo. En cambio, el sistema de alertas envía notificaciones cuando ocurren emergencias. Los webhooks siguen este modelo push - recibes información cuando está disponible.

La Suscripción al Periódico: En lugar de ir al quiosco cada mañana para verificar si llegó el periódico (polling), lo tienes entregado en tu puerta (webhook). La entrega ocurre automáticamente cuando hay algo nuevo.

La Alarma de Incendios: Una alarma de incendios no requiere que verifiques periódicamente si hay fuegos. Monitorea continuamente y te alerta inmediatamente cuando detecta humo. Los webhooks crean alertas instantáneas similares para eventos digitales.

Code Example


// Registrar un webhook
POST /api/webhooks
{
  "url": "https://myapp.com/webhooks/payment",
  "events": ["payment.completed", "payment.failed"]
}

// Recibir webhook (Express.js)
app.post('/webhooks/payment', (req, res) => {
  const event = req.body;

  // Verificar firma por seguridad
  const signature = req.headers['x-webhook-signature'];
  if (!verifySignature(event, signature, secret)) {
    return res.status(401).send('Firma inválida');
  }

  // Procesar evento
  if (event.type === 'payment.completed') {
    processPayment(event.data);
  }

  // Confirmar recepción
  res.status(200).send('OK');
});

// Ejemplo de payload de webhook
{
  "id": "evt_123",
  "type": "payment.completed",
  "created": 1609459200,
  "data": {
    "amount": 1000,
    "currency": "eur",
    "customer": "cus_123"
  }
}

Diagram

sequenceDiagram
participant Client
participant Provider
Client->>Provider: POST /webhooks
Provider->>Client: 201 Created + secret
Provider->>Provider: Evento ocurre
Provider->>Client: POST callback + firma
Client->>Client: Verificar firma
Client->>Provider: 200 OK
Provider--xClient: Entrega falla
Provider->>Client: Reintentar con backoff

Notas de Seguridad

SECURITY NOTES

Requisitos Principales:

  • Siempre verifica las firmas de webhook usando HMAC u otros métodos criptográficos.
  • Usa HTTPS para URLs de webhook.
  • Implementa idempotencia para manejar entregas duplicadas.

Mejores Prácticas:

  • Valida las direcciones IP de origen del webhook.
  • Almacena secretos de webhook de forma segura.
  • Implementa lógica de reintentos y backoff exponencial para entregas fallidas.
  • Considera usar una cola para procesar webhooks asincrónicamente para prevenir timeouts..

Mejores Prácticas

  1. Siempre verifica firmas de webhook usando HMAC-SHA256 o similar
  2. Usa solo endpoints HTTPS - nunca aceptes webhooks sobre HTTP
  3. Implementa idempotencia usando IDs de evento para manejar entregas duplicadas
  4. Retorna 200 OK inmediatamente, procesa el payload asincrónicamente via cola
  5. Almacena secretos de webhook de forma segura (variables de entorno, secrets manager)
  6. Implementa manejo de reintentos apropiado con backoff exponencial

Errores Comunes

No validar firmas de webhook (riesgo de seguridad), procesar webhooks sincrónicamente causando timeouts, no manejar entregas duplicadas (sin idempotencia), exponer endpoints HTTP, retornar no-2xx antes de completar procesamiento, no registrar webhooks fallidos para depuración, hardcodear secretos de webhook en código.

Standards & RFCs