AWS Cognito Security — Overview

Incognito person walking through the dense amazon forest.

This series of blog posts presents the results of our research into hacking Amazon Cognito applications. The base research was initially presented at OhMyHack International 2021 in the form of a talk. However, this series includes new attack vectors and misconfigurations previously unknown to the security community. Together, we will dive deep into AWS Cognito structure, its underlying components, and use cases, identifying potential security pitfalls and gotchas.

In this first post, we will give you a detailed introduction to the components of Cognito, explaining basic authentication flows and concepts. Here is what awaits you:

  1. AWS Cognito Security - Overview

  2. Cognito User Pool - Introduction & Attributes

  3. Cognito User Pool - Shared User Pools

  4. Cognito Identity Pool - Introduction

  5. Cognito Identity Pool - Rule-Based Role Resolution

  6. Cognito Identity Pool - Misconfigured IAM Roles

  7. AWS Cognito - Dangerous IAM Permissions

We also provide a vulnerable application called Octopus Storage. It is a practical demo we built with Cognito that can be used as a playground to master the vulnerabilities discussed in this series.

Why Amazon Cognito

Cognito is a service for implementing customer identity and access management (CIAM) into web and mobile applications. It provides developers with an authentication, authorization, and accounting (AAA) system, provided they can configure it securely.  However, based on our experience as security consultants, this task can be challenging, and modern web applications routinely suffer from high-severity vulnerabilities and misconfigurations in such systems. This is why we chose Cognito as our research target.

Credentials and authentication methods - User Pools and Identity Pools

Amazon Cognito Components

We can highlight two main components in Cognito: User Pools and Identity Pools. User Pools provide managed authentication services, while Identity Pools handle authorization to cloud resources via temporary AWS credentials.

User Pools

User Pools are user directories that provide a variety of authentication and security features and options for web and mobile application users:

  • Social sign-in

  • OIDC

  • SAML

  • Custom authentication

  • Account takeover protections

  • Multi-Factor Authentication (MFA)

  • User Management

  • Phone & Email Verification

Cognito User Pools make it possible to define user attributes, such as email addresses or phone numbers. The attribute configuration may often be overlooked, and thus it can introduce some unexpected bugs that we will cover in the upcoming entries of the blog post series.

User Pools also allow developers to customize the authentication process and the supported MFA methods. With User Pools, users can sign in to web or mobile applications through Amazon Cognito directly or via third-party identity providers.

Amazon Cognito integration could be implemented in various ways, depending on the needs of the application architecture. Common use cases include:

  • Client-side authentication: application users interact directly with User Pool API (default flow)

  • Server-side authentication: an intermediate server-side application (lambda or web server) carries out the authentication process and stores a pair of valid AWS credentials

  • Custom authentication: developers can define any desired authentication flow via custom Lambda functions

After a successful authentication, the web or mobile application receives user pool tokens from Amazon Cognito (default implementation, serverless approach). You can then use those tokens to retrieve AWS credentials that enable application users to access your resources through the public cloud API.

There are two flows in Amazon Cognito that use solely User Pool for users to access AWS resources:

1. Directly by granting necessary permissions to User Pool tokens:

When an application authenticates a user to the User Pool API, it responds with a set of JWTs (User Pool tokens). For flow, it is necessary to implement your own mechanism for token validation.

You can use those tokens to control access to your server-side resources. You can also create user pool groups to manage permissions and to represent different types of users.

2. Indirectly by controlling access through API Gateway:

You can enable your users to access your API through API Gateway. API Gateway validates the tokens from a successful user pool authentication and uses them to grant your users access to resources including Lambda functions or your own API.

Processing access controls indirectly through API Gateway

Both use cases do not involve the usage of Identity Pool (no temporary AWS credentials are granted).

Identity Pools

When configured, Cognito Identity Pools allow application users to exchange User Pool tokens for temporary AWS credentials to directly access other AWS services, such as Amazon S3 or DynamoDB.

The service offers a number of configuration options for the credential-granting process. Some of these options, if misconfigured, could be exploited by an attacker who wants to obtain the credentials.

These temporary AWS credentials are associated with a specific IAM role with a developer-defined set of permissions on AWS resources.  When it comes to scoping these permissions, it is crucial to follow the least privilege principle. Otherwise, attackers may cause lasting harm to the cloud account by changing its settings to achieve persistence, extract all useful data, shutt down services, or even use the developers’ wallet to mine cryptocurrencies.

Diagram illustrating the use of OIDC, SAML, Social Network Sign-In, or custom authentication methods used via API gateway.

Default IAM roles can be configured both for authenticated and unauthenticated users. In order to be able to cover the entire attack surface of the service, it is important to understand how to enumerate the roles and permissions available to the users.

Diagram illustrating authentication to third party content providers using OIDC, SAML, Social Sign-In or custom authentication flows.

If users are authenticated through a federated service, Identity Pools can also manage them. The application can exchange their tokens for temporary AWS credentials through the AWS SDK. This type of authentication flow is displayed below:

In a future blog post, we will show how all the features above can be exploited by an attacker.

Giant octopus hanging out in a storage container.

Octopus Storage

We have developed a playground for vulnerabilities mentioned in this series called Octopus Storage. It is a cloud file hosting service built as a server-less web application using AWS Cognito for authentication. The application can be deployed in an AWS account using Terraform. Try to find vulnerabilities on your own, and check yourself when we release the rest of the articles!

Summary

AWS Cognito is a complex system that may pose a significant challenge for application developers during the setup and configuration steps. Since Cognito enables application users to have direct access to AWS infrastructure and resources, it requires a special approach and more effort in tailoring privileges for application users.

In the next parts of the series, we are going to review where security issues can arise and why, as well as what impact attackers can achieve.

Security Services

Looking for someone to validate your AWS Cognito configuration? We are always happy to assist you and your team in reviewing your existing infrastructure, as well as working closely with your developers to create a secure SDLC for your products.

Fill out our contact form to have one of our team members reach out to you to learn more about your security initiatives.

Credits

Research prepared by:

Next
Next

AWS Cognito User Pool — Shared User Pools