Research

Amazon S3

Bucket Name Squatting

Author: Costas Kourmpoglou

We share our findings on four AWS services - Amazon Athena, AWS Elastic Beanstalk, AWS CodePipeline, AWS Config - and the implications of bucket name squatting.

The findings concern the behaviour of the AWS console when it comes to creating S3 buckets as a helping mechanism to assist with the use of the service.

S3 Bucket Name Squatting

AWS bucket names must be unique across all AWS accounts in all regions within a partition. Bucket name squatting often appears as an error in the AWS console: 'A bucket with that name already exists' when creating a new bucket. This is due to the global namespace.

An attacker can create a bucket, grant access to the victim, and either convince or confuse the victim to use that bucket. The attacker, having control of the bucket, can read or write to its contents, possibly without the victim's knowledge. The known attack vector involves predicting Amazon S3 bucket names that AWS services tend to pre-create for convenience in the AWS console. There is prior work on this subject with examples from Mckay and recently Kadkoda, Katchniskiy, Itach.

Joint analysis with AWS

On the 9th of August 2024, I emailed AWS security based on my findings. There were 4 services that I hadn’t seen prior work on - Amazon Athena, AWS Elastic Beanstalk, AWS CodePipeline, and AWS Config. I worked with the excellent and responsive AWS security representatives to outline the findings and receive feedback on my report.

Athena

AWS Athena icon

Amazon Athena - via the web console when accessing for the first time - required a query result location, which is an Amazon S3 bucket to be set.

Picture

Previously the Athena web console set a default bucket with the following format aws-athena-query-results-{accountid}-{region} like so:

Picture

The behaviour of the Athena web console has changed since and this is reflected in the documentation.

An attacker can create a query result S3 bucket knowing the victim’s AWS account ID - and region. They could then add a permission policy to the bucket that allows any principal from the victim’s account to write to said bucket.
The victim’s query Athena results would be transparently stored in the attacker’s defined bucket, where the attacker would have direct access, leading to data exfiltration.

Other services using Athena, e.g. QuickSight, that would require access to Athena query results also default to non-least privilege actions like

            {
            "Effect": "Allow",
            "Action": [
                "s3:GetBucketLocation",
                "s3:GetObject",
                "s3:ListBucket",
                "s3:ListBucketMultipartUploads",
                "s3:ListMultipartUploadParts",
                "s3:AbortMultipartUpload",
                "s3:CreateBucket",
                "s3:PutObject",
                "s3:PutBucketPublicAccessBlock"
            ],
            "Resource": [
                "arn:aws:s3:::aws-athena-query-results-*"
            ]
        }

IAM statement from AWS managed policy - arn:aws:iam::aws:policy/service-role/AWSQuicksightAthenaAccess that would allow access to any Athena query result bucket.

Amazon Athena as a defense in depth feature enhancement now requires a bucket be specified. Prior to this update, we provided customers the option to specify a specific bucket for the Athena query results. It is up to the customer to secure their workloads as part of the Customer side of the Shared Responsibility Model.

Statement by AWS

Elastic Beanstalk

AWS Elastic Beanstalk icon

The source bundle used by AWS Elastic Beanstalk is stored in an Amazon S3 bucket. In the web console the default bucket has the format of elasticbeanstalk-{region}-{accountid}.

An attacker could create an S3 bucket and have the victim store the source bundle artifacts to the S3 bucket of their ownership.

This can lead to data exfiltration as the attacker has direct access to the source bundle. Additionally, it could lead to an application compromise if the attacker manages to perform a TOCTOU (Time-of-check to time-of-use) type of vulnerability. Essentially modifying the source bundle from the time of the source bundle’s upload to the S3 bucket to the time of using the source bundle to deploy the application.

Additional defense in depth protections have been deployed as of 2024-12-11.

Statement by AWS

CodePipeline

AWS CodePipeline icon

Default artefact location

Screenshot of AWS console showing default settings

Confirmed in the review pane

Screenshot of review pane following creation of CodePipeline

The format is codepipeline-{region}-{12digits}

The 12 digits - which coincide with the AWS Account ID format, appear to be generated client-side before the console makes a call to CreatePipeline using

Math.floor(Math.random() * Math.pow(10, 12));

The buckets are per account, per region. The chances of a collision with an attacker controlled AWS account are roughly 10^6 due to the birthday paradox, meaning an attacker would need to control about a million buckets in that region to have a more than 50% chance to collide with another victim account.
The good news is that this is totally doable. The other good news is that this probability significantly increases depending on the AWS customers that have created CodePipeline artefacts using the console. The bad news is that it will cost ~USD20,000 per month.

CodePipeline is not impacted due to additional backend operations that already protect against bucket squatting.

Statement by AWS

Config

AWS Config icon

AWS Config - via the web console - before prior access requires a delivery channel to be set, which is an Amazon S3 bucket.

Screenshot of AWS Config setup showing S3 bucket creation

The attacker can pre-create the bucket which has the following format

config-bucket-{account}

The web console will do a writeability check by dropping a file named ConfigWritabilityCheckFile. The difference here is that the service principal - namely config.amazonaws.com will be writing to the bucket and not an IAM principal from the victim’s account, like in Athena.

This is well documented as part of the confused deputy prevention.
The web console calls an internal API under CreateS3BucketForConfiguration which checks whether the bucket exists already or not. This could be useful for reconnaissance, and identifying whether an account has AWS Config enabled.

Config is not impacted by the reported concern due to additional backend checks that are performed to validate ownership and protect against bucket squatting.

Statement by AWS

Conclusion

Amazon S3 serves as the backbone of many AWS services. Ensure that other AWS services check that the default bucket about to be created is owned by the account you’re operating. Even better start with the creating an S3 Bucket, its resource policy, and then work your way backwards to make the service operate against your policy.

The ways in which we interact with a service, e.g. via web console, API, or otherwise, makes all the difference in the world in their secure defaults, and where we operate in the share responsibility model.