Back to Blog
SecurityNovember 15, 20258 min read

Cloud-Native Security: The 7 AWS Misconfigurations That Lead to Breaches

AWS misconfigurations are behind the majority of cloud breaches. This post documents the 7 most common attack-leading misconfigurations, how external scanners detect them, and the AWS-native controls that prevent them.

Cloud infrastructure has changed the threat model for every organization. The perimeter is no longer defined by your firewall — it's defined by your IAM policies, your S3 bucket ACLs, and your security group rules. Misconfigure any of them and the exposure is global and immediate.

These 7 misconfigurations account for the vast majority of AWS-related security incidents. All of them are detectable from the external attack surface.

1. Public S3 Buckets

The most overexposed vulnerability category in AWS. Public S3 buckets have been the source of data exposures affecting healthcare records, financial data, source code, and customer PII across virtually every industry.

What it looks like externally:

GET https://company-backup.s3.amazonaws.com/  → HTTP 200, XML bucket listing
GET https://company-assets.s3.amazonaws.com/customer_data.csv  → HTTP 200, data

Why it happens: Teams create buckets for internal use and rely on the AWS console "public" indicator without understanding that IAM policies, ACLs, and bucket policies interact in complex ways. A bucket can appear "private" via one control path while being accessible via another.

Prevention:

# Account-level Block Public Access — prevents all public access regardless of bucket policies
aws s3control put-public-access-block \
  --account-id {account-id} \
  --public-access-block-configuration \
  BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true

Enable this at the account level. It overrides bucket-level settings. If you legitimately need public buckets (static website hosting, public assets), create a separate dedicated AWS account for them.

2. Overly Permissive Security Groups

Security groups are AWS virtual firewalls. The default configuration in many tutorials and automation templates opens ports to 0.0.0.0/0 (all of the internet) for convenience — and those ports stay open.

External detection: EASM tools scan for open ports across your known IP ranges. Common high-risk open ports:

PortServiceWhy It's High Risk
22SSHBrute-forceable; key exposure risk
3389RDPWindows remote desktop; ransomware target
3306MySQLDatabase direct access
5432PostgreSQLDatabase direct access
6379RedisOften no auth, in-memory data
27017MongoDBOften no auth by default
9200ElasticsearchNo auth by default in older versions
8080Development serverOften debug mode enabled
8888Jupyter NotebookNo auth by default

Prevention: Security groups should follow the principle of least privilege. Open only what's needed. Databases and internal services should never be in security groups with 0.0.0.0/0 ingress rules on their data ports.

3. IMDSv1 Enabled (SSRF → Credential Theft)

IMDSv1 (Instance Metadata Service version 1) is accessible at http://169.254.169.254/ from any process running on the instance. An SSRF vulnerability in any application on the instance can retrieve the instance's IAM credentials.

IMDSv1 credential retrieval:

curl http://169.254.169.254/latest/meta-data/iam/security-credentials/
# → {"role-name": "ec2-production-role"}

curl http://169.254.169.254/latest/meta-data/iam/security-credentials/ec2-production-role
# → {"AccessKeyId": "...", "SecretAccessKey": "...", "Token": "..."}

These credentials are temporary but valid for several hours. An attacker with these credentials has whatever permissions the EC2 instance's IAM role has.

Fix: Enforce IMDSv2, which requires a PUT-based session token before any metadata retrieval, making SSRF exploitation significantly harder:

aws ec2 modify-instance-metadata-options \
  --instance-id i-xxx \
  --http-tokens required

Or in your Terraform:

metadata_options {
  http_tokens = "required"
}

4. Wildcard IAM Policies

IAM policies that grant "Action": "*" or "Resource": "*" violate least privilege and create the conditions for catastrophic lateral movement when any credential is compromised.

The blast radius problem: If an EC2 instance with s3:* on * is compromised, an attacker can access every bucket in your account. If it also has iam:*, they can create new admin users and establish persistent access.

Detection from external perspective: Not directly detectable until compromise. Detection requires internal AWS Config rules or security tooling.

Prevention:

{
  "Effect": "Allow",
  "Action": [
    "s3:GetObject",
    "s3:PutObject"
  ],
  "Resource": "arn:aws:s3:::specific-bucket/*"
}

AWS IAM Access Analyzer identifies overly permissive policies automatically. Enable it in every region.

5. Exposed .git Directories

Web servers that serve .git/ directories publicly expose the entire version history of your codebase — including commits that contained credentials, API keys, or internal hostnames before they were removed.

Detection:

GET https://yourapp.com/.git/HEAD → HTTP 200 (exposed)
GET https://yourapp.com/.git/config → exposes remote URL
GET https://yourapp.com/.git/COMMIT_EDITMSG → exposes commit history

Tools like git-dumper can reconstruct the entire repository from an exposed .git/ directory.

Why it happens: Deployments that copy the entire project directory (including .git/) to web server document root, or Docker images built from the working directory without excluding .git/.

Fix: Configure your web server to deny access to .git/:

location ~ /\.git {
    deny all;
    return 404;
}

Or ensure your deployment pipeline never includes .git/ in the web root.

6. Default VPC and Insecure Default Configuration

AWS creates a default VPC in every region with public subnets and open internet gateway. Resources launched in the default VPC without explicit security group restrictions may be directly internet-accessible.

More critically: the default security group for the default VPC allows all inbound traffic from other instances in the same security group. In the default VPC, many teams' instances are in the same security group — creating an implicit east-west trust relationship.

Prevention: Don't use the default VPC for production workloads. Create application-specific VPCs with:

7. Public RDS Instances

RDS (Relational Database Service) instances with PubliclyAccessible: true are directly reachable from the internet. Combined with a weak password or default credentials, this is a direct path to database exfiltration.

Detection: EASM tools scanning for open database ports (3306, 5432, 1433) on IP ranges associated with AWS regions can identify publicly accessible RDS endpoints.

Fix: RDS instances should never have PubliclyAccessible: true unless there is a specific architectural requirement. Access to RDS should go through:

aws rds modify-db-instance \
  --db-instance-identifier mydb \
  --no-publicly-accessible \
  --apply-immediately

PentestCheck EASM Engine scans for all 7 of these misconfiguration patterns across your external IP range. Cloud infrastructure findings include direct remediation steps for AWS, GCP, and Azure.

Scan your attack surface today

Free plan includes 3 targets and 10 scans/month. No credit card required.

Start Free Scan