Avançado Cloud

Misconfiguration na cloud — S3 público, security group aberto, bucket ACL

Misconfiguration é a causa número um de vazamentos de dados em ambientes cloud. Não é malware, não é exploit de zero-day — é um checkbox marcado errado, uma política permissiva demais, um recurso exposto sem querer. O CSPM (Cloud Security Posture Management) existe justamente para detectar essas falhas em escala.

S3 público — o clássico vazamento

Buckets S3 com acesso público já expuseram dados de saúde, financeiros e governamentais de milhões de pessoas. O erro mais comum: desabilitar o “Block Public Access” sem perceber o impacto.

# Verificar se o bucket tem block public access habilitado
aws s3api get-public-access-block --bucket nome-do-bucket

# Resposta segura (todos true):
# {
#   "PublicAccessBlockConfiguration": {
#     "BlockPublicAcls": true,
#     "IgnorePublicAcls": true,
#     "BlockPublicPolicy": true,
#     "RestrictPublicBuckets": true
#   }
# }

# Corrigir — habilitar bloqueio total
aws s3api put-public-access-block \
  --bucket nome-do-bucket \
  --public-access-block-configuration \
    "BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true"

Bucket policy que vaza dados sem querer:

// RUIM — permite leitura pública de todos os objetos
{
  "Statement": [{
    "Effect": "Allow",
    "Principal": "*",
    "Action": "s3:GetObject",
    "Resource": "arn:aws:s3:::nome-do-bucket/*"
  }]
}

// BOM — acesso somente pela role da aplicação
{
  "Statement": [{
    "Effect": "Allow",
    "Principal": { "AWS": "arn:aws:iam::123456789:role/app-role" },
    "Action": "s3:GetObject",
    "Resource": "arn:aws:s3:::nome-do-bucket/*"
  }]
}

Security Groups — portas abertas demais

Security groups funcionam como firewalls stateful. O erro mais comum é abrir 0.0.0.0/0 em portas críticas:

# Listar regras de ingress perigosas
aws ec2 describe-security-groups \
  --query "SecurityGroups[?IpPermissions[?IpRanges[?CidrIp=='0.0.0.0/0']]].{ID:GroupId,Name:GroupName,Rules:IpPermissions}" \
  --output table
Portas nunca abertas para 0.0.0.0/0 em produção:
  22    (SSH)     → use Systems Manager Session Manager
  3389  (RDP)     → use SSM ou VPN
  3306  (MySQL)   → acesso apenas pela subnet da aplicação
  5432  (Postgres)→ idem
  6379  (Redis)   → nunca exposto à internet
  27017 (MongoDB) → idem
  443   (HTTPS)   → aceitável se for load balancer público

Correto:
  SG do banco   → ingress apenas do SG da aplicação, porta específica
  SG da app     → ingress do SG do load balancer
  SG do LB      → ingress 0.0.0.0/0 em 443 apenas

ACL de bucket vs bucket policy

ACLs são o mecanismo legado da AWS. A AWS recomenda desabilitar ACLs e usar apenas bucket policies:

# Checar ownership controls do bucket
aws s3api get-bucket-ownership-controls --bucket nome-do-bucket

# Configurar BucketOwnerEnforced (desabilita ACLs)
aws s3api put-bucket-ownership-controls \
  --bucket nome-do-bucket \
  --ownership-controls "Rules=[{ObjectOwnership=BucketOwnerEnforced}]"

Outros vetores comuns de misconfiguration

RDS com acesso público:
  aws rds modify-db-instance \
    --db-instance-identifier meu-banco \
    --no-publicly-accessible

Snapshot de EBS/RDS público:
  aws rds describe-db-snapshots \
    --query "DBSnapshots[?PubliclyRestored==true]"

Lambda com resource policy aberta:
  Remova policies que concedem invocação a "*"
  aws lambda remove-permission --function-name minha-func --statement-id id-perigoso

CloudFront sem HTTPS forçado:
  ViewerProtocolPolicy: redirect-to-https  (nunca allow-all)

Detecção automatizada

# AWS Config — regra gerenciada para S3 público
aws configservice put-config-rule --config-rule '{
  "ConfigRuleName": "s3-bucket-public-read-prohibited",
  "Source": {
    "Owner": "AWS",
    "SourceIdentifier": "S3_BUCKET_PUBLIC_READ_PROHIBITED"
  }
}'

# Security Hub — ativa CIS AWS Foundations Benchmark
aws securityhub enable-security-hub --enable-default-standards

Use ferramentas como Prowler, ScoutSuite ou Checkov para varredura contínua de misconfiguration no pipeline e na conta.