Seguridad de S3 más allá de "bloquear acceso público": las ocho comprobaciones que hacemos
Los buckets públicos son el titular y la parte fácil. Las fugas que encontramos ahora vienen de políticas de bucket, URLs prefirmadas, replicación y logs que nadie lee. Esta es la pasada completa.
Block Public Access resolvió el problema de 2017. Ya casi no hay buckets legibles por todo el mundo por accidente, y cualquier escáner pilla los que quedan. Los incidentes que vemos ahora son más silenciosos: una política de bucket que confía en una cuenta entera, una URL prefirmada con siete días de validez parada en un canal de Slack, replicación a un bucket de una cuenta que nadie recuerda tener.
Esta es la pasada completa que hacemos sobre S3 en un diagnóstico, en orden.
1. Block Public Access a nivel de cuenta, en todas
No por bucket: a nivel de cuenta, en todas las cuentas, impuesto por una SCP que deniegue s3:PutAccountPublicAccessBlock cuando debilite el ajuste. La configuración por bucket es un elemento que puede derivar; la de cuenta es un muro. Si de verdad necesitas un bucket público para activos estáticos, ponlo en su propia cuenta con sus propias reglas y sírvelo por CloudFront con un origin access control en vez de lecturas públicas.
2. Lee todas las políticas de bucket, no solo las públicas
El hallazgo que más reportamos no es un bucket público, es una política con "Principal": {"AWS": "arn:aws:iam::123456789012:root"} — que confía en todos los principales de esa cuenta, incluido el rol del becario y cualquier cosa que se comprometa allí. Acota a ARN de roles concretos. Cuando un tercero necesite acceso, exige sts:ExternalId y una condición sobre aws:SourceAccount o aws:SourceArn.
Añade también una denegación por aws:SecureTransport y, donde puedas, una condición aws:PrincipalOrgID, que convierte "cualquiera con el ARN" en "cualquiera dentro de nuestra organización".
3. Cifrado, y quién tiene la clave
SSE-S3 viene activado por defecto y vale para la mayoría de datos. SSE-KMS importa cuando quieres una traza de auditoría del descifrado y la posibilidad de revocar acceso por política de clave en lugar de por política de bucket. Usa una clave gestionada por el cliente para lo regulado, activa bucket keys para bajar el coste de peticiones a KMS y —la parte que se olvida— revisa la política de la clave, porque una política de KMS permisiva deshace una política de bucket cuidadosa.
4. URLs prefirmadas y su vida útil
Este es el vector de fuga actual. Una URL prefirmada lleva los permisos de quien la firma durante toda su validez, y es un token al portador: quien tenga el enlace tiene el objeto. Dos reglas: limita la caducidad a 15 minutos para lo sensible, y genéralas con un rol dedicado acotado a un solo prefijo, nunca con un rol de aplicación que pueda leer el bucket entero.
5. Versionado, object lock y el camino de borrado
Versionado activo, MFA delete u object lock para logs y copias de seguridad, y una regla de ciclo de vida que caduque las versiones no actuales — si no, el versionado es una fuga de coste silenciosa. Para copias que deban sobrevivir a una cuenta comprometida, replica a un bucket en otra cuenta con object lock en modo compliance. Esa combinación es lo que convierte "tenemos copias" en "tenemos copias que un atacante con admin no puede borrar".
6. Registro de accesos que alguien pueda consultar
Logs de acceso del servidor o, mejor, eventos de datos de CloudTrail para los buckets que importan. Los eventos de datos cuestan dinero a volumen, así que actívalos de forma selectiva en los buckets con datos de clientes, mándalos a la cuenta de archivo de logs y asegúrate de que alguien puede consultarlos de verdad — Athena sobre el bucket de logs con una tabla de proyección de particiones, configurado una vez.
7. Replicación y dónde viven las copias
Enumera todas las reglas de replicación y anota la cuenta de destino. En entornos con más de tres años casi siempre encontramos un destino de replicación en una cuenta sin dueño, sin monitorización y con una política de bucket rancia. Una copia de tus datos en una cuenta no monitorizada son tus datos, sin ninguno de tus controles.
8. Qué hay ahí dentro realmente
Macie, ejecutado como escaneo puntual en lugar de continuo, te dice qué buckets contienen números de tarjeta, documentos de identidad o credenciales. Dejarlo encendido es caro; como trabajo trimestral es barato y revelador. Casi todos los equipos encuentran al menos un bucket con datos que no sabían que estaban clasificados — lo que suele cambiar por completo la conversación sobre retención.
Metemos las ocho en el diagnóstico de seguridad, y los escáneres open source de nuestro artículo sobre herramientas de postura cubren de la uno a la tres sin licencia ninguna.
Qué hacer esta semana
Saca todas las políticas de bucket de producción con aws s3api get-bucket-policy en un bucle y busca :root". Cada coincidencia es un bucket que confía en una cuenta entera. Ese grep son diez minutos y es la comprobación de S3 con mejor relación esfuerzo/resultado que existe.