Archive for category AWS

Ahh-My-API : Discover publically exposed APIs in AWS


The REST API gateways created in AWS have a default endpoint [https://{api_id}.execute-api.{region}] and If not explicitly secured, they are publically accessible from internet by default. Wrote a script which would find such APIs across all regions under all the AWS accounts in the AWS organizations and takes screenshot their webpage for evidence. It will also generate a CSV file which may be ingested by a SIEM such as Splunk for alerting and remediation.

The script when executed will produce a CSV file in the below format showing all the API URLs and which one could be publically accessible and which security setting are applied on the API if API is not accessible.

It is important to discover and actually test the endpoints from an external environment to reduce the false positives for detection becuase APIs can be secured by various means (described below)

Most common ways to secure AWS Rest APIs

  • API Token e.g. Check for specific token value in the pre-defined x-api-header.
  • Lambda Authorizers e.g. Custom lamda code to check for specific headers/secrets before allowing access.
  • Resource policies e.g. Allow access from certain IP addresses and deny others.
  • Authentication/Authorization from with in the backend code (e.g. Lambda).

How to use the script

We follow below two steps :

  • Set up an IAM user with approperiate permissions in the management account to assume a given role in the other accounts.
  • Set up the role to assume in all the workload accounts using CloudFormation and StackSets.

The script makes use of Access Key on the IAM user “boto3user” in the management account.
boto3user has the permission to assume role in the workload account and get temporary credentials to access the API gateways in the workload accounts. Diagram below :

In my AWS organizations, I have 3 AWS accounts out of which “Account 1” is the management account.

Setting up the IAM user and permissions in the management account

Create a IAM user named boto3user.

Create an access key and secret for the IAM user.

Create a policy with below and assosciate it with the IAM user.


This allows the user to assume the role named ScanAWSAPIRole in all the AWS accounts in the AWS organization.
Since the script will iterate through the AWS organizations as well, we provide the ListAccounts and DescribeAccount permission as well.

    "Version": "2012-10-17",
    "Statement": [
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
            "Resource": "*"
            "Sid": "VisualEditor1",
            "Effect": "Allow",
            "Action": "sts:AssumeRole",
            "Resource": "arn:aws:iam::*:role/ReadOnlyAPIGatewayAssumeRole"

Create the role to assume in the other accounts

We will use a CloudFormation template for the role to be created and Stackset to deploy the template across all the AWS accounts in the AWS organization.

  1. Download the CloudFormation template from here and save it locally :
  2. On the management account, navigate to CloudFormation > StackSets > Create StackSet

3. In the “Specify template” section, choose “Upload a template file” and browse to select the previously saved CloudFormation template

4. Specify a name for the StackSet and optional description.

5. In the deployment options screen, set the deployment target as “Deploy to Organization”
and specify US East as the region.

6. In the review screen, acknowledge and submit.

StackSet has been deployed with success.

Verify the role has been created across all the accounts

We can see the role “ReadOnlyAPIgatewayAssumeRole” has been created in the AWS accounts.
The “Trusted entities” is the AWS Account number of the management account which is trusted to assume the “ReadOnlyAPIgatewayAssumeRole” role.

If we look at the role, we see the Policy named “ReadOnlyAPIGatewayPolicy” is attached to it with GET/HEAD operations on apigateway just like we specified in the CloudFormation template.

when we look at the “Trusted Entities”, we notice the IAM user named “boto3user” in the management account.
This means It is this user which has the permission to assume the “ReadOnlyAPIgatewayAssumeRole” role in all the AWS accounts and call the API gateway GET/HEAD operation.

Running the script

Setup the AWS credentials

aws configure

Clone the git repo

Install all the requirements

pip install -r requirements

Run the script

python .\


Leave a comment

Random Thoughts

The World as I see it

Simple Programmer

Making The Complex Simple

Ionic Solutions

Random thoughts on software construction, design patterns and optimization.

Long (Way) Off

A tragic's view from the cricket hinterlands