Firmas de webhooks en lealtad: cómo validar origen, integridad y reintentos
Un webhook permite reaccionar con rapidez, pero también expone un endpoint que puede recibir eventos falsificados, repetidos o modificados. Cuando esos eventos alteran puntos, beneficios o perfiles, validar únicamente que el JSON «parece correcto» es insuficiente. La recepción segura exige verificar una firma sobre los bytes exactos, limitar la vigencia del mensaje, evitar replay, procesar de forma idempotente y separar la confirmación HTTP del trabajo de negocio. Esta guía se ocupa de autenticidad e integridad en cada entrega. KA-057 cubre la elección del patrón de integración, KA-090 la rotación de secretos y KA-082 el reprocesamiento de fallos; aquí la frontera es decidir si un evento recibido merece confianza.
Un endpoint público necesita una prueba de autenticidad
Un webhook existe para recibir llamadas desde otro sistema, por lo que su endpoint suele estar expuesto a Internet. TLS protege el transporte, pero no prueba por sí solo que el emisor sea el sistema esperado. Si el receptor procesa cualquier JSON bien formado, un tercero podría intentar simular compras, altas o redenciones. Una firma criptográfica permite verificar que el emisor conocía un secreto y que el cuerpo no cambió en tránsito.
La firma es un gate previo, no una validación de negocio completa. Un evento auténtico todavía puede contener un identificador inexistente, un monto fuera de rango o una operación duplicada. Por eso el pipeline debe separar autenticidad, sintaxis, esquema, reglas, idempotencia y aplicación transaccional. Cuando una etapa falla, se registra una razón específica y no se responde como si el evento hubiese sido procesado.
Cómo funciona HMAC en este contexto
HMAC combina una función hash con una clave secreta compartida para producir un código de autenticación. El emisor calcula la firma sobre una representación exacta del mensaje y la envía en un encabezado; el receptor calcula su propia firma con el mismo secreto y compara resultados. Si el cuerpo cambia aunque sea mínimamente, la comparación falla. La seguridad depende de la función elegida, la protección de la clave y la implementación correcta.
El detalle crítico es firmar bytes, no un objeto reconstruido. Parsear JSON y volver a serializar puede cambiar espacios, orden o caracteres, produciendo un falso rechazo. El receptor debe conservar el cuerpo bruto recibido para verificar y solo después parsearlo. También debe conocer el formato exacto del encabezado, el algoritmo y la codificación. Copiar un ejemplo de otro proveedor sin respetar su contrato es una causa común de integraciones frágiles.
Comparación segura y manejo de secretos
Comparar firmas con una operación ordinaria puede filtrar pequeñas diferencias de tiempo. Las bibliotecas suelen ofrecer comparaciones de tiempo constante y deben preferirse. El secreto no se hardcodea en repositorios, logs o documentos; se guarda en un gestor apropiado, con acceso limitado y rotación planificada. Ambientes de prueba y producción necesitan claves distintas para evitar que una credencial de menor control afecte eventos reales.
La rotación requiere una ventana de coexistencia: el receptor puede aceptar la clave actual y la siguiente durante un periodo corto, registrar cuál verificó y retirar la anterior después de confirmar tráfico. Esta operación se relaciona con KA-090, pero el foco aquí es que cada entrega declare y valide su versión de firma sin interrumpir el servicio. Nunca debe registrarse el secreto ni el valor completo de firmas sensibles en trazas accesibles.
Detener ataques de replay
Una firma válida demuestra integridad, pero un atacante que capture un mensaje podría reenviarlo. Para reducir replay, el contrato puede incluir un timestamp y un identificador único dentro de la cadena firmada. El receptor comprueba que el tiempo se encuentre dentro de una tolerancia razonable, que el identificador no haya sido procesado y que la firma cubra esos campos. Una ventana demasiado amplia aumenta exposición; una demasiado corta rechaza eventos legítimos por retrasos o relojes desalineados.
La idempotencia complementa esta defensa. Aunque el mismo evento llegue varias veces por reintentos legítimos, su efecto de negocio debe aplicarse una sola vez. Guardar la clave de idempotencia y el resultado permite responder de forma consistente. El historial de entregas debe distinguir repetición aceptada, replay sospechoso y reintento después de un fallo interno. Esa distinción es necesaria para no convertir mecanismos normales de resiliencia en alertas inútiles.
Orden correcto de procesamiento
El receptor debería limitar tamaño y método, conservar el cuerpo bruto, extraer encabezados, validar timestamp y algoritmo, calcular la firma, comparar de forma segura y solo entonces parsear. Después valida esquema, identifica evento y aplica reglas e idempotencia. Si el procesamiento de negocio es lento, puede confirmar recepción después de persistir de forma durable y procesar asincrónicamente. Responder éxito antes de conservar el evento abre pérdida silenciosa; esperar toda la operación puede causar reintentos innecesarios.
Cada respuesta comunica algo al emisor. Los códigos deben diferenciar solicitud inválida, autenticación fallida, limitación temporal y aceptación. Sin revelar detalles explotables, los logs internos conservan causa, entrega, proveedor, timestamp y correlación. La observabilidad debe permitir seguir un evento desde recepción hasta efecto en saldo o perfil, sin almacenar más datos personales que los necesarios.
Probar más que el camino feliz
Las pruebas deben modificar un byte, eliminar encabezados, usar firma incorrecta, repetir un evento, enviar timestamps viejos, alterar codificación y superar límites de tamaño. También deben simular rotación, retrasos y caída posterior a la persistencia. Un test que solo demuestra que una entrega válida funciona no comprueba la frontera de seguridad. Los vectores de prueba del proveedor ayudan a detectar diferencias de canonicalización antes de producción.
La operación necesita alertas basadas en proporción y contexto. Un fallo aislado durante despliegue puede ser configuración; una oleada desde orígenes distintos puede ser abuso. Los equipos deben saber quién posee el secreto, quién puede rotarlo, qué sistema conserva eventos y cómo se recupera una cola. Esto conecta seguridad con confiabilidad y evita que la validación quede como fragmento de código sin dueño.
Aplicación a eventos de lealtad
En lealtad, algunos webhooks solo notifican contenido; otros pueden disparar acumulaciones, cambios de nivel o redenciones. El impacto define la severidad. Un evento de compra debe reconciliarse con la transacción fuente y no otorgar valor si falta identidad o estado válido. Un evento de devolución debe referenciar la operación original. La firma protege el origen, pero no reemplaza esas invariantes.
Cuando Lealto se integra con POS, CRM, ERP u otros entornos, el contrato exacto debe documentar autenticación, esquema, idempotencia, reintentos y observabilidad para cada dirección del flujo. No se debe asumir que todos los webhooks usan el mismo algoritmo o que una capacidad general de integración implica una implementación específica. La evaluación técnica confirma el mecanismo real antes del lanzamiento.
Checklist de aceptación
Antes de aprobar, el equipo demuestra que la firma cubre el cuerpo bruto y los campos anti-replay, que las claves están separadas por ambiente, que existe rotación sin interrupción y que la comparación es segura. También comprueba límites, respuestas, logs, idempotencia y recuperación. El contrato debe indicar qué reloj se usa y qué tolerancia aplica.
La prueba final relaciona seguridad con efecto: una entrega falsificada no cambia datos; una válida repetida no duplica valor; una válida con regla inválida se rechaza o cuarentena con causa; y una aceptada puede rastrearse hasta su resultado. Solo esa cadena permite confiar en el webhook como parte de un programa que mueve beneficios y datos.
Preguntas frecuentes
¿HTTPS elimina la necesidad de firma? No. Protege el canal, pero el receptor todavía necesita verificar quién generó el mensaje y si el cuerpo corresponde al emisor esperado.
¿Se debe firmar el JSON ya parseado? Normalmente se verifica el cuerpo bruto exacto según el contrato del proveedor.
¿Firma e idempotencia son lo mismo? No. La firma valida autenticidad e integridad; la idempotencia evita aplicar el mismo efecto más de una vez.
Errores de implementación que parecen problemas de red
Muchos fallos de firma se diagnostican primero como intermitencia. Un proxy puede descomprimir o transformar el cuerpo, un framework puede consumir el stream antes de verificar, un parser puede normalizar Unicode y una función puede comparar hex con base64. El contrato debe fijar representación y el receptor registrar hashes de diagnóstico no sensibles, versión y longitud para ubicar la diferencia. Los relojes también necesitan sincronización y monitoreo.
Otro error es devolver una respuesta de éxito al capturar la solicitud sin asegurar persistencia. Si el proceso cae, el emisor cree que terminó y no reintenta. La frontera de aceptación debe ser explícita: firma válida, evento durably stored e identificador registrado. Después puede procesarse de forma asíncrona. Si una dependencia está caída antes de esa frontera, se devuelve un estado que permita reintento según contrato. Esta precisión convierte el webhook en un componente confiable, no en una llamada oportunista.
Pasar de un endpoint funcional a una recepción confiable
El contrato de webhook debe dejar explícitos el algoritmo, la construcción de la firma, el formato del timestamp, la ventana aceptada, la clave activa y la política de reintentos. Las pruebas de aceptación deben alterar un byte, repetir un evento, usar una firma vencida, rotar la clave y provocar fallos transitorios antes de tocar datos reales. Solo después se conecta el evento con acumulaciones, redenciones o cambios de perfil. Lealto y cada sistema integrado deben confirmar qué parte del flujo soportan y quién opera las excepciones. Una implementación confiable se reconoce porque puede rechazar lo inválido sin perder entregas legítimas ni duplicar efectos.
Fuentes
- RFC 2104 — HMAC
- GitHub Docs — Validating webhook deliveries
- OWASP — Secrets Management Cheat Sheet
- Lealto — integración con POS, CRM y ERP
Contáctenos
Construyamos su estrategia de lealtad
