Python Injection Path Audit
Audit Python code for SQL injection, shell injection, and unsafe deserialization vulnerabilities.
1 views
Cursorpythonsecurityinjection
How to Use
1. Create the file .cursor/rules/python-injection-path-audit.mdc with the agent content. 2. The rule activates automatically when Python files matching **/*.py are open, or invoke manually with @python-injection-path-audit in chat. 3. Ask it to audit a file or directory: "Audit src/ for injection risks." 4. Verify the rule appears in Cursor Settings > Rules.
Agent Definition
---
description: Activates when editing Python files that handle user input, database queries, shell commands, deserialization, authorization checks, or configuration/secrets loading.
globs:
- "**/*.py"
alwaysApply: false
---
# Python Injection Path Audit
Audit Python code for injection vulnerabilities, authorization boundary issues, and secrets exposure. Cover five attack surfaces: SQL injection, shell injection, unsafe deserialization, broken authorization, and secrets in config/runtime.
## 1. SQL Injection
- Flag any string concatenation or f-string interpolation inside SQL query strings.
- Require parameterized queries for all database calls (sqlite3, psycopg2, SQLAlchemy text(), Django raw/extra).
- When an ORM is used, flag `.raw()`, `.extra()`, or `text()` with interpolated values. Suggest parameterized equivalents.
- Check that user input never flows into `ORDER BY`, `LIMIT`, or table/column names without allowlist validation.
Example of what to flag:
```python
cursor.execute(f"SELECT * FROM users WHERE id = {user_id}")
```
Fix: `cursor.execute("SELECT * FROM users WHERE id = %s", (user_id,))`
## 2. Shell Injection
- Flag `os.system()`, `os.popen()`, and `subprocess` calls with `shell=True` when arguments include any variable.
- Require `subprocess.run()` with a list of arguments and `shell=False` (the default).
- Flag use of `shlex.quote()` as sole mitigation when `shell=True` is still used — recommend removing `shell=True` instead.
- Check for command injection via environment variables passed unsanitized to subprocesses.
## 3. Unsafe Deserialization
- Flag `pickle.loads()`, `pickle.load()`, `shelve.open()`, `marshal.loads()`, and `yaml.load()` without `Loader=SafeLoader`.
- Flag `jsonpickle.decode()` on untrusted input.
- For YAML: require `yaml.safe_load()` or explicit `Loader=yaml.SafeLoader`.
- For any deserialization of user-controlled or network-received data, recommend a schema-validated format (JSON with pydantic/marshmallow, or msgpack with schema).
## 4. Authorization Boundary Audit
- Identify endpoints, views, or functions that access resources by user-supplied ID (path param, query param, request body).
- Flag missing ownership or permission checks before data access. Look for patterns where a record is fetched by ID without verifying the requesting user owns or is authorized to access it.
- In Django: flag views missing `@permission_required`, `@login_required`, or object-level permission checks. In Flask: flag routes missing authorization decorators or explicit checks.
- Flag any route that performs write operations (create, update, delete) without verifying the caller's role or ownership.
- Check that authorization is enforced at the data access layer, not only at the view/route layer, especially when internal helper functions fetch records.
## 5. Secrets Handling
- Flag hardcoded secrets: API keys, passwords, tokens, or DSNs as string literals in source files.
- Flag secrets in default argument values, class attributes, or module-level constants.
- Require secrets to be loaded from environment variables (`os.environ`, `os.getenv`) or a secrets manager (AWS Secrets Manager, HashiCorp Vault, python-dotenv loading `.env` files that are gitignored).
- Flag `.env` files or config files containing secrets that are not in `.gitignore`.
- Flag logging or print statements that output variables likely containing secrets (variable names containing `password`, `secret`, `token`, `api_key`, `dsn`, `credentials`).
- Check that secrets are not passed as CLI arguments (visible in process listings).
## Audit Process
1. Trace data flow from entry points (request handlers, CLI args, file reads, environment) to each of the five sink categories.
2. For each finding, report: file, line, sink category (SQL/shell/deserialization/authz/secrets), the tainted data flow, and a concrete fix.
3. Classify severity: Critical (RCE, SQLi with no parameterization, hardcoded production secrets), High (authz bypass, shell=True with variables, pickle on semi-trusted input), Medium (missing SafeLoader, secrets in logs, authz only at view layer).
4. After the audit, produce a summary table grouped by category with counts and top-severity item per category.
## Tools to Recommend
- `bandit` for static analysis (`bandit -r . -ll` for high-confidence findings).
- `semgrep` with `p/python` and `p/owasp-top-ten` rulesets for deeper taint analysis.
- `pip-audit` for known vulnerabilities in dependencies that may introduce injection or deserialization risks.
- `detect-secrets` for scanning committed secrets.
## Boundaries
- Do not modify application logic or refactor code beyond what is needed to fix the vulnerability.
- When a fix requires architectural change (e.g., moving from pickle to JSON for IPC), describe the change but do not implement it without confirmation.
- Do not flag parameterized queries or properly sandboxed deserialization as issues.