Cómo crear un bucket seguro de Amazon S3 (AWS)
Josh Stella
8 de septiembre de 2020
0 minutos de lecturaNota del editor
Este blog se publicó originalmente en fugue.co. Fugue se unió a Snyk en 2022 y es un componente clave de Snyk IaC.
Mucho se ha dicho en la prensa y en publicaciones técnicas sobre la seguridad de Amazon S3 en Amazon Web Services (AWS), y gran parte de esa información es demasiado simplista y de poca utilidad práctica. Amazon S3 es un servicio en la nube increíblemente fácil de usar, pero proteger adecuadamente tus recursos de S3 no es nada sencillo, como han descubierto demasiadas organizaciones.
En esta publicación (y en nuestras dos sesiones de Cloud Security Masterclass dedicadas a Amazon S3), presento un enfoque práctico para comprender la seguridad de S3. Podrás analizar cómo proteger tus casos de uso específicos de S3 y crear un bucket seguro que se adapte a tus necesidades.
Si te guías únicamente por lo que lees en la prensa, podrías cometer el error de pensar que lo único que debes hacer para garantizar la seguridad de tu bucket de S3 es activar Block Public Access. Aunque es importante configurar correctamente esta opción (y AWS ha tomado las medidas necesarias para advertirte si no lo está), hacerlo puede generar una falsa sensación de seguridad si no haces nada más.
Las capas de seguridad de Amazon S3
Amazon S3 tiene varias capas de seguridad, y algunas son más importantes que otras.
Puntos de control de acceso (ACL)
Políticas de administración de identidades y accesos (IAM)
Políticas de bucket
Block Public Access
Puntos de acceso
Cifrado
De estas opciones, lo más importante es comprender las políticas de IAM, el cifrado y las políticas de bucket, al menos al principio. Pero antes de entrar en los detalles de esos tipos de políticas, es fundamental tener un modelo mental de las políticas y de cómo se relacionan con las acciones y los recursos de AWS. Omitiremos las ACL, ya que son un vestigio histórico que AWS recomienda no usar en la mayoría de los casos.
Políticas de IAM
En AWS hay entidades principales, acciones y recursos. Por supuesto, también hay otros tipos de entidades en AWS, pero estas son las que debes comprender para diseñar buckets de S3 seguros.
Las entidades principales son actores, tanto humanos como máquinas. Son las entidades que invocan acciones y acceden a recursos mediante credenciales.
Las acciones son los endpoints de API que usamos para realizar operaciones en la nube. Cada servicio de AWS tiene un conjunto de acciones, como ListBuckets o GetObject en S3.
Los recursos son instancias y objetos específicos de un servicio de AWS, como un bucket o un objeto de S3, o una instancia de EC2.
Para que una entidad principal realice una acción en un recurso (por ejemplo, para enumerar el contenido de un bucket de S3), debe haber políticas que otorguen los permisos necesarios en cada etapa. Cualquier denegación en cualquier etapa impedirá realizar la acción en el recurso. AWS tiene una política predeterminada para todas las acciones y recursos respecto de todas las entidades principales: Denegar.
Veámoslo con un ejemplo.

¿Ves la línea vertical entre las entidades principales y las acciones, y otra entre las acciones y los recursos? Llamémoslas nuestras «barreras de denegación». Al crear un bucket seguro de S3, nuestro trabajo consiste en abrir brechas en estas líneas solo para las acciones que necesita la entidad principal y únicamente en los recursos adecuados.
Para las entidades principales de AWS, como los usuarios y los recursos de AWS (por ejemplo, una instancia de EC2 asociada a un rol de IAM), podemos usar IAM para permitir el acceso a acciones y recursos. Este es un ejemplo de una política de IAM que permite un grupo de acciones en todos los buckets de S3 de la cuenta:
Observa que la política tiene secciones para las acciones y los recursos, igual que en nuestro diagrama. Fíjate en que abrimos una brecha en la barrera de denegación entre las entidades principales y las acciones para las tres operaciones Get definidas en la política, y que esto se aplica a todos los buckets de S3 incluidos en los recursos.

En este caso y en muchos otros, la sección de recursos es «*», lo que significa que incluye todos los recursos detrás de esa acción. A menudo es una buena idea, ya que podemos usar políticas de bucket y otros medios para limitar los recursos permitidos cuando se evalúan todas las políticas.
Al decidir dónde especificar detalles como los nombres de los recursos, es importante tener en cuenta que conviene evitar multiplicar las políticas de IAM, ya que llevar un registro de ellas se convierte en una fuente de costos y riesgos. Por eso, en general, no es recomendable incluir identificadores de recursos específicos en una política de IAM, pues esto daría lugar a numerosas copias de la política. A continuación, usaremos políticas de bucket de S3 para limitar el acceso a los recursos en la capa del bucket. Así, cuando se implemente para un usuario o proceso, esta política no permitirá el acceso a todos los buckets de S3.
Recomendamos usar las políticas administradas por AWS siempre que tenga sentido, ya que tu cuenta ya tiene más de 700 y AWS las mantiene por ti. Aunque no encuentres una que se ajuste exactamente a tus necesidades, vale la pena usarlas como ejemplo para crear políticas de IAM bien diseñadas.
Políticas de bucket
Ahora tenemos una política de IAM que permite varias acciones Get en todos los buckets de S3 de la cuenta, pero probablemente queramos limitarla a los buckets de S3 que necesita la aplicación en la que estamos trabajando. Hay varias formas de hacerlo, pero recomendamos agregar una política de bucket a todos tus buckets de S3 como última línea de defensa.
Las políticas de bucket son políticas de AWS que se aplican a cada bucket individual y son una excelente manera de denegar solicitudes que podrían estar permitidas por las políticas de IAM. En este ejemplo, queremos que el bucket «foo» solo acepte acciones iniciadas desde dos redes VPC específicas. Veamos una política tomada directamente del portal de soporte de AWS.
Aquí establecemos Deny para todas las entidades principales en todas las acciones de S3 al comienzo de la declaración. Luego, agregamos una condición que limita la denegación a los endpoints de VPC que no coinciden con dos identificadores VpcE ni con dos bloques CIDR. En otras palabras, solo se permitirá realizar acciones de S3 a las entidades principales que pasen por esos endpoints de VPC y estén dentro de esos bloques CIDR.
Al combinar estos elementos en el diagrama, aplicar esta política al bucket «foo» y usar políticas de bucket diferentes con distintos endpoints de VPC y bloques CIDR, obtenemos lo siguiente:

Aquí, el usuario azul se conecta mediante una VPC con el endpoint vpce-1111111, mientras que el usuario rojo lo hace a través del endpoint vpce-3333333. La política del bucket «foo» deniega el acceso al usuario rojo, aunque use la misma política de IAM que el usuario azul, porque se conecta desde un endpoint de VPC no permitido.
Puedes pensar en todas estas políticas como parte de una sola evaluación, en la que cualquier Deny implica que la solicitud se deniega. Por lo tanto, puedes decidir dónde incluir las declaraciones Allow y Deny según tu caso de uso y arquitectura.
Block Public Access
A menudo escuchamos que la gente cree que está protegida contra las filtraciones en S3 por activar la función Block Public Access en AWS. Es una función excelente. Debes usarla cuando corresponda, pero no bloquea el acceso de la forma que podrías pensar. No puedes asumir que estás a salvo solo porque la tienes activada.
En la documentación de AWS, se indica lo siguiente:
«Para que se considere no público, una política de bucket debe otorgar acceso únicamente a valores fijos (valores que no contengan un comodín) de uno o más de los siguientes elementos:
Un conjunto de bloques CIDR (Classless Inter-Domain Routing), mediante aws:SourceIp. …»
El documento contiene mucha más información (que deberías leer), pero esto por sí solo demuestra que, desde la perspectiva de esta función, una lista de bloques CIDR con acceso público no hace que algo se considere «público». Los bloques CIDR pueden representar grandes segmentos de Internet. Por eso, podrías tener un bucket «no público» expuesto a millones de direcciones IP y creer que estás a salvo. Siempre es recomendable usar la política de bucket más restrictiva posible para cada bucket de S3.
Una nota sobre el cifrado
Al cifrar un bucket de S3, es importante usar claves de KMS o claves administradas por el usuario, ya que esos métodos obligan a un atacante a acceder a servicios o datos adicionales para obtener información descifrada de tu bucket de S3. Si solo activas el cifrado del servidor en su forma más básica, únicamente obtendrás cifrado en reposo dentro del servicio de S3, y cualquier entidad principal con permisos GetObject recibirá los objetos descifrados.
Si las normativas exigen que todos los datos en reposo estén cifrados, esto te permitirá cumplir con ese requisito. Sin embargo, desde un punto de vista práctico, hacerlo tiene poco o ningún efecto en tu postura de seguridad.
Y hay mucho más...
En AWS hay más funciones y capas de seguridad de S3 de las que cubrimos en esta publicación; algunas las abordamos en nuestra serie Cloud Security Masterclass sobre la seguridad de S3. Si te quedas con una sola idea de esta publicación, esperamos que sea esta: para comprender la seguridad de S3, necesitas comprender realmente las políticas de AWS y no puedes confiar únicamente en ejemplos genéricos.
EDICIÓN: Olvidé mencionar que deberías activar el registro de acceso, el registro a nivel de objeto y el control de versiones para tus buckets de S3. El registro de acceso y el registro a nivel de objeto te permitirán ver qué ocurrió en tu bucket, y el control de versiones te permitirá volver a versiones anteriores de tus objetos si alguien obtiene acceso y modifica o elimina objetos necesarios.
Si hay temas más avanzados sobre la seguridad de S3 que te gustaría que abordáramos, ¡escríbenos y los analizaremos!
Seguridad de IaC diseñada para desarrolladores
Snyk protege tu infraestructura como código desde el ciclo de vida del desarrollo de software hasta el runtime en la nube con un motor unificado de políticas como código, para que todos los equipos puedan desarrollar, implementar y operar de forma segura.


