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-015 --project .About This Rule
Understanding the vulnerability and how it is detected
This rule detects SQL injection vulnerabilities in AWS Lambda functions where untrusted event data is used to construct a SQL query string via f-string interpolation or string concatenation, and the resulting tainted string is subsequently passed to any database execute() function.
This rule differs from driver-specific rules (SEC-010 through SEC-014) by focusing on the intermediate SQL string construction step rather than the specific database driver. It catches the pattern where a tainted SQL string is built in one variable or function and then passed to execute() in another, which may span multiple helper functions or modules in the Lambda codebase.
Lambda functions receive attacker-controllable event data from API Gateway, SQS, SNS, S3, DynamoDB Streams, and other triggers (event.get("body"), event.get("queryStringParameters"), event["Records"]). When this data is used to build SQL strings, the string becomes tainted regardless of which database driver is used to execute it. Detecting the tainted string construction step, rather than only the execute() call, catches vulnerability patterns where the string is stored in a variable, passed through helper functions, or assembled from multiple event fields before reaching the sink.
Security Implications
Potential attack scenarios if this vulnerability is exploited
Cross-Module Tainted SQL Propagation
SQL strings built from event data in one Lambda module (e.g., a query builder utility) and executed in another module are vulnerable even when the execute() call site appears to use safe patterns. This inter-module taint propagation is the primary pattern that driver-specific rules miss.
Multi-Driver Vulnerability Coverage
Lambda functions that connect to multiple databases via different drivers (e.g., PyMySQL for MySQL and psycopg2 for PostgreSQL) may construct SQL strings centrally and execute them through different drivers. A tainted SQL string passed to any driver's execute() is equally dangerous regardless of the driver.
Stored Query Template Injection
Some Lambda functions build SQL query templates by combining event data with stored query fragments, then execute the assembled template. The tainted template construction step exposes the injection vulnerability even before the execute() call.
Dynamic WHERE Clause Construction
Lambda handlers that build dynamic WHERE clauses by appending conditions based on event fields (e.g., adding AND column = 'value' for each filter parameter) via string concatenation are particularly vulnerable, as each filter field is an injection point and the vulnerability scales with the number of event fields processed.
How to Fix
Recommended remediation steps
- 1Restructure SQL construction helpers to return a (query_template, params_list) tuple rather than a pre-built SQL string with embedded values.
- 2Use placeholders (%s for MySQL/psycopg2, :name for SQLAlchemy text()) in the SQL template and collect event values in a separate list or dictionary.
- 3For dynamic WHERE clause construction, append placeholders to the WHERE string and values to a separate list; never append event data to the SQL string directly.
- 4Validate and type-convert event fields before adding them to the parameters list as a defense-in-depth measure.
- 5Apply least-privilege database permissions to the Lambda's database user to limit the blast radius of any successful injection.
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 rule tracks taint through f-string interpolation and string concatenation operations to identify SQL string variables that contain event data. The sink is any calls("*.execute") call where the tainted SQL string variable is passed as the first argument (tracked via .tracks(0)). Sanitizers include explicit int() or float() type conversion. The analysis follows taint through variable assignments, function return values, 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 SQL Injection via psycopg2 cursor.execute()
Lambda event data flows to psycopg2 cursor.execute() without parameterization, enabling SQL injection against RDS PostgreSQL or Aurora PostgreSQL backends.
Lambda SQL Injection via pymssql cursor.execute()
Lambda event data flows to pymssql cursor.execute() without parameterization, enabling SQL injection against RDS SQL Server backends.
Lambda SQL Injection via PyMySQL cursor.execute()
Lambda event data flows to PyMySQL cursor.execute() without parameterization, enabling SQL injection against RDS MySQL or Aurora MySQL backends via the pure-Python driver.
Frequently Asked Questions
Common questions about Lambda Tainted SQL String Construction
New feature
Get these findings posted directly on your GitHub pull requests
The Lambda Tainted SQL String Construction rule runs in CI and posts inline review comments on the exact lines — no dashboard, no SARIF viewer.