Critical AWS CDK Vulnerability: Understanding the Impact and Resolution

November 26, 2024
Insights

A critical AWS CDK vulnerability was found by researchers Itach and Kadkoda from the Aqua team. The flaw was serious - letting attackers potentially take over AWS accounts as admins if certain conditions lined up. This meant they could access everything in the compromised account. AWS jumped on fixing it after the June 27 report came in. By July, they’d rolled out CDK version 2.149.0 with a patch. Anyone using CDK should grab this update ASAP to stay safe.

Understanding AWS CDK

Cloud tools have come a long way since the early days. When AWS first started, everyone just clicked around in their web console to set things up. Sure, it worked fine for small projects, but it got messy fast. You couldn’t really trust that things would stay consistent - a huge problem when you’re running real applications, as projects grow, manual resource management becomes too complicated and error-prone

That’s why AWS built CloudFormation. Finally, teams could write their infrastructure setup in JSON or YAML files instead of pointing and clicking. This meant you could track changes and automate things. But CloudFormation isn’t perfect, it comes with its own set of problems: verbose syntax, difficult to learn and, most importantly, a lack of modern development tools such as type checking.

Click to enlarge

Here’s how AWS CDK changed the game: it lets devs build cloud setups using languages they already know, like Python, TypeScript or Java. Instead of learning new tools, teams can stick to what works.

CDK treats infrastructure like regular code - you can reuse parts, write tests, and catch errors before they hit production. Plus, all the usual programming tools work: type checking, debugging, the whole deal. It’s like bringing the best parts of software development into infrastructure work.

Click to enlarge

CDK core components

The fundamental building blocks are called constructs, and they are arranged in three different levels. Layer 1 (L1) constructs integrate directly with CloudFormation, offering full control to developers but requiring meticulous setup. Layer 2 (L2) constructs simplify this process by incorporating AWS best practices and predefined configurations, enabling faster creation of standard cloud infrastructure. At the highest level, Layer 3 (L3) constructs provide maximum abstraction, allowing developers to deploy intricate solutions, such as complete web applications, with minimal effort.

These constructs are grouped into stacks, which serve as self-contained units of deployable infrastructure. A stack typically includes all the resources needed for a specific component of an application, such as a database layer or user interface. Stacks can be deployed independently or as part of a larger system and are designed to reference one another, enabling a modular structure that simplifies managing complex systems while maintaining clear boundaries between components.

When deploying, the CDK automates the intricate aspects of resource provisioning and asset management. It handles tasks like uploading Lambda functions or website assets to S3, setting up and configuring AWS services as defined in your code, and ensuring all dependencies are resolved so that resources are created in the proper sequence and connected seamlessly.

Understanding AWS

Before any deployment, CDK requires a preliminary step called bootstrapping. This single step, initiated by the cdk bootstrap command, prepares the AWS environment by creating the essential resources: an S3 storage space to store deployment assets, IAM roles to manage authorizations, in particular the CloudFormationExecutionRole, which has administrator rights by default.

Bootstrapping environment aws://[redacted]/eu-central-1...
Trusted accounts for deployment: (none)
Trusted accounts for lookup: (none)
Using default execution policy of 'arn:aws:iam::aws:policy/AdministratorAccess'. Pass '--cloudformation-execution-policies' to customize.
CDKToolkit: creating CloudFormation changeset...
[-------redacted*****************************************] (8/12)

Resources created by AWS CDK follow a precise and predictable naming format:

cdk-{Qualifier}-{Description}-{Account-ID}-{Region}

cdk-hnb659fds-cfn-exec-role-123456789012-us-east-1
    │         │             │           │
    │         │             │           └─ AWS REGION
    │         │             └─ AWS ACCOUNT ID
    │         └─ RESOURCE DESCRIPTION
    └─ Qualifier (default to "hnb659fds" )

1. Qualifier   : "hnb659fds" (default to "hnb659fds" )
2. Description : "cfn-exec-role", "file-publishing-role", 
3. Account-ID  : AWS account id  (12 digits)
4. Region      : AWS region (ex: us-east-1)

AWS CDK uses a standardized naming convention for the resources it creates.

This naming predictability is a key element in the AWS CDK vulnerability discovered, hence the importance of using a custom qualifier.

The vulnerability arises from two primary issues: the predictable naming structure of resources created by the CDK and the default administrative privileges assigned to the CloudFormation execution role. If an attacker obtains an organization’s AWS account ID and region, they could potentially exploit these predictable patterns to gain access to the highly privileged CloudFormation execution role. To mitigate this risk, AWS strongly advises configuring custom qualifiers during the bootstrapping process, which enhances security by introducing additional uniqueness.

cdk bootstrap --qualifier mynqualif

S3 staging bucket

CDK bootstrap creates an S3 bucket that acts as a staging area for your deployments. When you develop with CDK, the process happens in two steps. First, CDK synthesizes your code into the cdk.out folder, generating CloudFormation templates and other necessary resources. Then, during deployment, these files are automatically transferred to the bootstrap S3 bucket, allowing CloudFormation to access them to create your infrastructure.

This mechanism is fundamental because CloudFormation cannot directly use your local files. The S3 bucket serves as an essential intermediary, storing all deployment artifacts in a centralized and secure manner. This approach notably allows handling large deployments that would exceed CloudFormation’s standard limits.

The staging bucket follows this naming pattern:

// Format of the staging bucket name:
cdk-{qualifier}-assets-{account-ID}-{Region}// Example with default values:
cdk-hnb659fds-assets-123456789012-us-east-1│   │          │      │            │
│   │          │      │            └── AWS Region (predictable)│   │          │      
└── Account ID (known)│   │          └── Constant ("assets")│   └── Default qualifier
└── Constant prefix

Click to enlarge

Predictability of CDK Buckets: A Major Security Flaw

To guess the name of an organization’s CDK staging bucket, an attacker only needs two pieces of information:

This predictability is compounded by two factors:

The concept of global uniqueness for S3 buckets means that a bucket name must be unique across all AWS accounts worldwide, not just within one account or region.

For example, if a bucket named my-super-bucket already exists in the AWS account of a company in Australia, no other AWS user anywhere in the world will be able to create a bucket with this same name. It is this global uniqueness constraint that makes the “Bucket Namesquatting” attack possible: an attacker can create a bucket with the predictable name of an organization’s CDK staging (cdk-hnb659fds-assets-VICTIM_ACCOUNT-REGION), even if it’s in a different AWS account.

Real-world scenario

Partial denial-of-service (DoS) attacks

Consider the following situation: a business wants to use AWS CDK to administer its cloud infrastructure. With just its AWS account ID, an attacker can plan a preemptive strike before it even launches its initial deployment. The attacker uses the default naming scheme cdk-hnb659fds-assets-{VICTIM_ID}-{REGION} to establish S3 buckets in various AWS regions beforehand, taking advantage of the name predictability of CDK staging buckets. The “legitimate” buckets are already in place but are under the attacker’s control, so when the company’s DevOps team later performs their first CDK bootstrap, the operation fails. The company’s first deployment procedure is disrupted as a result of having to employ a custom qualifier. this attack may appear harmless because it is easily evaded, but it is a prime illustration of how S3 buckets’ global uniqueness and name predictability can be used to interfere with or even damage CDK deployments.

const victimAccountId = '123456789012';

const regions = [
  'us-east-1',
  'eu-west-1',
  'ap-southeast-1',
  // ... all AWS regions
];

async function deployPreventiveAttack() {
  for (const region of regions) {
    const bucketName = `cdk-hnb659fds-assets-${victimeAccountId}-${region}`;
    await createAWSBucket(bucketName);
  }
}

CDK Account Takeover: A Critical Attack Scenario

The attack’s mechanism An especially risky scenario is created when an attacker takes over an organization’s CDK staging bucket. As the source and destination of CloudFormation templates and other vital resources, this bucket is in fact more than simply a place to store data; it is the central component of the CDK deployment process.

What makes it so risky? The staging bucket’s dual purpose is the source of the risk:

A crucial element of this vulnerability is the CloudFormationExecutionRole role. By default, this role has full administrator privileges on the AWS account. This configuration, while convenient for deployment, becomes a formidable attack vector when the staging bucket is compromised.

AWS CDK Vulnerability Attack Methodology

Let’s imagine a user who has correctly initialized AWS CDK via the bootstrap process, creating all the necessary roles, the staging S3 bucket and other resources. For various reasons, including the S3 quota limit (100 buckets per AWS account by default), this user decides to delete the CDK staging bucket.

This deletion creates an exploitable vulnerability. Since the name of the staging bucket follows a predictable format, an attacker can create a new bucket with the same name and wait for the victim to use CDK again, particularly during a CDK deploy. The danger lies in the fact that all CDK roles and resources created during the initial bootstrap remain in place in the victim’s account. CDK will then trust the bucket controlled by the attacker and write its CloudFormation templates to it.

The attacker must prepare two essential elements:

1. Reserve the bucket with the predictable name of the victim, by configuring :

2. Set up a Lambda function that :

Attack sequence

  1. The victim has initially bootstrapped CDK, creating the necessary roles and staging bucket.
  2. The staging bucket is deleted, freeing the name
  3. The attacker creates a malicious bucket with this name
  4. Victim runs cdk deploy
  5. CDK process sends templates to compromised bucket
  6. Attacker’s Lambda injects malicious admin role
  7. CloudFormation deploys the modified template with administrator privileges
  8. Attacker gains administrator access to victim’s account

Far from being a theoretical hypothesis, this vulnerability is rooted in common cloud management practices. Deleting the CDK staging bucket is a frequently observed action in AWS environments, motivated by several legitimate operational factors. DevOps teams often find themselves constrained by the limit of 100 S3 buckets per AWS account, forcing them to make difficult quota management choices. Others delete these buckets as part of initiatives to clean up unused resources or during environment reorganizations, in the mistaken belief that such deletions are of no consequence. This operational reality turns a simple maintenance action into a potential major security flaw, creating an exploitable attack vector in many organizations.

Contact us to better protect yourself from vulnerabilities like these - before they're ever created in the first place.

About the author
Koceila Lounas
Front-End Developer
Icon line
See all articles

Book a demo

See how our solution empowers teams to grow their security maturity and to code securely & efficiently.
Icon line
Book a demo
Demo illustration