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-005 --project .About This Rule
Understanding the vulnerability and how it is detected
This rule detects command injection vulnerabilities in AWS Lambda functions where untrusted event data flows into asyncio.create_subprocess_exec() calls within async Lambda handlers.
asyncio.create_subprocess_exec() does not invoke a shell and passes arguments directly to the process via execve(), making it the safer async subprocess API. However, it is still vulnerable to argument injection when event data controls the executable path (first argument) or argument values that the target binary interprets as flags or commands. Classic examples include passing attacker-controlled strings as filenames to tools like rsync, wget, or curl that interpret certain argument patterns as additional operations.
Lambda functions receive input from the event dictionary populated by API Gateway, SQS, SNS, S3, DynamoDB Streams, and other triggers. Fields such as event.get("body"), event.get("queryStringParameters"), and event["Records"] are fully attacker- controllable in public-facing deployments.
While the shell injection risk is reduced compared to create_subprocess_shell(), the risk of argument injection and executable path manipulation remains when event data is used in any argument position without validation.
Security Implications
Potential attack scenarios if this vulnerability is exploited
Executable Path Hijacking
If event data controls the first argument (the executable path) of create_subprocess_exec(), an attacker can point the execution to any binary accessible in the Lambda filesystem, including user-written scripts in /tmp. Always use hardcoded, absolute executable paths from an allowlist.
Argument Injection via Flag-Like Values
Many command-line tools interpret arguments beginning with '-' as flags. If event data is passed as an argument without the '--' separator, values like '--exec', '--output', or '-rf' may activate unintended behaviors in the target binary. Prefix user-provided arguments with '--' when the target tool supports it.
AWS Credential Access via Argument Injection
Argument injection can cause tools like curl, wget, or rsync to write output files, follow redirects, or establish connections in ways that expose the Lambda execution environment's AWS credentials stored in environment variables.
/tmp Exfiltration and Modification
Argument injection into file processing tools can redirect output to attacker- controlled destinations, read arbitrary /tmp files, or overwrite Lambda deployment package files if /tmp is used for code storage.
How to Fix
Recommended remediation steps
- 1Validate the executable argument against a hardcoded allowlist of absolute paths; never derive the executable from event data.
- 2Prefix user-controlled filename arguments with '--' to prevent the target binary from interpreting them as flags.
- 3Validate all event fields with strict allowlists or regular expressions before they appear in any argument position.
- 4Apply least-privilege IAM policies to the Lambda execution role to minimize the AWS APIs accessible if exploitation occurs.
- 5Prefer native Python libraries over subprocess calls wherever possible to eliminate the subprocess attack surface.
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"]. The sink is calls("asyncio.create_subprocess_exec") with tainted values tracked via .tracks(0) for the executable argument and additional argument positions. The analysis follows taint through async function calls, await expressions, list construction, and 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 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 os.spawn*()
Lambda event data flows to os.spawn*() functions, enabling process execution with attacker-controlled arguments in the Lambda execution environment.
Frequently Asked Questions
Common questions about Lambda Command Injection via asyncio.create_subprocess_exec()
New feature
Get these findings posted directly on your GitHub pull requests
The Lambda Command Injection via asyncio.create_subprocess_exec() rule runs in CI and posts inline review comments on the exact lines — no dashboard, no SARIF viewer.