Cloud security misconfigurations are responsible for the majority of cloud data breaches. Unlike traditional network attacks that require exploitation of software vulnerabilities, misconfiguration breaches often require no skill — just knowing where to look for open resources that were left accessible by mistake. This guide covers the most dangerous AWS misconfigurations found in real-world environments.
The Scale of the Problem
Cloud Security Alliance research consistently shows 70%+ of cloud breaches result from customer-side misconfigurations, not provider-side vulnerabilities. AWS’s shared responsibility model makes this explicit: AWS secures the infrastructure; customers secure their configurations, data, and access controls.
Notable breaches from misconfigurations:
- Capital One (2019): Over-privileged EC2 instance role accessed S3 buckets containing 100M+ customer records
- Twitch (2021): Internal data exposed through misconfigured server
- Thousands of S3 breaches annually: Databases, credentials, backup files found publicly accessible
Critical Misconfiguration #1: Public S3 Buckets
The risk: S3 buckets are private by default, but multiple settings can make them public:
- Bucket ACL set to “Everyone can read/write”
- Bucket policy granting
s3:GetObjectto*(everyone) - Object ACLs set to public
- “Block Public Access” settings disabled
Audit command:
# List all buckets
aws s3 ls
# Check public access block for each bucket
aws s3api get-public-access-block --bucket BUCKET_NAME
# Check bucket policy
aws s3api get-bucket-policy --bucket BUCKET_NAME
# Check bucket ACL
aws s3api get-bucket-acl --bucket BUCKET_NAME
Fix:
# Enable all block public access settings
aws s3api put-public-access-block --bucket BUCKET_NAME --public-access-block-configuration "BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true"
Account-wide fix: Enable S3 Block Public Access at the account level — prevents any bucket in the account from becoming public:
aws s3control put-public-access-block --account-id ACCOUNT_ID --public-access-block-configuration "BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true"
Critical Misconfiguration #2: Overly Permissive IAM
The risk: IAM entities with *:* permissions (admin access) when they need only specific permissions violates least privilege. Compromising one highly-privileged entity gives attackers full account access.
Common violations:
- Lambda functions with AdministratorAccess when they only need S3 read
- EC2 instance roles with full S3 access when they need to write to one bucket
- Developer users with production database access
- Service accounts with permissions accumulated over time and never reviewed
Audit commands:
# Find all IAM users/roles with AdministratorAccess
aws iam list-entities-for-policy --policy-arn arn:aws:iam::aws:policy/AdministratorAccess
# Find IAM policies that allow *:* (broad permissions)
aws iam list-policies --scope Local --query 'Policies[*].Arn' | xargs -I{} aws iam get-policy-version --policy-arn {} --version-id $(aws iam get-policy --policy-arn {} --query 'Policy.DefaultVersionId' --output text)
Fix: Implement least privilege — grant only the minimum permissions needed:
{
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:PutObject"
],
"Resource": "arn:aws:s3:::my-specific-bucket/*"
}
Use IAM Access Analyzer to identify unused permissions and right-size policies:
aws accessanalyzer create-analyzer --analyzer-name myAnalyzer --type ACCOUNT
Critical Misconfiguration #3: Publicly Accessible Databases
The risk: RDS databases, ElasticSearch/OpenSearch clusters, and Redshift warehouses with 0.0.0.0/0 in their security groups are accessible from the internet.
Audit:
# Find RDS instances with public accessibility
aws rds describe-db-instances --query 'DBInstances[?PubliclyAccessible==`true`].[DBInstanceIdentifier,Endpoint.Address]'
# Check security groups for 0.0.0.0/0 ingress on database ports
aws ec2 describe-security-groups --query 'SecurityGroups[?IpPermissions[?IpRanges[?CidrIp==`0.0.0.0/0`] && (FromPort==`3306` || FromPort==`5432` || FromPort==`1433`)]]'
Fix: Databases should only be accessible from application subnets, not from the internet:
- Set
PubliclyAccessible = falseon RDS instances - Configure security groups to allow inbound database connections only from specific application security groups or VPC CIDR ranges
- Use VPC endpoints and bastion hosts / AWS Systems Manager Session Manager for administrative access
Critical Misconfiguration #4: Exposed EC2 Metadata Service (IMDSv1)
The risk: EC2’s metadata service (169.254.169.254) can return temporary credentials for the instance’s IAM role. IMDSv1 is unauthenticated — any SSRF (Server-Side Request Forgery) vulnerability in an application can leak these credentials.
The Capital One breach exploited this exact vulnerability: An SSRF in a firewall application was used to query the metadata service and retrieve credentials for a highly-privileged IAM role.
Fix: Enforce IMDSv2 (requires session tokens):
# Enforce IMDSv2 on an existing instance
aws ec2 modify-instance-metadata-options --instance-id i-XXXXX --http-tokens required --http-endpoint enabled
# Require IMDSv2 for all new instances (account-level policy)
aws ec2 describe-instances --query 'Reservations[*].Instances[*].[InstanceId,MetadataOptions.HttpTokens]'
Critical Misconfiguration #5: Secrets in Code and Environment Variables
The risk: AWS access keys committed to GitHub, hard-coded in Lambda environment variables (visible in console), or stored in EC2 user data.
GitHub continuously scans public repositories for exposed credentials. Attackers also scan using tools like TruffleHog and GitLeaks.
Audit your repositories:
# Install trufflehog
pip3 install trufflehog --break-system-packages
# Scan a repository
trufflehog git https://github.com/your-org/your-repo
Fix: Use AWS Secrets Manager or Parameter Store for secrets:
import boto3
client = boto3.client('secretsmanager')
secret = client.get_secret_value(SecretId='prod/database/password')
Enable IAM access key rotation and GitHub secret scanning alerts for your organization.
Automated Misconfiguration Detection
AWS Security Hub: Aggregates findings from multiple AWS security services and runs CIS AWS Foundations Benchmark checks automatically.
aws securityhub enable-security-hub --enable-default-standards
AWS Config: Continuously monitors resource configurations against rules:
aws configservice put-config-rule --config-rule file://s3-bucket-public-read-prohibited.json
ScoutSuite: Open-source multi-cloud security audit tool that checks all of the above automatically:
python3 -m scout aws --no-browser
Cloud security posture management is an ongoing practice, not a one-time audit. Enable AWS Security Hub, run ScoutSuite quarterly, and make IAM least privilege a development practice from day one.