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-003 --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.spawn*() family functions: os.spawnl(), os.spawnle(), os.spawnlp(), os.spawnlpe(), os.spawnv(), os.spawnve(), os.spawnvp(), and os.spawnvpe().
Lambda functions receive input from the event dictionary populated by API Gateway, SQS, SNS, S3, DynamoDB Streams, and other AWS triggers. Fields such as event.get("body"), event.get("queryStringParameters"), and event["Records"] are fully attacker-controllable in public-facing deployments. There is no sanitization layer between the raw event payload and application code.
The os.spawn*() family is a lower-level process spawning API that predates the subprocess module. Variants ending in 'p' (spawnlp, spawnvp) search PATH for the executable, making them susceptible to PATH manipulation attacks when combined with user-controlled executable names. The 'l' variants take arguments as individual strings; when any argument position contains attacker-controlled event data, the attacker controls a process argument. In Lambda, successful exploitation yields access to the execution role's AWS credentials stored in environment variables, enabling further attacks against the broader AWS environment.
Security Implications
Potential attack scenarios if this vulnerability is exploited
Direct Process Spawning with Attacker-Controlled Arguments
os.spawn*() spawns a new process directly. When event data controls argument positions, an attacker can influence the behavior of the spawned process. Argument injection remains possible if the target binary interprets attacker-controlled flags as commands (e.g., passing '-e cmd' to certain binaries).
PATH Manipulation via spawnlp/spawnvp Variants
The 'p' variants (spawnlp, spawnvp, spawnlpe, spawnvpe) search the PATH environment variable for the executable. If an attacker can control the executable name argument and the PATH contains writable directories, the spawn can be redirected to an attacker-controlled binary in /tmp.
AWS Credential Exfiltration
Spawned processes in the Lambda environment inherit the parent's environment variables, including AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, and AWS_SESSION_TOKEN. An attacker who controls process arguments can spawn a process that reads and exfiltrates these credentials via the network.
Execution Environment Reconnaissance
Injected arguments can cause spawned processes to list filesystem contents, read configuration files, or probe the network. Lambda execution environments contain deployed code, environment variables with secrets, and /tmp data that can be enumerated and exfiltrated through injected process arguments.
How to Fix
Recommended remediation steps
- 1Replace all os.spawn*() calls with subprocess.run() using a list of arguments and shell=False to use the modern, well-documented safe API.
- 2When using spawn variants that search PATH ('p' variants), always pass the full absolute path to the executable instead of relying on PATH lookup.
- 3Validate all event fields with strict allowlists or regular expressions before they appear in any argument position of a spawn or subprocess call.
- 4Apply least-privilege IAM policies to the Lambda execution role to minimize the scope of credential exfiltration if injection occurs.
- 5Monitor Lambda CloudWatch logs for unexpected process output or error 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__"), including event.get("body"), event.get("queryStringParameters"), event.get("pathParameters"), and event["Records"]. Sinks are calls("os.spawnl"), calls("os.spawnle"), calls("os.spawnlp"), calls("os.spawnlpe"), calls("os.spawnv"), calls("os.spawnve"), calls("os.spawnvp"), and calls("os.spawnvpe") with tainted values tracked via .tracks(0) for the executable argument and additional argument positions. The analysis follows taint through variable assignments, list construction, and function 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 os.system()
Lambda event data flows to os.system(), enabling arbitrary OS command execution inside the Lambda execution environment.
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 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.spawn*()
New feature
Get these findings posted directly on your GitHub pull requests
The Lambda Command Injection via os.spawn*() rule runs in CI and posts inline review comments on the exact lines — no dashboard, no SARIF viewer.