After conducting over 120 AWS cloud security audits across industries from healthcare to financial services in both the UK and USA, certain misconfigurations appear with near-perfect consistency. These are not exotic edge cases — they are fundamental errors that result from the speed of cloud adoption outpacing security maturity. Here are the seven we find in almost every engagement.

1. Wildcard IAM Policies

IAM policies using Action: "*" or Resource: "*" grant far more access than any role legitimately requires. We find these in CI/CD pipelines, Lambda execution roles, and developer sandbox accounts that were never cleaned up.

The pattern is always the same: a developer needed broad access to get something working quickly, applied a permissive policy, it worked, and nobody ever revisited it. Months later, that role has been assigned to fifteen different resources and touched by multiple teams.

Remediation: Implement least-privilege IAM programmatically. Tools like IAM Access Analyzer identify over-permissive policies automatically. AWS's own IAM best practices guidance recommends using * only as the resource when the action itself doesn't support resource-level permissions — and even then, with condition keys to narrow scope.

2. Publicly Readable S3 Buckets

Despite AWS's account-level public access block, organisations regularly have buckets created by third-party tools or older Terraform modules that expose internal documents and credential files.

In a FTSE 250 audit last quarter, we found a publicly readable S3 bucket containing a database backup with 2.3 million customer records. The bucket had been created by a third-party analytics tool during a proof-of-concept that was never properly decommissioned. The public access block was enabled at the account level, but this specific bucket had an explicit ACL that predated the account-level setting.

Remediation: Enable S3 Block Public Access at the organisation level via Service Control Policy. Run aws s3api list-buckets combined with get-bucket-acl and get-bucket-policy checks in your security automation pipeline.

3. Long-Lived, Unrotated IAM Access Keys

Long-lived IAM user access keys — some over three years old — appear in every audit. These keys are typically associated with programmatic access for legacy applications, CI/CD systems, or developer accounts.

A single inadvertent commit to a public repository is enough to expose them. Once exposed, services like GitGuardian or even public GitHub search will surface them within minutes. We regularly find keys in build logs, in application configuration files checked into source control, and in Slack messages.

Remediation: Replace IAM user credentials with IAM role assumption for application access and AWS Secrets Manager for secret storage. For developers, enforce SSO. Audit key age with aws iam generate-credential-report and set a policy of automatic revocation at 90 days.

4. CloudTrail Coverage Gaps

CloudTrail is frequently enabled only in a single region, or with data events disabled, or logging to a bucket in the same account as the workloads it's auditing.

If CloudTrail logs to a bucket in the same account, an attacker with sufficient permissions can delete the logs before exfiltrating data. If only one region is covered, API calls in other regions — including global services like IAM — may not be captured.

Remediation: Enable multi-region trails. Enable S3 and Lambda data event logging (these are disabled by default and incur cost, but are essential for forensic capability). Deliver logs to an immutable, cross-account S3 bucket with Object Lock enabled.

5. Unencrypted Parameter Store Secrets

We routinely find database credentials, API keys, and signing secrets in unencrypted standard parameters (/aws/standard/ tier) accessible to any role with ssm:GetParameter permissions — which is often far too broad.

The Standard tier of Parameter Store does not encrypt values at rest by default. Developers frequently use it as a convenient configuration store without understanding the security implications. A Lambda function with ssm:GetParameter:* can read every parameter in the account.

Remediation: Use SecureString parameters with KMS encryption for all sensitive values. Scope ssm:GetParameter permissions to specific parameter ARNs rather than wildcards. Consider migrating sensitive secrets to AWS Secrets Manager, which provides automatic rotation.

6. Security Groups with 0.0.0.0/0 Ingress

Overly permissive security groups are endemic, particularly on development infrastructure promoted to production without hardening.

RDP (3389) and SSH (22) exposed to 0.0.0.0/0 are the highest-risk variants — directly exploitable if the instance has a weak password, default credentials, or an unpatched vulnerability. We also frequently find database ports (5432 for PostgreSQL, 3306 for MySQL) open to the internet.

Remediation: Implement a security group baseline that denies all inbound internet traffic by default. Use AWS Systems Manager Session Manager for shell access to EC2 instances — this eliminates the need for inbound SSH entirely. Enforce this via AWS Config rules with automated remediation.

7. IMDSv1 Enabled on EC2 Instances

IMDSv1 is vulnerable to Server-Side Request Forgery (SSRF) attacks that allow credential theft from the instance metadata endpoint (169.254.169.254). Any SSRF vulnerability in an application running on an EC2 instance can be leveraged to steal the instance's IAM role credentials.

This attack vector was used in the 2019 Capital One breach. Despite significant public awareness since then, IMDSv1 remains enabled on the majority of EC2 instances we assess.

Remediation: Enforce IMDSv2 at the account level via Service Control Policy:

{
  "Effect": "Deny",
  "Action": "ec2:RunInstances",
  "Resource": "arn:aws:ec2:*:*:instance/*",
  "Condition": {
    "StringNotEquals": {
      "ec2:MetadataHttpTokens": "required"
    }
  }
}

This takes under ten minutes to implement and eliminates an entire attack class.


These seven findings are not the result of sophisticated attacks or novel techniques. They are the predictable output of cloud adoption that moved faster than security governance. The organisations that address all seven will have eliminated the attack paths we successfully exploit in the vast majority of our engagements.