# Unauthenticated AWS API Gateway + Over-Permissioned Lambda: Credential Extraction Attack Chain

> GuidePoint Security's Threat and Attack Simulation (TAS) team demonstrated a repeatable AWS serverless attack chain: an API Gateway method left at the default authorizationType NONE fronts a Lambda function that passes unsanitized user input into Python's eval(), letting an attacker with no AWS credentials enumerate the API, pull the Lambda's source, inject a payload to read process environment variables, and exfiltrate the function's temporary IAM execution-role credentials (AWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEY/AWS_SESSION_TOKEN) via the HTTP response. Because the demo execution role was over-permissioned with secretsmanager:GetSecretValue, the stolen credentials were then used to pull database secrets from AWS Secrets Manager.

- **Published:** 2026-09-21T00:00:00Z
- **Last reviewed:** 2026-09-21T00:00:00Z
- **Canonical:** https://intel.threadlinqs.com/threat/TL-2026-2601
- **ID:** TL-2026-2601
- **Severity:** HIGH
- **Category:** CLOUD
- **Status:** ACTIVE
- **Detections:** 9 · **IOCs:** 11 (full data via the Threadlinqs MCP server — Purple tier)

## Description

GuidePoint Security's TAS team built an intentionally vulnerable AWS lab (API Gateway REST API 7793fgpqri, region us-east-1, stage prod, fronting three Lambda functions) to walk through, end to end, how a single unauthenticated HTTP request to a misconfigured serverless stack escalates into IAM credential theft and secrets exposure. Amazon API Gateway leaves a method unauthenticated (authorizationType: NONE) unless an authorizer -- AWS_IAM, a Lambda authorizer, or an Amazon Cognito user pool -- is explicitly attached to it; because that authorization has to be configured per method rather than enforced by an account-wide policy, it is easy for a method to ship without it. Enumerating the lab API's resources and methods (aws apigateway get-method, checking authorizationType/apiKeyRequired per resource) found all three backing Lambda functions -- vuln-lab-get-user-data, vuln-lab-process-report, and vuln-lab-search-records -- exposed at the default NONE with no API key required. Deep analysis focused on vuln-lab-get-user-data, whose deployment package (retrieved via the pre-signed S3 URL returned by aws lambda get-function's Code.Location field) showed request input passed straight into Python's eval() (result = eval(user_input)), a textbook CWE-95 eval-injection sink.

The walkthrough runs in ten stages: (1) enumerate the account's deployed REST APIs (aws apigateway get-rest-apis), (2) enumerate each API's stages (aws apigateway get-stages), (3) enumerate resources and check each method's authorizationType (aws apigateway get-resources / get-method) to find all three endpoints left at NONE, (4) retrieve the vulnerable Lambda's deployment package via its pre-signed Code.Location URL to read its source, (5) analyze that source for the eval() injection point, (6) craft and send three separate GET requests -- each with a --data-urlencode "user=__import__('os').environ['<VAR>']" payload -- through the unauthenticated endpoint into the eval() call, one per targeted environment variable, (7) recover the temporary AWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEY/AWS_SESSION_TOKEN that Lambda auto-injects for every execution role from the three HTTP responses, (8) export the recovered values as local environment variables to adopt the stolen identity, (9) confirm the resulting identity and permissions via aws sts get-caller-identity, and (10) use those credentials to call aws secretsmanager get-secret-value (secret ID vuln-lab/database/master) and retrieve database/application secrets -- possible only because the demo execution role (vuln-lab-lambda-execution-role) had been granted secretsmanager:GetSecretValue well beyond what the function itself needed. GuidePoint further notes that if the execution role also carried iam:PassRole plus lambda:CreateFunction/UpdateFunctionConfiguration/UpdateFunctionCode, the same stolen credentials could pivot into persistence or broader privilege escalation.

No CVE applies: this is a misconfiguration- and design-pattern-driven technique, not a single-product vulnerability, and GuidePoint states the underlying defaults and misconfigurations 'exist across production environments right now' based on their client assessments -- though the walkthrough itself was run purely against their own lab environment (the API ID, function names, and secret path above are that lab's illustrative identifiers, not live production infrastructure), with no claim of in-the-wild exploitation. The chain is entirely enabled by two independent, individually common misconfigurations (an unauthenticated method, and an over-permissioned execution role) stacking on top of unsafe dynamic code execution; removing any one of the three breaks the chain, and the discovery of three separate exposed functions behind one API underscores that the misconfiguration tends to recur across an account's endpoints rather than appear once. GuidePoint's own recommendations are to require authentication on every API Gateway endpoint that doesn't need to be public, never pass user-supplied input into eval()/exec(), and scope every Lambda execution role to least privilege.

## MITRE ATT&CK

- T1595.002 Vulnerability Scanning
- T1190 Exploit Public-Facing Application
- T1059.006 Python
- T1059.009 Cloud API
- T1526 Cloud Service Discovery
- T1580 Cloud Infrastructure Discovery
- T1087.004 Cloud Account
- T1552 Unsecured Credentials
- T1528 Steal Application Access Token
- T1078.004 Cloud Accounts

## Sources

- [Serverless, Not Riskless: Exploiting Unauthenticated API Gateways in AWS](https://www.guidepointsecurity.com/blog/serverless-not-riskless-exploiting-unauthenticated-api-gateways-in-aws/)
- [Serverless, Not Riskless: Exploiting Unauthenticated API Gateways in AWS (mirror)](https://securityboulevard.com/2026/09/serverless-not-riskless-exploiting-unauthenticated-api-gateways-in-aws/)
- [Control and manage access to REST APIs in API Gateway](https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-control-access-to-api.html)
- [Working with AWS Lambda environment variables](https://docs.aws.amazon.com/lambda/latest/dg/configuration-envvars.html)
- [GuardDuty IAM finding types (incl. UnauthorizedAccess:IAMUser/ResourceCredentialExfiltration.OutsideAWS)](https://docs.aws.amazon.com/guardduty/latest/ug/guardduty_finding-types-iam.html)
- [Use temporary credentials with AWS resources](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_use-resources.html)
- [CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code ('Eval Injection')](https://cwe.mitre.org/data/definitions/95.html)
- [CWE-250: Execution with Unnecessary Privileges](https://cwe.mitre.org/data/definitions/250.html)
- [CWE-276: Incorrect Default Permissions](https://cwe.mitre.org/data/definitions/276.html)

## Full data

Detection queries (Splunk SPL / Microsoft KQL / Sigma) and IOC values require the Threadlinqs MCP server (Purple tier): https://intel.threadlinqs.com/mcp

Canonical: https://intel.threadlinqs.com/threat/TL-2026-2601
