Verificación de Firmas Webhook: Cómo Proteger tus Integraciones

Ashley Innocent

Ashley Innocent

22 December 2025

Verificación de Firmas Webhook: Cómo Proteger tus Integraciones

Apidog para empresas

Despliegue local

SSO & RBAC

Conforme con SOC 2

Explorar Apidog Enterprise

Los webhooks son una de las formas más potentes de recibir actualizaciones en tiempo real de servicios de terceros. Una sola solicitud HTTP POST de Stripe, GitHub, Shopify o Twilio puede activar lógica de negocio crítica en tu aplicación: cobrar a un cliente, actualizar un repositorio, enviar un pedido o enviar un SMS de confirmación.

Pero cada solicitud de webhook llega a través de la internet pública. Y eso significa que cualquiera que adivine o descubra tu URL de webhook puede enviar cargas maliciosas que parecen completamente legítimas. Sin la autenticación adecuada, tu aplicación no tiene forma de distinguir entre un evento real y uno falsificado.

Ahí es donde entra en juego la verificación de la firma del webhook. Es un mecanismo simple y estandarizado que garantiza que cada solicitud de webhook entrante proviene genuinamente del servicio que esperas y no ha sido alterada durante el tránsito.

En esta guía completa, aprenderás exactamente cómo funciona la verificación de la firma del webhook y cómo implementarla correctamente en lenguajes populares. También verás errores comunes a evitar y cómo probar todo de principio a fin, de forma rápida y fiable.

💡
Antes de entrar en los detalles técnicos, quiero asegurarme de que tienes la herramienta adecuada para verificar y depurar webhooks en minutos. Apidog es completamente gratuito para descargar y ofrece pruebas de verificación de firma de webhook integradas, servidores de prueba (mock servers) e inspección de carga útil en tiempo real, sin necesidad de tarjeta de crédito. Es la forma más rápida de confirmar que tu lógica de verificación funciona realmente.
botón

¿Qué es la verificación de la firma de webhook?

La verificación de la firma de webhook es el proceso de confirmar que una solicitud de webhook entrante realmente proviene del servicio que esperas y no ha sido manipulada.

La mayoría de los proveedores utilizan HMAC (código de autenticación de mensajes basado en hash) con SHA-256 o SHA-512. El servicio calcula:

signature = HMAC-SHA256(secret_key, payload)

Luego, envían la firma en un encabezado (normalmente X-Signature, Signature, o X-Hub-Signature-256).

Tu servidor:

  1. Recibe la carga útil como bytes brutos (¡importante!)
  2. Vuelve a calcular el HMAC usando tu secreto almacenado
  3. Compara la firma calculada con la recibida

Si coinciden exactamente, procesas el webhook. De lo contrario, devuelves HTTP 401 o 403.

Por qué HMAC-SHA256 es el estándar de la industria

Los proveedores eligen HMAC-SHA256 por buenas razones:

GitHub, Stripe, Shopify, Slack y docenas de otros usan HMAC-SHA256.

Cómo implementar la verificación de la firma de webhook en Node.js

Comencemos con un ejemplo real en Node.js.

const crypto = require('crypto');

function verifyWebhookSignature(payload, signature, secret) {
  const hmac = crypto.createHmac('sha256', secret);
  const computedSignature = hmac.update(payload).digest('hex');

  return crypto.timingSafeEqual(
    Buffer.from(computedSignature),
    Buffer.from(signature)
  );
}

Puntos clave a tener en cuenta:

Ejemplo de middleware de Express:

app.post('/webhooks/stripe', (req, res, next) => {
  const signature = req.headers['stripe-signature'];
  const secret = process.env.STRIPE_WEBHOOK_SECRET;

  // Obtener cuerpo crudo (Express necesita middleware para preservar el cuerpo crudo)
  const rawBody = req.rawBody || req.body; // usar body-parser con la opción verify

  if (!verifyWebhookSignature(rawBody, signature, secret)) {
    return res.status(401).send('Firma inválida');
  }

  // La firma es válida → procesar el evento
  next();
});

Implementación en Python (FastAPI + Pydantic)

from fastapi import FastAPI, Request, HTTPException
import hmac
import hashlib

app = FastAPI()

def verify_signature(payload: bytes, signature: str, secret: str) -> bool:
    computed = hmac.new(
        secret.encode(),
        payload,
        hashlib.sha256
    ).hexdigest()

    return hmac.compare_digest(computed, signature)

@app.post("/webhooks/github")
async def github_webhook(request: Request):
    signature = request.headers.get("X-Hub-Signature-256")
    if not signature:
        raise HTTPException(status_code=401, detail="Firma faltante")

    payload = await request.body()

    if not verify_signature(payload, signature.split('=')[1], SECRET):
        raise HTTPException(status_code=401, detail="Firma inválida")

    # Procesar webhook
    return {"status": "ok"}

Errores comunes que cometen los desarrolladores (y cómo evitarlos)

1. Usar JSON.stringify() o el cuerpo parseado

Muchos frameworks parsean JSON automáticamente. Esto rompe la verificación porque los espacios en blanco, el orden de las claves y el formato difieren.

Solución: Siempre captura el cuerpo crudo antes de parsear.

En Express: Usa body-parser con { verify: true }

En FastAPI: Usa await request.body()

2. Comparar cadenas con ===

Los ataques de temporización pueden filtrar información. Usa crypto.timingSafeEqual o hmac.compare_digest.

3. Almacenar secretos en el código

Usa variables de entorno o gestores de secretos (AWS Secrets Manager, HashiCorp Vault, etc.).

4. Olvidar manejar ataques de repetición

La mayoría de los proveedores incluyen una marca de tiempo. Verifica que el evento sea reciente (por ejemplo, dentro de 5 minutos).

const timestamp = req.headers['X-Signature-Timestamp'];
if (Date.now() - timestamp > 5 * 60 * 1000) {
  return res.status(401).send('Marca de tiempo demasiado antigua');
}

5. Usar SHA-1 (¡Todavía sucede!)

GitHub dejó de usar SHA-1 en 2022. Usa siempre SHA-256.

Probando la verificación de la firma de webhook con Apidog

Probar webhooks manualmente es tedioso. Envías una solicitud, revisas los registros, corriges, repites.

Apidog lo hace trivial:

En tu proyecto Apidog, haz clic en el icono + en la barra lateral izquierda y elige "New Other Protocol APls" (Nuevas API de otros protocolos) > "Webhook".

Captura de pantalla limpia 2025-11-05 a las 17.18.02@2x.png

Después de crear el Webhook, completa los siguientes campos en el editor:Request Method (Método de solicitud): Típicamente POST.Webhook name (Nombre del Webhook): Aparecerá en la documentación de la API y en la exportación de OpenAPI, por ejemplo, pedido.Debug URL (optional) (URL de depuración (opcional)): La URL real utilizada para enviar solicitudes de prueba. Nota: Esto es solo para fines de prueba y no se incluirá en la documentación.Other Info (Otra información): Como el cuerpo de la solicitud.

imagen.png

Haz clic en Guardar una vez que hayas completado todos los campos requeridos.
Simplemente introduce tu URL de Webhook en el campo Debug URL y luego haz clic en Send para simular una llamada de Webhook.

imagen.png

He ahorrado horas de depuración con el simulador de webhooks de Apidog. Incluso es compatible con el formato exacto stripe-signature de Stripe y el prefijo sha256=... de GitHub.

Ejemplo del mundo real: Verificación de webhooks de Stripe

Stripe utiliza un formato de encabezado especial:

stripe-signature: t=1681234567,v1=abc123...,v0=def456...

Debes:

Stripe proporciona bibliotecas oficiales para manejar esta complejidad:

const stripe = require('stripe')('sk_...');
stripe.webhooks.constructEvent(payload, sigHeader, endpointSecret);

Pero comprender el HMAC subyacente es crucial cuando necesitas implementarlo tú mismo.

Temas avanzados: Tolerando múltiples firmas

Algunos proveedores (como Stripe) envían múltiples firmas para compatibilidad con versiones anteriores. Tu código debería:

Mejores prácticas de seguridad en 2025

Conclusión: Pequeño paso de verificación, gran ganancia de seguridad

La verificación de la firma de webhook parece un pequeño detalle. Pero es la diferencia entre una aplicación segura y una que los atacantes pueden explotar trivialmente.

Implémentala correctamente, pruébala a fondo con herramientas como Apidog, y duerme mejor sabiendo que tus integraciones están protegidas.

Descarga Apidog gratis hoy mismo y verifica tu primer webhook en menos de 5 minutos. Es la forma más rápida de probar que tu código realmente funciona.

botón

Practica el diseño de API en Apidog

Descubre una forma más fácil de construir y usar APIs