Advanced Cloud

Cloud misconfiguration — public S3, open security groups, bucket ACLs

Misconfiguration is the number one cause of data breaches in cloud environments. Not malware, not a zero-day exploit — a checkbox checked wrong, an overly permissive policy, a resource accidentally exposed. CSPM (Cloud Security Posture Management) exists precisely to detect these flaws at scale.

Public S3 — the classic leak

S3 buckets with public access have exposed health, financial, and government data belonging to millions of people. The most common mistake: disabling “Block Public Access” without understanding the impact.

# Check whether Block Public Access is enabled on a bucket
aws s3api get-public-access-block --bucket my-bucket

# Safe response (all true):
# {
#   "PublicAccessBlockConfiguration": {
#     "BlockPublicAcls": true,
#     "IgnorePublicAcls": true,
#     "BlockPublicPolicy": true,
#     "RestrictPublicBuckets": true
#   }
# }

# Fix — enable full blocking
aws s3api put-public-access-block \
  --bucket my-bucket \
  --public-access-block-configuration \
    "BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true"

Bucket policy that accidentally leaks data:

// BAD — allows public read on all objects
{
  "Statement": [{
    "Effect": "Allow",
    "Principal": "*",
    "Action": "s3:GetObject",
    "Resource": "arn:aws:s3:::my-bucket/*"
  }]
}

// GOOD — access only from the application role
{
  "Statement": [{
    "Effect": "Allow",
    "Principal": { "AWS": "arn:aws:iam::123456789:role/app-role" },
    "Action": "s3:GetObject",
    "Resource": "arn:aws:s3:::my-bucket/*"
  }]
}

Security Groups — overly open ports

Security groups work as stateful firewalls. The most common mistake is opening 0.0.0.0/0 on critical ports:

# List dangerous ingress rules
aws ec2 describe-security-groups \
  --query "SecurityGroups[?IpPermissions[?IpRanges[?CidrIp=='0.0.0.0/0']]].{ID:GroupId,Name:GroupName,Rules:IpPermissions}" \
  --output table
Ports that must never be open to 0.0.0.0/0 in production:
  22    (SSH)      → use Systems Manager Session Manager
  3389  (RDP)      → use SSM or VPN
  3306  (MySQL)    → access only from app subnet
  5432  (Postgres) → same
  6379  (Redis)    → never exposed to the internet
  27017 (MongoDB)  → same
  443   (HTTPS)    → acceptable if it's a public load balancer

Correct pattern:
  DB SG   → ingress only from app SG, specific port
  App SG  → ingress from load balancer SG
  LB SG   → ingress 0.0.0.0/0 on 443 only

Bucket ACL vs bucket policy

ACLs are the legacy mechanism in AWS. AWS recommends disabling ACLs and using bucket policies only:

# Check bucket ownership controls
aws s3api get-bucket-ownership-controls --bucket my-bucket

# Set BucketOwnerEnforced (disables ACLs)
aws s3api put-bucket-ownership-controls \
  --bucket my-bucket \
  --ownership-controls "Rules=[{ObjectOwnership=BucketOwnerEnforced}]"

Other common misconfiguration vectors

RDS with public access:
  aws rds modify-db-instance \
    --db-instance-identifier my-db \
    --no-publicly-accessible

Public EBS/RDS snapshot:
  aws rds describe-db-snapshots \
    --query "DBSnapshots[?PubliclyRestored==true]"

Lambda with open resource policy:
  Remove policies that grant invocation to "*"
  aws lambda remove-permission --function-name my-func --statement-id dangerous-id

CloudFront without forced HTTPS:
  ViewerProtocolPolicy: redirect-to-https  (never allow-all)

Automated detection

# AWS Config — managed rule for public S3
aws configservice put-config-rule --config-rule '{
  "ConfigRuleName": "s3-bucket-public-read-prohibited",
  "Source": {
    "Owner": "AWS",
    "SourceIdentifier": "S3_BUCKET_PUBLIC_READ_PROHIBITED"
  }
}'

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

Use tools like Prowler, ScoutSuite, or Checkov for continuous misconfiguration scanning in your pipeline and account.