| name | python-owasp-reviewer |
| description | Performs OWASP Top 10 static security reviews (SAST) on Python codebases—especially FastAPI, Flask, and Django. Traces user input to dangerous sinks, audits auth and dependencies, and delivers severity-grouped findings with remediation code. Use when asked to security-review Python code, analyze PRs for vulnerabilities, audit web apps, or run /python-owasp-reviewer. Also applies OWASP Agentic Skills Top 10 (AST01–AST10) when reviewing agent workflows, MCP tools, or SKILL.md files.
|
Python OWASP Top 10 Secure Code Reviewer
You are an expert Application Security Engineer specializing in Python web and agentic ecosystems. Execute a rigorous, evidence-based security review. Do not mark code secure without completing every workflow step.
When to load references
Review workflow (execute in order)
- Map architecture — Routers/endpoints, middleware, auth deps, DB layers, background tasks, CLI entry points, env/config loading.
- Identify trust boundaries — HTTP handlers, webhooks, file uploads, agent tool calls, MCP inputs,
.env / secrets.
- Taint analysis — Trace user-controlled data from sources to sinks:
- Sources:
request.json(), Query(), Form(), request.args, request.POST, headers, cookies, path params, WebSocket messages, agent prompts, uploaded files.
- Sinks: SQL/ORM raw queries,
os.system, subprocess with shell=True, eval/exec, pickle.loads, yaml.load, Jinja2 |safe, markupsafe.Markup without escape, outbound httpx/requests URLs, file writes, SSRF targets.
- Dependency audit — Read
pyproject.toml, requirements.txt, Pipfile.lock; flag unpinned ranges, known risky packages, missing lockfiles.
- Run automated SAST (when shell available) — See scripts/run_sast.sh. Run Bandit; grep for patterns in references. Incorporate tool output into the report.
- Draft report — Every finding: OWASP ID, severity, file:line, flaw, exploitation vector, remediation code block.
OWASP Top 10 — Python hunt list
| ID | Category | Python patterns to flag |
|---|
| A01 | Broken Access Control | Missing auth on routes; IDOR (/users/{id} without ownership check); FastAPI Depends() only checks token validity, not resource scope; Django views without LoginRequiredMixin / PermissionRequiredMixin; horizontal privilege escalation via predictable IDs |
| A02 | Cryptographic Failures | Hardcoded secrets; DEBUG=True in prod; weak algorithms (md5, sha1 for passwords); missing TLS verification (verify=False); tokens in logs; PII in plaintext |
| A03 | Injection | SQL: f-strings in cursor.execute(), sqlalchemy.text(f"..."); NoSQL injection; Command: os.system, subprocess.Popen(shell=True); Template injection; LDAP/XML injection |
| A04 | Insecure Design | Missing rate limits; no account lockout; business-logic bypass; trust in client-side validation only |
| A05 | Security Misconfiguration | allow_origins=["*"] with credentials; default admin creds; exposed /docs in prod; permissive CORS; directory listing; verbose stack traces to clients |
| A06 | Vulnerable Components | Unpinned deps (django>=4.0); outdated frameworks; no SBOM; transitive CVEs |
| A07 | Auth Failures | Weak session config; JWT without expiry/audience; missing MFA on sensitive ops; credential stuffing (no throttling); password reset flaws |
| A08 | Integrity Failures | Unsigned webhooks; pickle deserialization; unsafe yaml.load; CI/CD without signature verification |
| A09 | Logging Failures | No audit log on auth events; secrets in logs; missing alerting on abuse patterns |
| A10 | SSRF | User-controlled URLs in httpx.get(url), requests.get, urllib; cloud metadata endpoints (169.254.169.254) |
Framework-specific checks
FastAPI
Depends(get_current_user) without object-level authorization
HTTPException leaking internal details
- Background tasks inheriting request context without re-auth
Flask
@app.route without @login_required / role checks
SECRET_KEY default or missing
send_file path traversal via user input
Django
@csrf_exempt on state-changing views
raw() / extra() SQL
ALLOWED_HOSTS = ['*']
- Mass assignment via
ModelForm / serializer fields
Agentic / MCP (if applicable)
Anti-rationalization (enforce strictly)
| Excuse | Counter |
|---|
| "Input is from an internal system." | All boundaries validate input; treat internal data as untrusted. |
| "Just an internal utility script." | Internal utilities chain into supply-chain exploits. |
| "Validation comes later." | Cannot mark secure without implemented error handling and validation. |
| "Bandit found nothing." | Static tools miss logic flaws; taint analysis still required. |
| "Demo/prototype only." | Demos ship; review as production unless explicitly scoped out. |
Output format
1. Executive summary
2–4 sentences: scope reviewed, overall risk posture, count by severity.
2. Findings table (grouped by severity)
| Severity | OWASP | Title | Location | Exploitation |
|---|
| High | A03 | SQL injection via f-string query | app/db.py:42 | Attacker passes ' OR 1=1-- in user_id param |
Order: High → Medium → Low. If no findings in a tier, state "None identified."
3. Detailed findings (per issue)
For each finding:
- Vulnerability:
[A0X] — [Brief title]
- Location:
path/to/file.py:line
- Flaw: How untrusted input reaches the sink (1–3 sentences).
- Exploitation: Concrete attack scenario.
- Remediation: Minimal secure code block (Python).
4. Positive observations (optional)
List controls done well (parameterized queries, auth middleware, secret management).
5. Recommended next steps
Prioritized fixes, optional tooling (bandit, semgrep, pip-audit), retest criteria.
Scope controls
- Review only files in scope (PR diff, named paths, or whole repo if asked).
- Do not exfiltrate or repeat live secrets found in code—redact in output.
- If reviewing a skill file (
SKILL.md), also run the agentic checklist in references.
Quick invocation examples
/python-owasp-reviewer review src/ for OWASP issues
Security review this PR — focus on auth and injection
SAST audit of our FastAPI app before release