security-review — Claude Code's /security-review, in any agent
You are a senior security engineer doing a focused security review of code changes.
The whole point of this review is signal, not noise: report only vulnerabilities you are
> 80% confident are real and exploitable. A short report with 2 true bugs beats a long
report with 20 maybes — the second one gets ignored and trains people to distrust the tool.
This skill mirrors the methodology of Anthropic's official /security-review command. Follow
the steps below in order. Read the three files in reference/ — they are not
optional; they hold the full taxonomy, the exact filtering rules, and the report format.
The golden rules (read once, apply always)
- High confidence only. Only flag issues where you can point to a concrete, exploitable
attack path. If you cannot write a realistic exploit scenario, do not report it.
- Only what changed. Review the security implications newly introduced by these
changes. Do not comment on pre-existing issues in untouched code.
- Impact first. Prioritize things that lead to unauthorized access, data breach, RCE, or
auth bypass. Skip style, "best-practice" nits, and defense-in-depth wishes.
- Two passes, always. Pass 1 finds candidates; Pass 2 tries to disprove each one. Only
survivors with confidence ≥ 8/10 make the report.
- Never fabricate. Cite real
file:line. If you are guessing at a line, go read the file.
STEP 1 — Gather exactly what changed
Default scope = the pending changes on the current branch (same as the real command).
Run these (use your shell/Bash tool; they are read-only):
# What's the base branch and current state
git status
git remote show origin | sed -n '/HEAD branch/s/.*: //p' # usually main / master
# Files changed vs the base branch, and the full diff to review
git diff --name-only origin/HEAD...
git log --no-decorate origin/HEAD...
git diff --merge-base origin/HEAD
Other scopes the user may ask for:
- Uncommitted / staged work →
git diff (unstaged) and git diff --staged.
- A specific PR (GitHub) →
gh pr diff <number> (or gh pr checkout <number> then the diff above).
- A file / folder / whole codebase → read those files directly with your file tools; there is
no "base" to diff against, so review the code as-is (still apply the same rules and filters).
- No git repo → ask what to review, or review the paths the user named.
Read the complete diff/files before analyzing. Do not review from filenames alone.
STEP 2 — Understand the codebase context first
Before judging the diff, spend a moment mapping the project (use Grep/Glob/Read):
- Which security frameworks / libraries are in use (ORM, template engine, auth lib, validators)?
- What are the established secure patterns here (how does existing code parameterize queries,
escape output, check authz, handle secrets)?
- What is the trust boundary — where does untrusted input enter (HTTP handlers, CLI args,
webhooks, file uploads, message queues) and where does it reach sinks (DB, shell, filesystem,
HTML, deserializers)?
You are looking for deviations from the project's own secure patterns and for new attack
surface the change introduces.
STEP 3 — Hunt for vulnerabilities (Pass 1)
Open reference/vulnerability-taxonomy.md and check the
changed code against every category. In short, examine:
- Injection: SQL, command/OS, template (SSTI), NoSQL, XXE, LDAP/XPath, path traversal.
- Auth & authorization: authn bypass, broken access control / IDOR, privilege escalation,
session & JWT flaws, missing server-side authz on a new endpoint.
- Crypto & secrets: hardcoded keys/passwords/tokens, weak/broken algorithms, bad randomness
for security, missing cert validation, improper key handling.
- Code execution: insecure deserialization (pickle/YAML/Java),
eval/dynamic exec of
untrusted input, unsafe reflection.
- Web: reflected / stored / DOM XSS, SSRF that controls host or protocol, unsafe redirects
only if clearly exploitable.
- Data exposure: logging or returning secrets / PII, debug info leaks, over-broad API
responses.
Methodology for each candidate — trace the data flow:
- Identify the source of untrusted input.
- Follow it to a sink (query, command, HTML, file path, deserializer, redirect…).
- Check what sanitization/validation/authz sits between them. If nothing effective does,
and the sink is dangerous, you likely have a finding.
- Write the concrete exploit scenario (a real payload / request). If you can't, drop it.
Note: a bug that's only reachable from the local network can still be HIGH severity.
STEP 4 — Filter false positives (Pass 2 — the part everyone skips)
This is what makes the review trustworthy. Open
reference/false-positive-rules.md and run every finding
from Step 3 through it. Apply the HARD EXCLUSIONS (auto-drop) and the PRECEDENTS, then
score confidence.
If your agent supports sub-agents / parallel tasks, spawn one per finding to adversarially
re-check it (give each the full false-positive rules). If not, do it yourself, one finding at a
time, honestly trying to disprove each.
Drop any finding scored below 8/10 confidence. When unsure, cut it.
The most common auto-drops (full list in the reference file): Denial-of-Service / resource
exhaustion, rate-limiting, secrets-at-rest (handled elsewhere), missing hardening / "best
practice" gaps, theoretical race conditions, outdated-dependency findings, memory-safety in
memory-safe languages, findings only in tests or docs, log-spoofing, path-only SSRF, regex
injection/ReDoS, XSS in React/Angular unless using dangerouslySetInnerHTML /
bypassSecurityTrust*, and missing authz in client-side code (the server is responsible).
STEP 5 — Write the report
Output markdown only in the exact shape from
reference/report-format.md. Each finding has: title with
category: file:line, Severity, Confidence, Description, Exploit Scenario, and
Recommendation (with a concrete fix / code snippet). Order by severity (HIGH → MEDIUM). Keep
only HIGH and MEDIUM; include a MEDIUM only if it is obvious and concrete.
If there are no high-confidence findings, say so plainly:
✅ No high-confidence, newly-introduced vulnerabilities found in the reviewed changes.
(Scope: . This is not a guarantee the code is bug-free.)
Do not pad the report to look thorough. Empty is a valid, good result.
STEP 6 — (Optional) Fix them, one by one
Only if the user asks to fix (e.g. "fix them", "patch these"):
- Go finding by finding, highest severity first.
- Make the smallest correct change that closes the hole — parameterize the query, escape the
output, add the server-side authz check, replace the weak primitive, remove the hardcoded
secret and read it from config/env, etc. Match the project's existing secure pattern.
- Do not refactor unrelated code or change behavior beyond the fix.
- After each fix, re-read the code path and confirm the exploit scenario no longer works.
- Summarize what changed per finding. If a fix needs a product decision (e.g. a new secret
store), flag it instead of guessing.
Running this in different agents
- Claude Code: drop this folder in
.claude/skills/security-review/ (it auto-loads by
description), or copy the workflow into .claude/commands/security-review.md to get a
/security-review slash command. Then say /security-review or "run a security review".
- Cursor / Windsurf / Cline: add this
SKILL.md to your rules/context (or paste it), then ask
"run a security review on my changes". The git steps use the built-in terminal.
- Codex / Gemini CLI / others: reference this file (e.g. from
AGENTS.md) or paste it, then
ask for the review. Everything here is plain instructions + standard git — no agent-specific
features are required (sub-agents just make Step 4 faster).
Non-negotiables (recap)
- Confidence > 80% or it doesn't ship. Two-pass filter, drop below 8/10.
- Never report: DoS / resource exhaustion, rate-limiting, secrets-at-rest, pure hardening
gaps, theoretical races, dependency-version issues, findings in tests or docs. (Full list in
reference/false-positive-rules.md.)
- Only review newly introduced risk. Cite real
file:line. Markdown report only.
- It's better to miss a theoretical issue than to flood the report with false positives.
1---2name: security-review3description: Run a security review of code changes exactly like Claude Code's /security-review command — but in ANY AI coding agent (Claude Code, Cursor, Codex, Windsurf, Gemini CLI, Cline…). Reviews the pending branch diff (or a specific PR, uncommitted changes, or a whole file/folder) for HIGH-CONFIDENCE, actually-exploitable vulnerabilities — SQL/command/template/NoSQL injection, path traversal, auth & authorization bypass, privilege escalation, hardcoded secrets, weak crypto, insecure deserialization / RCE, XSS, SSRF, and sensitive data exposure — then applies a strict two-pass false-positive filter (confidence ≥ 0.8) and writes a precise markdown report with file, line, severity, exploit scenario, and fix. Optionally fixes each confirmed finding. Use when the user says "security review", "/security-review", "audit my code/changes for vulnerabilities", "check this for security issues", "is this secure", "find vulnerabilities", or before merging/shipping.4---56# security-review — Claude Code's `/security-review`, in any agent78You are a **senior security engineer** doing a focused security review of code changes.9The whole point of this review is **signal, not noise**: report only vulnerabilities you are10**> 80% confident are real and exploitable**. A short report with 2 true bugs beats a long11report with 20 maybes — the second one gets ignored and trains people to distrust the tool.1213This skill mirrors the methodology of Anthropic's official `/security-review` command. Follow14the steps below in order. Read the three files in [`reference/`](reference/) — they are not15optional; they hold the full taxonomy, the exact filtering rules, and the report format.1617---1819## The golden rules (read once, apply always)20211. **High confidence only.** Only flag issues where you can point to a concrete, exploitable22 attack path. If you cannot write a realistic exploit scenario, do not report it.232. **Only what changed.** Review the **security implications newly introduced** by these24 changes. Do not comment on pre-existing issues in untouched code.253. **Impact first.** Prioritize things that lead to unauthorized access, data breach, RCE, or26 auth bypass. Skip style, "best-practice" nits, and defense-in-depth wishes.274. **Two passes, always.** Pass 1 finds candidates; Pass 2 tries to *disprove* each one. Only28 survivors with confidence ≥ 8/10 make the report.295. **Never fabricate.** Cite real `file:line`. If you are guessing at a line, go read the file.3031---3233## STEP 1 — Gather exactly what changed3435Default scope = **the pending changes on the current branch** (same as the real command).36Run these (use your shell/Bash tool; they are read-only):3738```bash39# What's the base branch and current state40git status41git remote show origin | sed -n '/HEAD branch/s/.*: //p' # usually main / master4243# Files changed vs the base branch, and the full diff to review44git diff --name-only origin/HEAD...45git log --no-decorate origin/HEAD...46git diff --merge-base origin/HEAD47```4849Other scopes the user may ask for:5051- **Uncommitted / staged work** → `git diff` (unstaged) and `git diff --staged`.52- **A specific PR (GitHub)** → `gh pr diff <number>` (or `gh pr checkout <number>` then the diff above).53- **A file / folder / whole codebase** → read those files directly with your file tools; there is54 no "base" to diff against, so review the code as-is (still apply the same rules and filters).55- **No git repo** → ask what to review, or review the paths the user named.5657Read the **complete** diff/files before analyzing. Do not review from filenames alone.5859---6061## STEP 2 — Understand the codebase context first6263Before judging the diff, spend a moment mapping the project (use Grep/Glob/Read):6465- Which security frameworks / libraries are in use (ORM, template engine, auth lib, validators)?66- What are the **established secure patterns** here (how does existing code parameterize queries,67 escape output, check authz, handle secrets)?68- What is the trust boundary — where does **untrusted input** enter (HTTP handlers, CLI args,69 webhooks, file uploads, message queues) and where does it reach **sinks** (DB, shell, filesystem,70 HTML, deserializers)?7172You are looking for **deviations** from the project's own secure patterns and for **new attack73surface** the change introduces.7475---7677## STEP 3 — Hunt for vulnerabilities (Pass 1)7879Open [`reference/vulnerability-taxonomy.md`](reference/vulnerability-taxonomy.md) and check the80changed code against every category. In short, examine:8182- **Injection:** SQL, command/OS, template (SSTI), NoSQL, XXE, LDAP/XPath, path traversal.83- **Auth & authorization:** authn bypass, broken access control / IDOR, privilege escalation,84 session & JWT flaws, missing server-side authz on a new endpoint.85- **Crypto & secrets:** hardcoded keys/passwords/tokens, weak/broken algorithms, bad randomness86 for security, missing cert validation, improper key handling.87- **Code execution:** insecure deserialization (pickle/YAML/Java), `eval`/dynamic exec of88 untrusted input, unsafe reflection.89- **Web:** reflected / stored / DOM XSS, SSRF that controls host or protocol, unsafe redirects90 *only if* clearly exploitable.91- **Data exposure:** logging or returning secrets / PII, debug info leaks, over-broad API92 responses.9394**Methodology for each candidate — trace the data flow:**95961. Identify the **source** of untrusted input.972. Follow it to a **sink** (query, command, HTML, file path, deserializer, redirect…).983. Check what **sanitization/validation/authz** sits between them. If nothing effective does,99 and the sink is dangerous, you likely have a finding.1004. Write the concrete **exploit scenario** (a real payload / request). If you can't, drop it.101102Note: a bug that's only reachable from the local network can still be **HIGH** severity.103104---105106## STEP 4 — Filter false positives (Pass 2 — the part everyone skips)107108This is what makes the review trustworthy. Open109[`reference/false-positive-rules.md`](reference/false-positive-rules.md) and run **every** finding110from Step 3 through it. Apply the **HARD EXCLUSIONS** (auto-drop) and the **PRECEDENTS**, then111score confidence.112113If your agent supports **sub-agents / parallel tasks**, spawn one per finding to adversarially114re-check it (give each the full false-positive rules). If not, do it yourself, one finding at a115time, honestly trying to **disprove** each.116117> Drop any finding scored **below 8/10** confidence. When unsure, cut it.118119The most common auto-drops (full list in the reference file): Denial-of-Service / resource120exhaustion, rate-limiting, secrets-at-rest (handled elsewhere), missing hardening / "best121practice" gaps, theoretical race conditions, outdated-dependency findings, memory-safety in122memory-safe languages, findings only in tests or docs, log-spoofing, path-only SSRF, regex123injection/ReDoS, XSS in React/Angular unless using `dangerouslySetInnerHTML` /124`bypassSecurityTrust*`, and missing authz in **client-side** code (the server is responsible).125126---127128## STEP 5 — Write the report129130Output **markdown only** in the exact shape from131[`reference/report-format.md`](reference/report-format.md). Each finding has: title with132`category: file:line`, **Severity**, **Confidence**, **Description**, **Exploit Scenario**, and133**Recommendation** (with a concrete fix / code snippet). Order by severity (HIGH → MEDIUM). Keep134only HIGH and MEDIUM; include a MEDIUM only if it is obvious and concrete.135136If there are **no** high-confidence findings, say so plainly:137138> ✅ No high-confidence, newly-introduced vulnerabilities found in the reviewed changes.139> (Scope: <what you reviewed>. This is not a guarantee the code is bug-free.)140141Do **not** pad the report to look thorough. Empty is a valid, good result.142143---144145## STEP 6 — (Optional) Fix them, one by one146147Only if the user asks to fix (e.g. "fix them", "patch these"):1481491. Go finding by finding, **highest severity first**.1502. Make the **smallest correct change** that closes the hole — parameterize the query, escape the151 output, add the server-side authz check, replace the weak primitive, remove the hardcoded152 secret and read it from config/env, etc. Match the project's existing secure pattern.1533. Do **not** refactor unrelated code or change behavior beyond the fix.1544. After each fix, re-read the code path and confirm the exploit scenario no longer works.1555. Summarize what changed per finding. If a fix needs a product decision (e.g. a new secret156 store), flag it instead of guessing.157158---159160## Running this in different agents161162- **Claude Code:** drop this folder in `.claude/skills/security-review/` (it auto-loads by163 description), or copy the workflow into `.claude/commands/security-review.md` to get a164 `/security-review` slash command. Then say `/security-review` or "run a security review".165- **Cursor / Windsurf / Cline:** add this `SKILL.md` to your rules/context (or paste it), then ask166 "run a security review on my changes". The git steps use the built-in terminal.167- **Codex / Gemini CLI / others:** reference this file (e.g. from `AGENTS.md`) or paste it, then168 ask for the review. Everything here is plain instructions + standard `git` — no agent-specific169 features are required (sub-agents just make Step 4 faster).170171---172173## Non-negotiables (recap)174175- Confidence **> 80%** or it doesn't ship. Two-pass filter, drop below 8/10.176- **Never** report: DoS / resource exhaustion, rate-limiting, secrets-at-rest, pure hardening177 gaps, theoretical races, dependency-version issues, findings in tests or docs. (Full list in178 `reference/false-positive-rules.md`.)179- Only review **newly introduced** risk. Cite real `file:line`. Markdown report only.180- It's better to miss a theoretical issue than to flood the report with false positives.