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-LANG-SEC-080 --project .About This Rule
Understanding the vulnerability and how it is detected
psycopg2 is the most widely used PostgreSQL adapter for Python. SQL injection occurs when user-supplied data is concatenated or formatted into the SQL query string instead of being passed as separate parameters. When the query is constructed with string formatting (% operator, .format(), or f-strings), an attacker can embed SQL syntax characters in their input to modify the query structure.
The correct approach with psycopg2 is to use parameterized queries: pass the SQL template as a literal string with %s placeholders and user data as a separate tuple argument to cursor.execute(). psycopg2 handles proper escaping and quoting of parameters at the database protocol level.
This rule detects patterns where SQL strings built with string formatting are passed to psycopg2's cursor.execute() or cursor.executemany() methods.
Security Implications
Potential attack scenarios if this vulnerability is exploited
Database Records Exfiltration
UNION SELECT injection allows an attacker to retrieve data from any table in the PostgreSQL database. This includes user credentials, session tokens, private data, and application secrets stored in the database.
Authentication Bypass
Login queries built with string concatenation can be bypassed with ' OR '1'='1 payloads or similar techniques, granting access without valid credentials.
Data Manipulation and Destruction
Stacked queries or subquery injection can issue INSERT, UPDATE, or DELETE statements, allowing attackers to alter data, create backdoor accounts, or wipe database tables.
PostgreSQL Server Escalation
PostgreSQL's COPY TO/FROM PROGRAM (superuser), pg_read_file(), and pg_read_binary_file() can read server filesystem files. On misconfigured servers, SQL injection can escalate to OS command execution.
How to Fix
Recommended remediation steps
- 1Always use parameterized queries with %s placeholders and pass user data as the second argument tuple to cursor.execute().
- 2Never construct SQL strings with % operator, .format(), or f-strings when user-supplied values are involved.
- 3Use psycopg2.sql module (psycopg2.sql.SQL, psycopg2.sql.Identifier) for dynamic column names, table names, or ORDER BY directions that cannot be parameterized.
- 4Grant the PostgreSQL database user the minimum required privileges to prevent SQL injection from accessing unintended schemas or escalating to system functions.
- 5Enable PostgreSQL's pg_audit extension to log all SQL statements for security monitoring.
Detection Scope
How Code Pathfinder analyzes your code for this vulnerability
This rule performs taint analysis tracing user-controlled data through string formatting operations to psycopg2 cursor.execute() and cursor.executemany() call sites. Sources include HTTP request parameters, os.environ, file reads, and other external inputs. The sink is the first argument (position 0) of cursor.execute().
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
Frequently Asked Questions
Common questions about psycopg2 SQL Injection via String Formatting
New feature
Get these findings posted directly on your GitHub pull requests
The psycopg2 SQL Injection via String Formatting rule runs in CI and posts inline review comments on the exact lines — no dashboard, no SARIF viewer.