Saltar al contenido
Open Security
Cloud y Producción Intermedio · 30 min

S3: el bucket que quedó público sin querer

La fuga de datos más común en la nube no es un hackeo: es un bucket mal configurado. Acá ves las cuatro capas que deciden si un objeto es público y cómo verificarlo antes de que lo haga un escáner ajeno.

#cloud#aws#s3

Antes de empezar necesitás

  • Idea básica de qué es S3 y un bucket
  • Haber leído una policy de IAM (lab: IAM, Deny gana)

Al terminar vas a poder

  • Entender las capas que deciden el acceso: Block Public Access, policy, ACL y permisos de IAM
  • Leer una bucket policy y detectar el Principal '*'
  • Verificar si un bucket es público sin adivinar
  • Aplicar el default seguro: Block Public Access activado

La filtración de datos más repetida de la última década no fue un exploit ingenioso: fue un bucket de S3 que quedó público. Nadie “entró”; estaba abierto y un escáner lo encontró. La buena noticia es que decidir si un objeto es público depende de capas concretas que podés leer y cerrar.

Las capas, de afuera hacia adentro

1. Block Public Access   interruptor maestro. Si está ON, gana: nada es público.
2. Bucket policy          JSON a nivel bucket. Un Principal "*" lo abre al mundo.
3. ACL del objeto         permisos viejos por objeto (AllUsers = público).
4. IAM del que pide       qué puede hacer esa identidad concreta.

La policy que abre el bucket

Esta es la que aparece en buckets filtrados. Leela despacio, fijate en el Principal:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "PublicRead",
      "Effect": "Allow",
      "Principal": "*",
      "Action": "s3:GetObject",
      "Resource": "arn:aws:s3:::reportes-prod/*"
    }
  ]
}

Verificar, no suponer

Antes de creer que está cerrado, confirmalo:

vt@labs:~
# ¿El Block Public Access está activado? Querés ver los cuatro flags en true.
aws s3api get-public-access-block --bucket reportes-prod

# ¿Hay una bucket policy? ¿tiene Principal "*"?
aws s3api get-bucket-policy --bucket reportes-prod \
  --query Policy --output text | jq '.Statement[] | {Effect, Principal, Action}'

Un BPA sano se ve así:

{
  "BlockPublicAcls": true,
  "IgnorePublicAcls": true,
  "BlockPublicPolicy": true,
  "RestrictPublicBuckets": true
}

El fix: cerrar y dejar el cinturón puesto

Primero sacá el Principal "*" de la policy (si el bucket sirve un sitio, eso se hace con CloudFront + OAC, no abriendo S3). Después prendé BPA para que ninguna policy futura lo vuelva a abrir:

vt@labs:~
aws s3api put-public-access-block --bucket reportes-prod \
  --public-access-block-configuration \
  BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true

La policy privada típica no nombra Principal "*" en absoluto: el acceso lo dan los roles de IAM de tus servicios, cada uno con lo justo (mirá el lab de IAM y mínimo privilegio).

El criterio

1. ¿Block Public Access está ON a nivel cuenta?   → cinturón maestro
2. ¿Alguna bucket policy tiene Principal "*"?      → la puerta abierta clásica
3. ¿Hay ACLs públicas viejas (AllUsers)?           → legado peligroso
4. ¿El acceso real lo dan roles de IAM acotados?   → así debería ser

Lo que practicás en este lab

Llevátelo a tu repo si querés, pero no es obligatorio: es tu aprendizaje.

  • El antes/después de una bucket policy: de pública a privada
  • El comando con el que verificaste el estado de Block Public Access
  • Writeup de 2 líneas: qué capa estaba dejando el bucket abierto

Reto

Tomá la policy 'abierta' de abajo y volvela privada. Después escribí en dos líneas qué chequeo correrías para confirmar, desde afuera, que ya nadie anónimo puede leer los objetos.

Resolvelo y escribí dos líneas explicando qué pasó. Con eso lo fijás.

¿Hiciste el lab?

Si querés, guardá lo que hiciste (comandos, notas, un repo) para volver después. Y si encontrás un error o querés mejorar este lab, contribuí al repo. El progreso se guarda solo en tu navegador.