AWS CDK Risk: Exploiting a Missing S3 Bucket Allowed Account Takeover
In June 2024, we uncovered a security issue related to the AWS Cloud Development Kit (CDK), an open-source project. This discovery adds to the six other vulnerabilities we discovered within AWS services. The impact of this issue could, in certain scenarios (outlined in the blog), allow an attacker to gain administrative access to a target AWS account, resulting in a full account takeover.
Our research, covering over 38,000 well-known account IDs, identified several cases where AWS CDK users were susceptible to this attack vector due to the manual deletion of their deployment artifact S3 bucket(s). AWS later confirmed that approximately 1% of CDK users were susceptible to this security issue.
This blog post expands on the findings from our previous research, “Bucket Monopoly”, and examines how the techniques from our previous research are applicable to open-source projects.
We reported this security issue to AWS, and they promptly addressed it by ensuring that assets are only uploaded to buckets within the user’s account.
However, user action is required if you’ve used CDK version v2.148.1 or earlier.
For detailed mitigation steps, please refer to the Mitigation section of this blog.
AWS directly notified potentially affected customers and added messages to the CLI terminal, alerting users to upgrade their bootstrap resources.
We appreciate AWS security team’s collaboration on this matter.
Disclosure timeline:
Infrastructure as Code (IaC) is a way to manage and provision computing infrastructure by using code instead of manually configuring physical hardware. This approach allows you to define essential infrastructure components, such as servers, databases, and networks through machine-readable files.
The AWS Cloud Development Kit (CDK) is a framework that empowers developers to define cloud infrastructure using familiar programming languages like Python, TypeScript, or JavaScript. CDK translates this code into configurations that AWS, can interpret and deploy efficiently.
In other words, AWS CDK makes building and managing cloud infrastructure more intuitive by letting you write it in the same programming languages you use for your applications. This means you can create, customize, and deploy your cloud resources all from your codebase.
In our previous blog, we labeled the term shadow resources, which are resources that are created by service/application and the user is unaware of them. In this instance, AWS CDK users are made aware of the default resources created during the bootstrapping process.
To use the AWS Cloud Development Kit (AWS CDK), users need to bootstrap their environment to prepare it for CDK stack deployments.
This is done using the cdk bootstrap command.
When bootstrapping the CDK, it deploys a CloudFormation template file that automatically creates essential infrastructure components, including IAM roles, policies, an S3 bucket, and more – all of which are used by the CDK during deployments.
This one-time setup ensures that your CDK applications have the necessary permissions and resources to function properly.
For example, the bootstrapping process creates several IAM roles, including:
Additional IAM roles are created during the bootstrap process, which you can explore in more detail here.
The naming pattern of resources created by AWS CDK follows the following structure: cdk-{Qualifier}-{Description}-{Account-ID}-{Region}
hnb659fds. However, users can customize this value by specifying a qualifier during the bootstrapping process. For example: cdk bootstrap --qualifier abcde0123 cfn-exec-role for the CloudFormationExecutionRole, or file-publishing-role for the FilePublishingRole. For instance, if your AWS account ID is 123456789012, your current region is us-east-1, and you used the default CDK bootstrap command (meaning the qualifier for your resources will be hnb659fds), the physical ID of the CloudFormationExecutionRole IAM role would be: cdk-hnb659fds-cfn-exec-role-123456789012-us-east-1.
During the CDK bootstrap process, AWS CDK creates a staging S3 bucket to store deployment assets, such as CloudFormation templates and other resources. These assets are first generated and saved locally in the cdk.out directory, after which they are uploaded to the S3 staging bucket for use during the deployment process. This ensures that CloudFormation has access to the necessary resources for stack deployment.
The staging bucket follows this naming pattern: cdk-{qualifier}-assets-{account-ID}-{Region}.
Since many users run the cdk bootstrap command without customizing the qualifier, the S3 bucket naming pattern of the staging bucket becomes predictable. This is because the default value for the bucket name qualifier is set to hnb659fds, making it easier to anticipate the bucket’s name.
As a result, predicting someone else’s CDK staging bucket name only requires knowing their AWS Account-ID and the Region where the CDK was deployed.
Since the Prefix is always cdk, the Qualifier is by default hnb659fds, and assets is a constant string in the bucket name, the only variables that change are the Account ID and the Region.
A quick GitHub search reveals thousands of instances where users have used the default qualifier in the bootstrap process to set up their environments.
Since the bucket name is predictable when a user using the default CDK bootstrap command, and S3 bucket names are globally unique across all AWS accounts, it is possible for an attacker to perform “S3 Bucket Namesquatting” or “Bucket Sniping”.
This allows the attacker to claim another user’s CDK staging S3 bucket if it does not already exist.
If a user hasn’t yet used AWS CDK, an attacker could exploit this by creating the staging S3 bucket that the CDK bootstrap process would attempt to generate.
The only information the attacker needs is the target’s account ID.
With that, the attacker can create the staging S3 bucket for the CDK across all AWS regions, as the region name forms part of the staging bucket’s name.
Furthermore, it’s common for users not to set a custom qualifier, so the default qualifier hnb659fds is often used by the CDK bootstrap process, making the bucket name predictable.
If the attacker sets up the bucket ahead of time, when the user later tries to bootstrap the CDK from a specific region, they will encounter an error during the process because the CDK bucket that the bootstrap process attempts to create already exists. The documentation advises selecting a non-default qualifier.
The CDK bootstrap process of the target account fails with an error because the S3 bucket has already been claimed by an attacker
This creates a partial “DoS” scenario, which the victim can easily resolve by simply modifying the qualifier to successfully complete the bootstrap process.
If there is a scenario where the victim’s CDK both writes and reads data, such as a CloudFormation template, to and from an attacker-controlled staging S3 bucket, the security implications would be severe.
This could allow the attacker to manipulate the data and execute malicious actions within the victim’s AWS account.
As a reminder, the CDK staging bucket contains CloudFormation templates. If an attacker gains access to the CDK staging bucket of other users, these files can be easily tampered with and backdoored, enabling the injection of malicious resources into the victim’s account during deployment. For example, the attacker could add an admin role that they could later assume.
As mentioned earlier, the deploy role of the CloudFormation service, which is the role CloudFormationExecutionRole in CDK has administrative privileges within the account by default. This means that any CloudFormation template written to the attacker’s S3 bucket by the victim’s CDK would be deployed later with administrative privileges in the victim’s account. This would allow the attacker to create privileged resources.
During our research, we discovered a scenario where users were susceptible to this exact attack vector.
In this scenario, the user had previously used AWS CDK and initiated the CDK bootstrap process, which set up all necessary roles, a staging CDK S3 bucket, and other resources. However, at some point, the user deleted the CDK staging S3 bucket.
Why does this happen? S3 buckets have quota limits – by default, you can create up to 100 buckets per AWS account. While users can request a quota increase, they sometimes delete buckets to free up space or resources. As we’ll explore later, we’ve found cases where users bootstrapped CDK in the past but subsequently deleted the related S3 staging bucket for various reasons.
When this occurs, an attacker can exploit this situation. Since the name of the CDK staging bucket is predictable, the attacker can create a new bucket with the same name and wait for the victim to use CDK again, particularly during a cdk deploy.
Since all the necessary roles and resources for CDK were already set up during the previous bootstrap process in the victim’s account, CDK will trust the attacker-controlled bucket and proceed to read and write CloudFormation templates to it. This allows the attacker to manipulate the deployment process and inject malicious resources into the victim’s account.
Before we dive into the attack workflow, the attacker needs to complete the following steps:
Now we can describe the attack and how we can achieve admin role access on a targeted victim’s account:
cdk bootstrap command. This process sets up essential roles, such as the admin and publish roles, and creates an S3 bucket to store assets for CDK, using the naming convention: cdk-{qualifier}-assets-{account_id}-{region}. cdk deploy. CloudFormationExecutionRole) already exist in the victim’s account and the S3 bucket (now in the attacker’s control) also exist, the victim CDK deploy process sends the CloudFormation template file to the attacker’s S3 bucket. Essentially, we were able to create an admin role in a target account if someone deletes the CDK staging S3 bucket that was created during the bootstrap process and then tries to use CDK again.
However, we should consider the likelihood of someone deleting the CDK S3 bucket after it has been bootstrapped. To assess this, we can enumerate the instances and identify how many users might be exposed to this attack vector.
To evaluate whether this scenario is realistic, we can first check if AWS accounts have previously used CDK by looking for roles created during the CDK bootstrap process. Then, we can determine if the associated CDK staging S3 bucket has been deleted.
Since AWS CDK resources follow a predictable naming pattern – cdk-{Qualifier}-{Description}-{Account-ID}-{Region} – We can focus on roles such as CloudFormationExecutionRole, which is identified by the description cfn-exec-role.
Regarding the qualifier field in the resource name, as previously mentioned, most users are likely to use the default hnb659fds qualifier instead of customizing it.
We developed a scanner to perform this task, which operates as follows: We started with a list of 38,000 well-known account IDs. For each account ID, we scanned three popular regions: us-east-1, us-west-2, and eu-west-1.
First, we checked whether CDK had been used in each account by looking for the existence of one of the CDK roles—CloudFormationExecutionRole (cdk-hnb659fds-cfn-exec-role-<Account_ID>-<Region>) – using the AWS AssumeRole Enumeration Script.
Then, we checked if the associated CDK staging S3 bucket (cdk-{qualifier}-assets-{Account_ID}-{Region}) existed or not.
If the CDK staging bucket is missing but the CDK roles still exist in a specific account and region, the account is considered vulnerable to this technique. An attacker could create the missing staging bucket and wait for the victim to use cdk deploy, causing the CloudFormation template to be written to the attacker’s S3 bucket, which the victim’s CDK and CloudFormation services would then read from and write to, enabling the attacker to exploit this attack vector.
Out of 38,560 accounts analysed, we identified 782 (2%) that had CDK installed. Among those, 81 accounts (10%) were found to be vulnerable to this attack vector. Additionally, we discovered 100+ vulnerable staging buckets, with some accounts having multiple buckets across different regions, indicating that CDK had been bootstrapped in multiple regions.
Following our report, AWS confirmed that approximately 1% of CDK users were impacted.
After we reported this security issue to AWS, they released several fixes:
hnb659fds. While the AWS patch resolves the issue for new CDK users, it only applies to new bootstraps.
This means users who bootstrapped with an older version, such as CDK v2.148.1 (July 11, 2024) or earlier, will remain susceptible, even if they update their CDK.
AWS added messages to the CLI terminal, alerting users to upgrade their bootstrap resources and directly notified potentially affected customers.
To mitigate this risk, user action is required:
cdk bootstrap command. cdk-${Qualifier}-file-publishing-role-${AWS::AccountId}-${AWS::Region}, similar to the AWS patch. This blog expands on our recent research, Bucket Monopoly, and reinforces key security best practices that we believe cloud admins should adopt: