Lesson 333 of 2116
Security Review of AI-Generated Code
AI happily writes code with classic vulnerabilities. Learn the OWASP-aligned review checklist for AI output, the prompts that catch issues early, and the tools that automate the rest.
Lesson map
What this lesson covers
Learning path
The main moves in order
- 1AI Has Read Every Vulnerability, And Sometimes Writes One
- 2OWASP
- 3injection
- 4secrets
Concept cluster
Terms to connect while reading
Section 1
AI Has Read Every Vulnerability, And Sometimes Writes One
Models train on public code, and public code is full of vulnerabilities. The model learns common patterns — including the insecure ones. SQL strings concatenated with user input, secrets hardcoded for examples, `eval` of user data, missing auth checks. AI will reproduce all of these on demand if you don't tell it not to.
The top eight AI-generated vulnerabilities to watch for
Compare the options
| Vuln | What AI does | Fix |
|---|---|---|
| SQL injection | f-string queries with user input | Parameterized queries, prepared statements |
| Command injection | `subprocess.call(f"...{user}...")` | `subprocess.run([...], shell=False)` |
| Path traversal | `open(user_input)` with no allowlist | Resolve, normalize, check inside allowed dir |
| Hardcoded secrets | `API_KEY = "sk-..."` in committed file | Read from env, use a secrets manager |
| Missing auth | Endpoint without role/permission check | Decorator/middleware mandatory on all routes |
| Open redirect | `redirect(request.args.get("next"))` | Allowlist of safe redirect targets |
| XSS | `dangerouslySetInnerHTML` with user data | Escape, or use safe APIs |
| Insecure deserialization | `pickle.loads(user_input)` | Use JSON; if pickle, sign and verify |
The pre-flight prompt addition
A 70-word boilerplate that stops 80% of AI-introduced vulns at the source.
# Append to any code-generation prompt that touches:
# - user input
# - filesystems
# - shells
# - databases
# - HTTP
# - secrets
"Apply OWASP best practices. No string-concatenated SQL — use parameterized queries.
No shell=True in subprocess calls. No eval/exec. Read all secrets from env vars,
never hardcode. Validate all user input with explicit schemas (Zod, Pydantic, etc.).
If you generate code with any of these, flag it and explain why you couldn't avoid it."The 5-minute review pass
- 1Search the diff for `f"`, `"" + `, or template strings near `query`, `execute`, `exec`, `subprocess`
- 2Search for hardcoded strings starting with `sk-`, `pk-`, `AKIA`, `ghp_`, `xoxb-`, `Bearer ` followed by characters
- 3Confirm every endpoint has explicit auth — `@require_auth`, `requireUser()`, etc.
- 4Search for `eval(`, `exec(`, `pickle.loads(`, `Function(`, `setTimeout("`, `innerHTML`
- 5Verify error messages don't leak internals — check `except: return str(e)` patterns
Tools that automate the boring parts
Compare the options
| Tool | What it catches | Setup |
|---|---|---|
| Semgrep | Pattern-based vulns (SQLi, command inj, etc.) | `semgrep --config=auto .` |
| Bandit (Python) | Common Python security smells | `pip install bandit && bandit -r .` |
| ESLint security plugins | JS/TS security patterns | `eslint-plugin-security` |
| GitHub Code Scanning | CodeQL queries on every push | Free for public repos |
| Trivy / Grype | Vulnerable dependencies in lockfiles | CI step or local scan |
| GitGuardian / TruffleHog | Hardcoded secrets in commits | Pre-commit hook + CI |
The adversarial review prompt
Cross-family adversarial review catches more than same-family review. Mix Claude with GPT for coverage.
# After AI writes code, run this in a fresh chat:
"Act as a security auditor. The following code was just generated by AI.
List every realistic security issue you can find, ranked by severity (critical/high/med/low).
For each: the line numbers, the threat model (who attacks how), and the fix.
Do not be polite. Assume hostile users.
<paste code>"
# Use a *different* model than wrote the code if possible.
# A second pair of eyes from a different family catches what the first missed.What no AI catches
- Business-logic flaws (a logged-in user accessing another tenant's data via the wrong route param)
- Race conditions in concurrent code
- Subtle privilege escalation through chained features
- Side channels (timing attacks on `==` comparison of secrets)
“AI knows the patterns. Humans know the threats.”
Key terms in this lesson
The big idea: AI accelerates code, but it does not understand attackers. Apply the OWASP-aligned prompt boilerplate, run static analyzers automatically, and budget a human security review for anything user-facing. Speed without security is a CVE in waiting.
End-of-lesson quiz
Check what stuck
15 questions · Score saves to your progress.
Tutor
Curious about “Security Review of AI-Generated Code”?
Ask anything about this lesson. I’ll answer using just what you’re reading — short, friendly, grounded.
Progress saved locally in this browser. Sign in to sync across devices.
Related lessons
Keep going
Creators · 12 min
Hallucinated Imports — When the AI Invents a Library
AI models confidently call libraries that do not exist. Learn the patterns of hallucinated imports, the verification habits that catch them, and the supply-chain attack this opens up.
Creators · 14 min
The 10-Minute Security Check
Before a vibe-coded app leaves your laptop, check auth, database policies, secrets, file uploads, admin routes, rate limits, and public pages. Write the smallest useful scope the agent can finish.
Creators · 14 min
Secrets, Env Vars, And The Frontend Trap
API keys in browser code are public. Learn the difference between public configuration and private secrets before connecting payments or AI APIs.
