S3, protección de datos
Block Public Access, bucket policies con condiciones, Object Lock (WORM), VPC endpoint policies y cifrado por defecto con KMS, aplicados a los buckets de Citas.
Las filtraciones de datos en la nube que llegan a la prensa casi nunca son “hackeos” sofisticados: son buckets de S3 mal configurados. En Citas, el bucket citas-adjuntos guarda documentos que los pacientes suben a sus citas —PII pura— y la cuenta log-archive guarda el rastro de auditoría de toda la organización. Proteger esos datos no es una sola palanca, sino varias capas que se refuerzan: bloquear lo público, escribir políticas con condiciones, cifrar por defecto y, para los datos que no deben cambiar nunca, hacerlos inmutables.
Block Public Access: la red de seguridad#
S3 Block Public AccessS3 Block Public AccessConjunto de cuatro ajustes de S3 que anulan ACLs y bucket policies que concedan acceso público, aplicables a cuenta, bucket, access point y organización. (BPA) se superpone a las ACLs y a las bucket policies: aunque alguien escriba una política pública, BPA la ignora o la rechaza. Son cuatro ajustes independientes:
| Ajuste | Qué hace |
|---|---|
BlockPublicAcls |
Rechaza operaciones que intenten poner una ACL pública |
IgnorePublicAcls |
Ignora cualquier ACL pública ya existente |
BlockPublicPolicy |
Rechaza PutBucketPolicy si la política concede acceso público |
RestrictPublicBuckets |
Si el bucket tiene política pública, bloquea todo acceso público y entre cuentas (salvo service principals) |
Se aplican a varios niveles —cuenta, bucket, access point y organización— y S3 hace cumplir la combinación más restrictiva de todos ellos. Esto importa: si lo activas a nivel de cuenta, ningún bucket nuevo podrá volverse público por error, aunque alguien le ponga una política pública. Desde abril de 2023 los buckets nuevos nacen con los cuatro activados, pero no lo des por hecho en cuentas antiguas.
aws s3control put-public-access-block --account-id 111122223333 \ --public-access-block-configuration \ BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=truePaso 1 de 5El bucket
citas-adjuntos guarda los adjuntos de las citas: PII cifrada con KMS. Dos peticiones quieren leer un objeto.
Bucket policies con condiciones#
Una vez bloqueado lo público, la bucket policy define el acceso legítimo con condiciones que restringen cómo se llega al dato. Tres son casi obligatorias para datos sensibles:
aws:SecureTransport— exige TLS. Deniega cualquier petición en claro (HTTP).aws:PrincipalOrgID— restringe el acceso a principals de tu organización AWS, sin tener que enumerar cuentas.aws:SourceVpce— exige que la petición entre por tu VPC endpoint de S3, no por la Internet pública.
Vulnerable
Seguro
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": "*", "Action": "s3:GetObject", "Resource": "arn:aws:s3:::citas-adjuntos/*" } ]}{ "Version": "2012-10-17", "Statement": [ { "Sid": "SoloOrgTlsYVpce", "Effect": "Deny", "Principal": "*", "Action": "s3:*", "Resource": ["arn:aws:s3:::citas-adjuntos", "arn:aws:s3:::citas-adjuntos/*"], "Condition": { "Bool": { "aws:SecureTransport": "false" }, "StringNotEquals": { "aws:PrincipalOrgID": "o-abc123", "aws:SourceVpce": "vpce-0a1b2c3d" } } } ]}La versión débil concede lectura a cualquiera en Internet: es exactamente la configuración que acaba en los titulares. La endurecida invierte la lógica con un Deny explícito: niega todo lo que no venga por TLS, de tu organización y de tu VPC endpoint. Un Deny así es más robusto que un Allow, porque un Deny siempre gana sobre cualquier Allow, aquí o en una política IAM. Esta es la política que protege citas-adjuntos.
VPC endpoint policies#
La condición aws:SourceVpce asegura que el dato se pide desde tu VPC. La otra mitad la pone la VPC endpoint policy: una política en el propio endpoint que limita a qué buckets puede hablar ese endpoint. Así cierras el círculo en los dos sentidos: las tareas de Citas solo alcanzan S3 por el endpoint, y el endpoint solo deja pasar peticiones a tus buckets.
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": "*", "Action": ["s3:GetObject", "s3:PutObject"], "Resource": ["arn:aws:s3:::citas-adjuntos/*", "arn:aws:s3:::citas-thumbnails/*"] } ]}Esto frena un camino de exfiltración habitual: una tarea comprometida que intenta subir datos a un bucket del atacante. Con esta política, el endpoint deniega la petición porque el destino no está en la lista.
Cifrado por defecto con KMS#
Todo bucket aplica cifrado por defecto; la decisión es qué llave. Para datos sensibles, usa SSE-KMS con una KMS keyAWS KMSServicio gestionado de AWS que crea y controla claves de cifrado; las claves nunca salen en claro y cada una lleva su propia key policy. propia en lugar de la gestionada por S3, porque así el acceso al dato depende también de la key policy (ver KMS a fondo): aunque alguien supere la bucket policy, sin permiso sobre la llave el objeto es ilegible.
resource "aws_s3_bucket_server_side_encryption_configuration" "adjuntos" { bucket = aws_s3_bucket.citas_adjuntos.id rule { apply_server_side_encryption_by_default { sse_algorithm = "aws:kms" kms_master_key_id = aws_kms_key.citas_adjuntos.arn } bucket_key_enabled = true # reduce llamadas a KMS y coste }}Puedes reforzarlo con una condición en la bucket policy que deniegue cualquier PutObject que no venga cifrado con tu llave (s3:x-amz-server-side-encryption-aws-kms-key-id), para que nadie suba un objeto con otro cifrado.
Object Lock (WORM) para logs y backups#
Hay datos que, una vez escritos, no deben cambiar nunca: los logs de CloudTrail en la cuenta log-archive, los backups. Para eso está S3 Object LockS3 Object LockFunción de S3 que aplica un modelo WORM (write-once-read-many) para impedir borrar o sobrescribir versiones de objetos durante un periodo o indefinidamente., que aplica un modelo WORM (write-once-read-many). Requiere versionado y ofrece dos modos de retención:
Nadie —ni el usuario root de la cuenta— puede borrar ni acortar la retención hasta que expire. El único modo de eliminar el objeto antes es cerrar la cuenta. Es el modo para el rastro de auditoría: garantiza que un atacante que comprometa la cuenta no pueda borrar las pruebas de lo que hizo.
Protege frente a la mayoría de usuarios, pero un principal con el permiso s3:BypassGovernanceRetention puede saltarse el bloqueo. Útil para backups donde quieres inmutabilidad por defecto pero con una válvula de escape controlada. Sirve también para probar una retención antes de pasarla a compliance.
A esto se añade el legal hold: una retención sin fecha de expiración, que dura hasta que alguien con permiso la retira. Es independiente del periodo de retención.
Tu turno
Cierra un bucket con datos sensibles
Elige un bucket con datos que importen en tu trabajo o tu lab.
- Comprueba BPA a nivel de cuenta y de bucket (
aws s3api get-public-access-block). ¿Están los cuatro ajustes activos? - Revisa la bucket policy: ¿tiene un
Denyparaaws:SecureTransport = false? ¿Restringe poraws:PrincipalOrgID? - ¿Usa cifrado por defecto con una KMS key propia o con la de S3?
- Si el bucket guardara logs o backups, ¿tendría sentido Object Lock en compliance? ¿Qué retención?
- Aplica una mejora hoy: activa BPA a nivel de cuenta o añade el
Denyde transporte inseguro.
Reto
Tienes BPA activado a nivel de cuenta. ¿Puedes olvidarte de las bucket policies?
▸Mostrar solución
No. BPA solo bloquea el acceso público. No impide que un rol de tu organización con permisos excesivos lea datos que no debería, ni que la petición viaje sin TLS, ni que una tarea comprometida exfiltre a un bucket ajeno. BPA es el suelo; las condiciones de la bucket policy y de la VPC endpoint policy son las que definen el acceso legítimo.
Reto
¿Object Lock en modo compliance protege contra el borrado por el usuario root?
▸Mostrar solución
Sí. En compliance, ningún principal —incluido el root de la cuenta— puede borrar ni acortar la
retención de una versión protegida antes de que expire. Por eso es la base de un rastro de
auditoría a prueba de manipulación. En governance, en cambio, quien tenga
s3:BypassGovernanceRetention sí puede saltárselo.
En resumen#
- Block Public Access a nivel de cuenta es la red de seguridad que impide que un error puntual vuelva público un bucket; son cuatro ajustes y S3 aplica la combinación más restrictiva.
- Las bucket policies con condiciones (
aws:SecureTransport,aws:PrincipalOrgID,aws:SourceVpce) y unDenyexplícito definen el acceso legítimo. - Las VPC endpoint policies limitan a qué buckets habla tu VPC y cortan un camino de exfiltración.
- Cifra por defecto con una KMS key propia: el acceso al dato depende también de la key policy.
- Object Lock (WORM) hace inmutables logs y backups; compliance resiste incluso al root.