Skip to main content

Mejores prácticas de seguridad para webhooks

Escrito por
Headshot of Gints Dreimanis

Gints Dreimanis

feature webhook

6 de julio de 2022

0 minutos de lectura

Los webhooks son una de las mejores formas de transferir información sobre eventos ocasionales de un sistema a otro. A diferencia de métodos como el sondeo HTTP —que consiste en que el cliente solicita información al servidor repetidamente—, los webhooks se activan por eventos.

Esto los hace simples y eficaces. Un cliente puede suscribirse a un webhook para enviar un mensaje a un endpoint cada vez que ocurre un evento específico.

Sin embargo, como los webhooks suelen implicar el envío de mensajes a un endpoint público en internet, pueden surgir problemas de seguridad. Sin las medidas de seguridad adecuadas, un atacante puede leer y modificar mensajes, o incluso hacerse pasar por ti. Por eso, debemos tomar todas las medidas posibles para alcanzar el nivel de seguridad necesario al ejecutar un servicio de webhooks.

En este blog, repasaremos las prácticas más eficaces para proteger los webhooks y compartir datos entre aplicaciones sin crear una gran superficie de ataque.

8 prácticas recomendadas de seguridad para implementar webhooks

  1. Cifra los datos que se envían a través de webhooks

  2. Firma los webhooks

  3. Autentica las conexiones

  4. Agrega marcas de tiempo a los mensajes

  5. Usa la fijación de certificados

  6. No uses webhooks para datos confidenciales

  7. Registra todos los mensajes enviados mediante webhooks

  8. Usa un modelo de suscripción con fechas de vencimiento

Al implementar webhooks, es mejor no depender de una sola práctica de seguridad. En su lugar, debemos implementar varios enfoques para garantizar que el sistema siga protegido, incluso si un atacante supera algunas de nuestras medidas de seguridad.

Como mínimo, debemos usar cifrado para mantener la privacidad de los mensajes enviados a los clientes y recibidos de ellos, y autenticación mutua para que tanto el cliente como el servidor sepan con quién se están comunicando.

Cifra los datos que se envían a través de webhooks

Aunque no podemos evitar que actores maliciosos intercepten nuestros mensajes, sí podemos impedir que lean su contenido. Una forma sencilla de garantizar que todas las comunicaciones sean seguras es usar HTTPS en lugar de HTTP.

Usar HTTPS es muy fácil y hay muy pocas razones para no hacerlo. HTTPS cifra todos los datos, lo que dificulta mucho que un tercero acceda a ellos.

Firma los webhooks

Los actores maliciosos pueden interceptar los mensajes que se envían por internet y modificar su contenido para beneficiarse. Para evitar cambios no deseados, debemos firmar nuestros mensajes. Podemos hacerlo con un código de autenticación de mensajes basado en hash (HMAC), que consiste en un algoritmo de hash y un código o clave secreta que comparten ambas partes.

Los hashes HMAC asignan una función de hash específica a cada mensaje. Esto permite que quien recibe el webhook verifique su autenticidad e integridad comparando el mensaje con el hash.

Obtén más información sobre cómo firmar webhooks en este útil artículo de Twilio.

Autentica las conexiones

Los endpoints de webhooks suelen ser públicos y estar disponibles para cualquier persona en internet. Esta disponibilidad crea varias vulnerabilidades para quienes reciben webhooks, incluidos los ataques de denegación de servicio. Para resolver este problema, quienes reciben webhooks deben autenticar el origen de los mensajes. Pueden hacerlo con un nombre de usuario y una contraseña o con un token de autenticación.

Además, es buena idea autenticar a quien recibe el mensaje para garantizar que llegue al destino correcto.

Agrega marcas de tiempo a tus mensajes

Podemos etiquetar nuestros mensajes con la hora de envío para ayudar a prevenir ataques de repetición. Estos ataques no leen ni manipulan mensajes, pero pueden capturar un mensaje legítimo y cifrado y volver a enviarlo en un momento oportuno.

Al agregar marcas de tiempo a nuestros mensajes, permitimos que el cliente compruebe que el mensaje recibido es actual y no uno que enviamos hace un par de semanas. Como nuestros mensajes también están firmados, el atacante no puede cambiar la marca de tiempo ni guardar el mensaje para repetir el ataque.

Usa la fijación de certificados

Si nuestro cliente recibe una conexión de un servidor web con un certificado de confianza para nuestra API, eso no significa que el sitio web (ni el certificado) sea nuestro. Un posible atacante puede hacer una copia de nuestra API y agregarle un certificado de confianza. Luego, puede interceptar el mensaje legítimo y enviar el suyo en su lugar.

Una forma de resolver este problema es fijar el certificado. Si el evento proviene del mismo servidor cada vez, el cliente puede fijar su certificado en el código. Esto significa codificar de forma fija el certificado o su hash (huella digital) en la aplicación y compararlo con el certificado proporcionado cada vez que se establece una conexión.

Sin embargo, debemos tener cuidado al usar esta técnica porque depende de parámetros codificados de forma fija. Si el certificado cambia o se revoca, es posible que el cliente no pueda actualizarlo con suficiente rapidez.

Consulta un ejemplo de fijación de certificados en esta documentación de Mozilla.

No uses webhooks para datos confidenciales

Incluso con medidas de seguridad, los webhooks no son adecuados para datos confidenciales, como contraseñas o información de tarjetas de crédito. Por lo general, los webhooks sirven para enviar notificaciones sobre eventos. Si incluyes datos confidenciales en los mensajes que envían, deberías reconsiderar ese caso de uso.

Registra todos los mensajes enviados mediante webhooks

Podemos registrar los mensajes de los webhooks con una solución propia o de terceros. Los registros nos ayudan a documentar cada mensaje enviado, lo cual resulta útil durante las auditorías. Además, nos permiten ver todos los mensajes enviados y las conexiones iniciadas si ocurre un incidente de seguridad. Supervisar los registros también puede ayudarnos a detectar comportamientos sospechosos —como intentos de entrega fallidos— antes de que ocurra un incidente de seguridad.

Registrar los mensajes de los webhooks también es útil para mejorar la eficiencia. Por ejemplo, podemos cancelar la suscripción de los usuarios que no hayan recibido nuestros registros correctamente durante mucho tiempo, para mantener la lista precisa y actualizada. Mira este video de NearForm para obtener más información sobre el registro de mensajes de webhooks. Y si buscas una buena herramienta para registrar webhooks, consulta este logger para Node.js.

Usa un modelo de suscripción con fechas de vencimiento

Lo mejor es permitir que los usuarios indiquen una fecha de vencimiento para su suscripción. Aunque esta fecha no tenga un gran impacto por sí sola, usarla junto con otras prácticas de seguridad agrega una capa de protección.

Al combinar distintos métodos de cifrado, autenticación y autorización, limitar el tiempo durante el cual un servidor o cliente dispone de privilegios ayuda a establecer una defensa en profundidad. Además, las fechas de vencimiento reducen el tiempo que tiene un actor malicioso para encontrar un punto débil en nuestra seguridad (como credenciales robadas), ya que el cliente debe volver a completar el proceso de suscripción cuando esta vence.

Cómo establecer la seguridad de los webhooks

Cifrar los mensajes de los webhooks es la base para ofrecer a los clientes una forma de validar los mensajes. Otras prácticas de seguridad se apoyan en este principio y, al combinarse, brindan una protección más completa.

Recuerda que el objetivo de los webhooks suele ser informar a los clientes sobre eventos que ocurren en tu sistema. La mayoría de estos eventos, como las nuevas solicitudes de pull request en GitHub o los nuevos seguidores de suscriptores, deberían ser inofensivos, por lo que a los atacantes no les interesará demasiado manipular estas comunicaciones. Se recomienda encarecidamente evitar el envío de datos muy confidenciales mediante webhooks.

Un enfoque integral de seguridad comienza por elegir medidas adecuadas para el dominio de tu aplicación y la naturaleza de la información que envías. Por ejemplo, las actualizaciones sobre próximos eventos requieren menos medidas de seguridad que los mensajes con información detallada de clientes individuales. Al adaptar tu enfoque y establecer varias capas de seguridad superpuestas, puedes tener mayor confianza en que tu código y los datos de tus clientes están protegidos frente a los distintos tipos de vulnerabilidades que vemos hoy.