La seguridad de buckets S3 concentra una parte desproporcionada de las brechas de datos en la nube. Amazon S3 es el servicio de almacenamiento de objetos más utilizado de AWS y, precisamente por su ubicuidad, un solo bucket mal configurado puede exponer millones de registros sin que intervenga ningún exploit sofisticado. Este artículo va más allá del catálogo general de fallos cloud y se centra en lo que hace único a S3: su modelo de control de acceso en tres planos, el cifrado, el secuestro de buckets (bucket takeover), la exfiltración de datos y un checklist de hardening específico para AWS.
Si buscas una panorámica más amplia de configuraciones inseguras en la nube, la tenemos en el artículo sobre los errores de configuración cloud más peligrosos en AWS y Azure. Aquí bajamos al detalle de un único servicio.
Por qué los buckets S3 siguen siendo un objetivo prioritario
La exposición de buckets no es teórica. El caso de Capital One en 2019 (más de 100 millones de registros de clientes) es el más mediático, pero la lista es larga: Booz Allen Hamilton filtró datos del ejército estadounidense por un bucket público, Deep Root Analytics expuso información de casi 200 millones de votantes en 2017, y FedEx dejó accesibles pasaportes escaneados. El patrón se repite porque S3 almacena datos de altísimo valor, es trivial de aprovisionar y su modelo de permisos es más sutil de lo que parece.
A esa superficie se suma que el espacio de nombres de S3 es global: el nombre de un bucket es único en toda la partición de AWS, lo que permite a un atacante enumerar nombres previsibles (empresa-backups, empresa-logs, empresa-prod) sin acceso previo a la cuenta.
Los tres planos de control de acceso
El error conceptual más común es tratar el acceso a S3 como si fuera un único interruptor. En realidad conviven tres mecanismos que se evalúan de forma combinada, y entender su interacción es la base del hardening.
ACL: el modelo heredado que conviene desactivar
Las Access Control Lists (ACL) son el mecanismo original de S3, anterior a IAM. Permiten conceder permisos a nivel de bucket u objeto a grupos predefinidos, incluido el peligroso AllUsers (cualquiera en Internet) y AuthenticatedUsers (cualquier titular de una cuenta AWS, no solo la tuya). Este último es especialmente traicionero: mucha gente asume que "usuarios autenticados" significa su organización, cuando en realidad abarca a todo el mundo con una cuenta de AWS.
Desde abril de 2023, AWS deshabilita las ACL por defecto en los buckets nuevos mediante la opción Object Ownership: Bucket owner enforced. Esta es la configuración recomendada: desactiva por completo las ACL y obliga a gestionar todo el acceso mediante políticas basadas en IAM y en el recurso. Si tienes buckets antiguos, verifica su Object Ownership:
aws s3api get-bucket-ownership-controls --bucket mi-bucket
aws s3api get-bucket-acl --bucket mi-bucket
Bucket policy: la política basada en recursos
La bucket policy es una política JSON asociada al propio bucket. A diferencia de una política IAM (que se adjunta a una identidad), esta se evalúa desde el lado del recurso y es la herramienta correcta para controlar el acceso a S3 con granularidad. El fallo clásico es un Principal comodín combinado con acciones de lectura:
{
"Effect": "Allow",
"Principal": "*",
"Action": ["s3:GetObject", "s3:ListBucket"],
"Resource": ["arn:aws:s3:::mi-bucket", "arn:aws:s3:::mi-bucket/*"]
}
Esa política hace público el bucket entero. La bucket policy bien diseñada, en cambio, refuerza controles: denegar peticiones sin TLS con aws:SecureTransport, exigir cifrado en la subida con s3:x-amz-server-side-encryption, restringir el acceso a un VPC endpoint concreto con aws:SourceVpce, o acotar el acceso entre cuentas a tu organización con aws:PrincipalOrgID. En acceso entre cuentas y desde servicios de AWS, añade siempre aws:SourceAccount y aws:SourceArn para prevenir el confused deputy.
Block Public Access: la red de seguridad
S3 Block Public Access (BPA) es la capa que anula cualquier configuración que exponga el bucket, independientemente de lo que digan las ACL o la bucket policy. Consta de cuatro ajustes:
BlockPublicAcls: rechaza nuevas ACL públicas.IgnorePublicAcls: ignora las ACL públicas ya existentes.BlockPublicPolicy: rechaza bucket policies que concedan acceso público.RestrictPublicBuckets: limita el acceso de cualquier política pública ya aplicada solo a principales de la cuenta y servicios de AWS.
Desde abril de 2023 BPA está activado por defecto a nivel de bucket en los buckets nuevos, pero la recomendación firme es habilitarlo también a nivel de cuenta, de forma que ningún bucket pueda ser público por accidente. Verifícalo así:
aws s3api get-public-access-block --bucket mi-bucket
aws s3control get-public-access-block --account-id 111122223333
Enumeración y exfiltración desde la óptica del atacante
Un pentester empieza por descubrir buckets. Herramientas como S3Scanner, cloud_enum o el índice público GrayhatWarfare permiten localizar buckets abiertos a partir de nombres de dominio y palabras clave. Con un nombre candidato, la comprobación es directa y no requiere credenciales:
aws s3 ls s3://empresa-backups --no-sign-request
aws s3 cp s3://empresa-backups/dump.sql . --no-sign-request
Si el bucket permite s3:ListBucket de forma anónima, el atacante lista objetos; si permite s3:GetObject, los descarga. La exfiltración masiva rara vez necesita más que eso. Herramientas como s3-account-search llegan a inferir el ID de la cuenta AWS propietaria de un bucket, información útil para el pivote posterior. En un ejercicio ofensivo completo, estos hallazgos se encadenan con otras debilidades, tal como describimos en la guía de pentesting cloud sobre AWS, Azure y GCP.
Del lado defensivo, dos servicios nativos aportan visibilidad: IAM Access Analyzer for S3 marca los buckets con acceso público o entre cuentas, y Amazon Macie descubre datos sensibles (PII, credenciales, tarjetas) dentro de los objetos. Ambos deberían formar parte del baseline.
Bucket takeover: el secuestro por nombre
El bucket takeover es una variante de subdomain takeover específica de S3. Ocurre cuando un registro DNS (habitualmente un CNAME) apunta a un endpoint de S3, por ejemplo assets.tudominio.com hacia assets-tudominio.s3-website-eu-west-1.amazonaws.com, y el bucket subyacente se elimina sin retirar el registro DNS. Como el espacio de nombres de S3 es global, cualquier atacante puede reclamar ese mismo nombre de bucket y servir contenido malicioso bajo tu subdominio: phishing con tu marca, robo de cookies o distribución de malware con la confianza de tu dominio.
La señal reveladora es un error NoSuchBucket al resolver el subdominio. La defensa es de higiene: al desmantelar infraestructura, elimina primero el registro DNS y solo después el bucket, y audita periódicamente tus zonas DNS en busca de CNAME colgantes que apunten a endpoints de S3 sin bucket vivo detrás.
Cifrado en reposo y en tránsito
Desde enero de 2023, S3 cifra por defecto todos los objetos nuevos con SSE-S3 (AES-256). Esto elimina el escenario de bucket sin cifrar. Para datos regulados conviene usar SSE-KMS con una clave gestionada por el cliente (CMK), que añade una capa de autorización adicional: aunque un atacante consiga s3:GetObject, necesita además permiso kms:Decrypt sobre la clave. Activa S3 Bucket Keys para reducir drásticamente el coste de las llamadas a KMS en buckets de alto tráfico.
El cifrado en tránsito se impone denegando en la bucket policy cualquier petición donde aws:SecureTransport sea false, lo que fuerza HTTPS en todas las operaciones.
Resiliencia frente a ransomware
Un atacante con permisos de escritura no solo lee datos: puede cifrarlos o borrarlos para pedir rescate. Tres controles reducen ese riesgo. El versionado conserva copias anteriores de cada objeto sobrescrito o eliminado. MFA Delete exige un segundo factor para borrar versiones. Y S3 Object Lock en modo compliance impone un almacenamiento WORM (write once, read many) que impide eliminar objetos incluso a la cuenta root durante el periodo de retención, la base ideal para copias inmutables.
Checklist de hardening para S3
- Activa Block Public Access a nivel de cuenta, no solo por bucket.
- Fija Object Ownership en Bucket owner enforced para desactivar las ACL.
- Revisa toda bucket policy en busca de
Principal: "*"y deAuthenticatedUsers. - Deniega peticiones sin TLS con la condición
aws:SecureTransport. - Restringe el acceso con
aws:PrincipalOrgID,aws:SourceVpceoaws:SourceIpcuando aplique. - Usa SSE-KMS con CMK para datos regulados y activa Bucket Keys.
- Habilita versionado, MFA Delete y Object Lock en buckets críticos.
- Activa server access logging y los data events de CloudTrail para S3.
- Ejecuta IAM Access Analyzer for S3 y Macie de forma continua.
- Evalúa el conjunto contra el CIS AWS Foundations Benchmark (sección S3) y las AWS Foundational Security Best Practices.
Estos controles no son estáticos: la deriva de configuración es constante en cuentas activas. Medirla de forma continua es precisamente el papel de un CSPM, como explicamos en qué es CSPM y la gestión de postura de seguridad cloud. Y dado que un bucket rara vez cae solo, conviene entender cómo se combina su compromiso con la escalada de privilegios en AWS IAM dentro de una cadena de ataque real.
Preguntas frecuentes
¿Es suficiente con activar Block Public Access para proteger un bucket S3?
Block Public Access evita la exposición pública, pero no cubre el acceso entre cuentas mal configurado, la exfiltración por una identidad interna sobre-privilegiada ni la falta de cifrado con clave gestionada. Es imprescindible, pero no una defensa completa: el hardening real lo combina con Object Ownership, bucket policies restrictivas, SSE-KMS y auditoría.
¿Qué diferencia hay entre ACL y bucket policy en S3?
Las ACL son el mecanismo heredado, previo a IAM, y conceden permisos a grupos predefinidos con muy poca granularidad. La bucket policy es una política JSON basada en el recurso que permite condiciones finas (TLS obligatorio, restricción por VPC, organización o IP). AWS recomienda desactivar las ACL con Object Ownership en Bucket owner enforced.
¿En qué consiste un ataque de bucket takeover?
Es una forma de subdomain takeover. Cuando un registro DNS apunta a un endpoint de S3 y el bucket se elimina sin retirar el registro, un atacante puede reclamar ese nombre (el espacio de nombres es global) y servir contenido malicioso bajo tu subdominio. Se previene eliminando siempre el registro DNS antes que el bucket y auditando los CNAME colgantes que devuelvan NoSuchBucket.
¿Los buckets S3 se cifran automáticamente?
Sí. Desde enero de 2023, S3 aplica cifrado SSE-S3 (AES-256) por defecto a todos los objetos nuevos. Aun así, para datos regulados conviene SSE-KMS con una clave gestionada por el cliente: leer el objeto requiere también kms:Decrypt sobre la clave, lo que limita la exfiltración aunque se conceda s3:GetObject.
¿Cómo se detecta la exfiltración de datos desde un bucket?
Habilitando los data events de CloudTrail para S3 y el server access logging, y correlacionando patrones anómalos: volúmenes de GetObject inusuales, accesos desde IPs o regiones atípicas o llamadas ListBucket masivas. Amazon GuardDuty con S3 Protection genera hallazgos sobre estos comportamientos.
Conclusión
La seguridad de buckets S3 se juega en detalles que parecen menores: un AuthenticatedUsers mal entendido, un CNAME que se quedó colgando, una bucket policy con Principal comodín. Ninguno requiere un exploit, y todos son prevenibles con disciplina de configuración. La receta es conocida: Block Public Access a nivel de cuenta, ACL desactivadas, bucket policies con condiciones estrictas, cifrado con clave gestionada, resiliencia frente a ransomware y auditoría continua. Si gestionas datos sensibles en S3 y no has validado tu exposición con un ejercicio ofensivo, en Secra lo comprobamos con nuestro servicio de auditoría cloud.
Sobre el autor
Equipo de Secra Solutions
Ethical hackers certificados OSCP, OSEP, OSWE, CRTO, CRTL y CARTE, con más de 7 años de experiencia en ciberseguridad ofensiva. Autores de los CVE-2025-40652 y CVE-2023-3512.

