https://d226lax1qjow5r.cloudfront.net/blog/blogposts/using-message-signatures-to-ensure-secure-incoming-webhooks-dr/Secure-Webhooks.png

Uso de firmas de mensajes para garantizar la seguridad de los webhooks entrantes

Publicado el April 26, 2021

Tiempo de lectura: 4 minutos

Las conversaciones unidireccionales no son divertidas. En Vonage, lo nuestro son las conversaciones bidireccionales y eso incluye nuestras API. Por ejemplo, para enviar un SMS llamas a nuestra API. Para recibir una respuesta de SMS, tu aplicación deberá manejar un webhook entrante. Los webhooks son geniales para usar HTTP para notificar eventos, pero requieren que tu aplicación esté disponible en una URL pública. ¿El inconveniente? Tu URL pública es, bueno, pública. Cualquiera o cualquier cosa podría enviarle datos, ¿y cómo estarás seguro de que los mensajes provienen de Vonage?

Nota: El uso de firmas de mensajes para verificar los webhooks entrantes actualmente sólo está disponible en la SMS API de Vonage.

Este es un problema común con los webhooks en todo tipo de aplicaciones. En Vonage te recomendamos habilitar firma de mensajes en tu Account para garantizar la seguridad de los webhooks entrantes. Este artículo explicará cómo funcionan las firmas de mensajes y cómo configurar esto para tus propias aplicaciones. El mismo enfoque se utiliza en algunos lugares, pero el ejemplo de hoy lo muestra en el contexto de la recepción de un SMS, tenemos algunos ejemplos de código para recibir un SMS por si te interesa verlos antes de entrar en materia.

Activar la firma de mensajes

Las nuevas cuentas de Vonage no tienen la firma de mensajes habilitada de manera predeterminada, por lo que lo primero que debes hacer es enviar un email a support@nexmo.com solicitando que se habiliten las firmas de mensajes en tu Account. Hay una segunda opción para requerir que todos los mensajes que envíes también tengan una firma con ellos; no cubriremos ese uso hoy pero vale la pena saber que está allí.

Consigue tu firma secreta

Una vez que haya activado la firma, deberá visitar la página de página de configuración de tu panel de control. Aquí puedes establecer qué algoritmo de firma utilizar (en estos ejemplos estoy utilizando la opción SHA-256 HMAC en estos ejemplos), y puedes acceder a tu secreto de firma. Copia este secreto de firma, es el "secreto compartido" que usaremos para calcular las firmas tanto en el servidor como en el cliente.

Un "secreto compartido" es una clave que se comparte de antemano entre dos partes, en este caso entre los servidores de Vonage y tú. Este secreto compartido nunca se transmite, pero es utilizado tanto por Vonage como por tu aplicación para garantizar que los datos provienen del servidor esperado y no han sido modificados de ninguna manera.

También en esta página de configuración está la opción de cambiar el verbo HTTP para sus webhooks a POST. Por defecto es GET y en los ejemplos se utiliza GET pero si quieres cambiarlo (yo prefiero POST personalmente), esa configuración está aquí en "Configuración predeterminada de SMS" -> "Método HTTP".

Vonage prepara una firma

Cuando llega un SMS a tu número de Vonage, Vonage enviará un webhook a la URL configurada para ese número que contiene toda la información sobre el mensaje que llega. Con las firmas de mensajes habilitadas, también calcula una firma para enviar junto con el mensaje.

Puede leer los pasos detallados para crear una firma pero la versión corta es:

  • Obtener campos de formulario en orden alfabético, concatenarlos en una cadena larga de claves y valores

  • Añade el secreto de firma al final

  • Haz hash de la cadena que has creado según el algoritmo elegido, por ejemplo SHA-256 HMAC. ¡Listo! Esta es la firma

Un hash es una representación textual de una cadena (normalmente más larga). A partir del hash no es posible aplicar ingeniería inversa a la cadena original. Podemos transmitir con seguridad este hash (en este caso, es la firma del mensaje) sin riesgo de revelar la cadena a partir de la que se creó.

Vonage envía los datos y una firma

Una vez creada la firma, el webhook que contiene los datos del mensaje y la firma, pero NO el secreto, se envía a la URL configurada para este número. Es algo parecido a esto:

msisdn: 44784xxxxxxx
to: 44741xxxxxxx
messageId: 16000002632BEC99
text: Next step
type: text
keyword: NEXT
message-timestamp: 2019-01-23 10:51:39
timestamp: 1548240699
nonce: 9a706fdd-2b68-4761-87ab-c6ea80cab452
sig: 062470CA9A00C81FBF32FACE34B73D819BCDED07B36203DF7C0714E1094D86DE

Recibimos estos datos en nuestra aplicación, y podemos usarlos y el secreto de firma que copiamos antes para recrear la firma y cotejarla con lo que nos llegó.

Calcular la firma prevista

A partir de los datos que se enviaron, más el secreto de la firma, podemos seguir los mismos pasos para crear una firma y asegurarnos de que obtenemos algo que coincide exactamente. El proceso manual se ha descrito y enlazado anteriormente, pero nuestros SDK de servidor para la pila tecnológica que elijas crearán la firma por ti.

Por ejemplo aquí está la biblioteca PHP en acción:

    $signature = new \Nexmo\Client\Signature(
        $_GET,
        NEXMO_API_SIGNATURE_SECRET,
        'sha256'
    );
    $isValid = $signature->check($_GET['sig']);

El valor de $isValid indicará si las firmas coinciden o no.

Atacar su propio código

Puedes probar un poco de hacking ligero capturando peticiones a tu plataforma de desarrollo local usando Ngrokcaptura los datos e intenta enviar webhooks a tu aplicación utilizando un cliente HTTP como Postman. Si cambias cualquier campo - el mensaje, el número de teléfono, la marca de tiempo - la coincidencia de la firma falla.

Garantizar la seguridad de los webhooks entrantes

En las aplicaciones web tradicionales tenemos información de sesión/cookie, tokens CSRF y otras medidas para protegernos contra datos entrantes maliciosos. Los webhooks no tienen el mismo contexto y, por lo tanto, un enfoque como un secreto compartido con una firma de mensaje puede proteger contra ataques de sincronización y datos entrantes que hayan sido manipulados o se originen en algún lugar que no sean los servidores de Vonage. En mi experiencia, la mayoría de los datos "maliciosos" en realidad son simplemente alguien que puso la URL incorrecta en algún lugar o algo igualmente inocuo. Ya sea un ataque o no, esto aún resulta en datos que tu aplicación no debería estar procesando.

Tómate el tiempo de habilitar las firmas en tu Account de Vonage y agregar el código de verificación, las aplicaciones seguras son aplicaciones felices :)

Compartir:

https://a.storyblok.com/f/270183/250x250/e3d3b71060/lornajane.png
Lorna MitchellAntiguos alumnos de Vonage

Lorna es ingeniera de software con un incurable hábito bloguero. Intenta domar las palabras y el código a partes iguales.