June 24, 2026
The S3 misconfiguration we keep finding in 2026
Ten years ago the classic S3 finding was a bucket open to the world. AWS has since added Block Public Access, default encryption, and enough console warnings that genuinely public buckets are now rare in the environments we test. That is real progress.
So why does S3 still show up in most of our cloud engagement reports? Because the misconfiguration moved. It went from loud to quiet.
The finding: cross-account trust that nobody remembers
The pattern we keep seeing in 2026 looks like this. A bucket policy grants access to another AWS account: a vendor, an old analytics integration, a sister company from before a restructure. The grant was reasonable when it was written. Then the relationship ended, the vendor got acquired, or the project was cancelled, and the policy stayed.
Here is a sanitized version of a policy we found this spring:
{
"Effect": "Allow",
"Principal": { "AWS": "arn:aws:iam::REDACTED:root" },
"Action": ["s3:GetObject", "s3:ListBucket"],
"Resource": ["arn:aws:s3:::corp-data-exports", "arn:aws:s3:::corp-data-exports/*"]
}
The account number belonged to a marketing agency the client stopped working with in 2023. The bucket held nightly exports of their customer table. Nobody had looked at the policy since it was written, because nothing was broken.
Access reviews catch employees who left. Almost nobody reviews the AWS accounts, roles, and integrations that left.
Three quieter variants
The same root cause, unowned access that outlived its purpose, shows up in three more shapes:
- Replication rules to buckets in other accounts. Replication is set up during a migration or a data-sharing agreement, then forgotten. Data keeps flowing to an account nobody monitors.
- Presigned URLs generated with long expiries. We have seen seven-day URLs generated in batch jobs and then written into logs, tickets, and Slack. Anyone with log access has data access.
- IAM conditions that are broader than they read. A condition on
aws:PrincipalOrgIDfeels tight until the organization adds accounts for a subsidiary, a sandbox program, or an acquisition, and every one of them inherits the access.
What to do about it
The fix is not a tool purchase. It is a small amount of recurring attention:
- Inventory every bucket policy and access point policy that names an external principal. AWS IAM Access Analyzer will list these for you, and it is free.
- For each one, write down an owner and a reason. If nobody claims it in a week, remove it and see what breaks. In our experience, almost nothing does.
- Cap presigned URL lifetimes in code review, and treat a presigned URL in a log file as a leaked credential.
- Re-run the review quarterly. Fifteen minutes on a calendar beats an incident retro.
We run this exact review as part of every cloud engagement, and it has produced a finding in every environment we have tested this year. If you have never done it, that is the highest-value afternoon available to your team this quarter.