¿Qué hace Auditoría de Permisos de Buckets S3 en AWS?
Cuándo Usarlo
- Al realizar una evaluación de seguridad de entornos AWS para identificar datos expuestos públicamente
- Al incorporar una nueva cuenta de AWS y establecer una línea base de seguridad para los recursos de almacenamiento
- Al responder a una alerta sobre una posible exposición de datos S3 desde AWS Trusted Advisor o Security Hub
- Cuando los marcos de cumplimiento (SOC 2, PCI DSS, HIPAA) requieren una revisión periódica de los controles de acceso a los datos
- Cuando una brecha o compromiso de credenciales requiere una revisión inmediata de todos los recursos S3 accesibles
No usar para auditar almacenamiento de objetos que no sea AWS (usar herramientas específicas del proveedor), para monitoreo en tiempo real (usar S3 Event Notifications con Lambda) o para auditar patrones de acceso a S3 (usar S3 Access Analyzer o CloudTrail S3 data events).
Prerrequisitos
- AWS CLI v2 configurado con credenciales que tengan permisos
s3:GetBucketPolicy,s3:GetBucketAcl,s3:GetBucketPublicAccessBlock,s3:GetEncryptionConfigurationys3:ListAllMyBuckets - Prowler instalado (
pip install prowler) para comprobaciones automatizadas del benchmark CIS - S3audit o una herramienta de enumeración similar para la detección rápida de buckets públicos
- Acceso a AWS Organizations si se audita en múltiples cuentas
- Python 3.8+ con boto3 para scripts de auditoría personalizados
Flujo de Trabajo
Paso 1: Enumerar Todos los Buckets S3 y el Bloqueo de Acceso Público a Nivel de Cuenta
Primero, verifique la configuración de Bloqueo de Acceso Público a nivel de cuenta, luego enumere todos los buckets con sus regiones.
# Verificar la configuración de Bloqueo de Acceso Público a nivel de cuenta
aws s3control get-public-access-block \
--account-id $(aws sts get-caller-identity --query Account --output text) \
--output json
# Listar todos los buckets con fechas de creación
aws s3api list-buckets \
--query 'Buckets[*].[Name,CreationDate]' \
--output table
# Obtener las regiones de cada bucket
for bucket in $(aws s3api list-buckets --query 'Buckets[*].Name' --output text); do
region=$(aws s3api get-bucket-location --bucket "$bucket" --query 'LocationConstraint' --output text)
echo "$bucket -> ${region:-us-east-1}"
done
Paso 2: Verificar el Bloqueo de Acceso Público y la Configuración de ACL de Cada Bucket
Itere sobre todos los buckets para evaluar sus bloques de acceso público individuales y las concesiones de ACL.
# Verificar la configuración de Bloqueo de Acceso Público por bucket
for bucket in $(aws s3api list-buckets --query 'Buckets[*].Name' --output text); do
echo "=== $bucket ==="
aws s3api get-public-access-block --bucket "$bucket" 2>/dev/null || echo " No se ha configurado Block Public Access"
# Verificar ACL en busca de concesiones públicas
aws s3api get-bucket-acl --bucket "$bucket" \
--query 'Grants[?Grantee.URI==`http://acs.amazonaws.com/groups/global/AllUsers` || Grantee.URI==`http://acs.amazonaws.com/groups/global/AuthenticatedUsers`]' \
--output json
done
Paso 3: Analizar las Políticas de Bucket en Busca de Acceso Demasiado Permisivo
Revise las políticas de bucket en busca de principals comodín, condiciones faltantes y declaraciones que permitan un acceso amplio.
# Extraer y analizar las políticas de bucket
for bucket in $(aws s3api list-buckets --query 'Buckets[*].Name' --output text); do
policy=$(aws s3api get-bucket-policy --bucket "$bucket" --output text 2>/dev/null)
if [ -n "$policy" ]; then
echo "=== Política de $bucket ==="
echo "$policy" | python3 -c "
import json, sys
policy = json.load(sys.stdin)
for stmt in policy.get('Statement', []):
principal = stmt.get('Principal', {})
effect = stmt.get('Effect', '')
if principal == '*' or principal == {'AWS': '*'}:
print(f' ADVERTENCIA: {effect} con principal comodín')
print(f' Acciones: {stmt.get(\"Action\", \"\")}')
print(f' Condición: {stmt.get(\"Condition\", \"NINGUNA\")}')
"
fi
done
Paso 4: Verificar la Configuración de Cifrado y Versionado
Compruebe que todos los buckets tengan el cifrado del lado del servidor habilitado y el versionado configurado para la protección de datos.
# Verificar el estado del cifrado y el versionado para todos los buckets
for bucket in $(aws s3api list-buckets --query 'Buckets[*].Name' --output text); do
echo "=== $bucket ==="
# Configuración de cifrado
aws s3api get-bucket-encryption --bucket "$bucket" 2>/dev/null \
&& echo " Cifrado: HABILITADO" \
|| echo " Cifrado: DESHABILITADO"
# Estado del versionado
aws s3api get-bucket-versioning --bucket "$bucket" \
--query 'Status' --output text
# Estado del registro de acceso
aws s3api get-bucket-logging --bucket "$bucket" \
--query 'LoggingEnabled' --output text 2>/dev/null
done
Paso 5: Ejecutar las Comprobaciones Específicas de S3 con Prowler
Ejecute las comprobaciones centradas en S3 de Prowler alineadas con el benchmark CIS AWS Foundations.
# Ejecutar comprobaciones específicas de S3 con Prowler
prowler aws \
--checks s3_bucket_public_access \
s3_bucket_default_encryption \
s3_bucket_policy_public_write_access \
s3_bucket_server_access_logging_enabled \
s3_bucket_versioning_enabled \
s3_bucket_acl_prohibited \
-M json-ocsf \
-o ./prowler-s3-audit/
# Ver resumen
prowler aws --checks s3 -M csv -o ./prowler-s3-audit/
Paso 6: Usar IAM Access Analyzer para Hallazgos S3 Públicos y entre Cuentas
Aproveche IAM Access Analyzer para identificar buckets compartidos externa o públicamente.
# Listar hallazgos de Access Analyzer para S3
aws accessanalyzer list-findings \
--analyzer-arn $(aws accessanalyzer list-analyzers --query 'analyzers[0].arn' --output text) \
--filter '{"resourceType": {"eq": ["AWS::S3::Bucket"]}}' \
--query 'findings[*].[resource,status,condition,principal]' \
--output table
# Crear un analizador si no existe
aws accessanalyzer create-analyzer \
--analyzer-name s3-access-audit \
--type ACCOUNT
Paso 7: Generar Informe de Auditoría y Remediar
Compile los hallazgos en un informe procesable y aplique la remediación para los problemas críticos.
# Remedio rápido: Habilitar Block Public Access en un bucket
aws s3api put-public-access-block \
--bucket TARGET_BUCKET \
--public-access-block-configuration \
'BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true'
# Habilitar el cifrado predeterminado con SSE-S3
aws s3api put-bucket-encryption \
--bucket TARGET_BUCKET \
--server-side-encryption-configuration \
'{"Rules":[{"ApplyServerSideEncryptionByDefault":{"SSEAlgorithm":"aws:kms","KMSMasterKeyID":"alias/aws/s3"},"BucketKeyEnabled":true}]}'
# Habilitar versionado
aws s3api put-bucket-versioning \
--bucket TARGET_BUCKET \
--versioning-configuration Status=Enabled
Conceptos Clave
| Término | Definición |
|---|---|
| S3 Block Public Access | Configuraciones a nivel de cuenta y de bucket que anulan ACL y políticas para evitar el acceso público independientemente de las configuraciones de recursos individuales |
| Bucket Policy | Política de recursos basada en JSON adjunta a un bucket que define quién puede acceder al bucket y qué acciones pueden realizar |
| ACL (Lista de Control de Acceso) | Mecanismo heredado de control de acceso a S3 que otorga permisos a cuentas de AWS o grupos predefinidos como AllUsers o AuthenticatedUsers |
| IAM Access Analyzer | Servicio de AWS que analiza las políticas de recursos para identificar recursos compartidos con entidades externas o el público |
| Cifrado del Lado del Servidor | Cifrado aplicado por S3 a nivel de objeto usando SSE-S3, SSE-KMS o SSE-C antes de escribir datos en el disco |
| CIS AWS Foundations Benchmark | Estándar de mejores prácticas de seguridad del Center for Internet Security con controles específicos para la configuración de buckets S3 |
Herramientas y Sistemas
- AWS CLI: Interfaz principal para consultar configuraciones de buckets S3, políticas, ACL y configuraciones de cifrado
- Prowler: Herramienta de seguridad de código abierto con más de 50 comprobaciones específicas de S3 alineadas con los controles CIS, PCI DSS e HIPAA
- IAM Access Analyzer: Servicio nativo de AWS para la supervisión continua de políticas de recursos que otorgan acceso externo
- S3audit: Herramienta ligera para la enumeración rápida de buckets S3 públicos en una cuenta
- ScoutSuite: Herramienta de auditoría multinube que recopila datos de configuración de S3 y genera informes HTML con puntuación de riesgo
Escenarios Comunes
Escenario: Identificar un Bucket Legible Públicamente que Contiene Datos de Clientes
Contexto: Un ingeniero de seguridad recibe una alerta de Trusted Advisor sobre un bucket S3 accesible públicamente. El bucket fue creado por un equipo de desarrollo para una demostración y nunca fue protegido.
Enfoque:
- Ejecute
aws s3api get-bucket-acly encuentre una concesión aAllUserscon permisoREAD - Verifique
get-bucket-policyy descubra una política conPrincipal: "*"ys3:GetObject - Confirme que Block Public Access no está habilitado a nivel de bucket ni de cuenta
- Enumere el contenido del bucket para evaluar la sensibilidad de los datos
- Habilite inmediatamente Block Public Access en el bucket
- Revise los eventos de datos de CloudTrail S3 para determinar si ocurrió un acceso no autorizado
- Informe el hallazgo con la línea de tiempo, el inventario de datos y la confirmación de la remediación
Errores Comunes: Habilitar Block Public Access puede romper aplicaciones que intencionalmente sirven contenido públicamente (sitios web estáticos). Siempre verifique el uso previsto del bucket antes de aplicar restricciones. Verifique las distribuciones de CloudFront u otros servicios que dependan del acceso público del bucket.
Formato de Salida
Informe de Auditoría de Permisos de Buckets S3
===============================================
Cuenta: 123456789012 (Producción)
Fecha: 2026-02-23
Auditor: Equipo de Ingeniería de Seguridad
Total de Buckets: 47
CONFIGURACIONES A NIVEL DE CUENTA:
Block Public Access: HABILITADO (las cuatro configuraciones)
HALLAZGOS CRÍTICOS:
[S3-001] Acceso de Lectura Pública a través de ACL
Bucket: marketing-assets-prod
Problema: Grupo AllUsers tiene permiso READ a través de ACL
Riesgo: Cualquier usuario de Internet puede listar y descargar el contenido del bucket
Sensibilidad de Datos: Contiene activos de marketing no sensibles orientados al cliente
Remediación: Eliminar la concesión ACL de AllUsers, habilitar Block Public Access
[S3-002] Principal Comodín en la Política del Bucket
Bucket: data-exchange-partner
Problema: La política permite s3:GetObject con Principal "*" y sin condición de VPC/IP
Riesgo: Intencionado para acceso de socios pero accesible para cualquiera que conozca el nombre del bucket
Remediación: Agregar condición aws:SourceVpce o aws:SourceIp para restringir el acceso
RESUMEN:
Buckets con acceso público: 3 / 47
Buckets sin cifrado: 5 / 47
Buckets sin versionado: 12 / 47
Buckets sin registro de acceso: 18 / 47
Buckets con políticas demasiado amplias: 7 / 47