Frisk your diff before it ships.
🇺🇸 English · 🇮🇩 Bahasa Indonesia · 🇨🇳 简体中文
A skill for your coding agent (Claude Code — also Codex, Cursor, Gemini CLI,
opencode, and anything that reads a rules file). Right before the agent says a
task is done, it pats down its own diff for security holes — secrets,
injection, SSRF, broken authz, path traversal, unsafe eval, weak crypto —
fixes the safe ones, escalates the rest, and won't sign off while a real one
is still open.
AI writes a lot of code now. A lot of it ships vulnerabilities. The agent that wrote it is the cheapest place to catch them — before review, before CI, before an attacker.
Without patdown — the agent writes it and moves on:
const stripe = new Stripe("sk_live_51H8xQ2eZ..."); // hardcoded live key
const res = await fetch(req.query.callbackUrl); // SSRF
db.query("SELECT * FROM orders WHERE id=" + req.params.id); // SQL injection"Done! Payments endpoint is wired up. ✅"
With patdown — it frisks the diff first:
patdown — 1 changed file
✗ critical payments.ts:1 hardcoded Stripe live key → moved to STRIPE_SECRET env [fixed]
✗ high payments.ts:2 SSRF: user callbackUrl fetched → added public-host allow-list [fixed]
⚠ high payments.ts:3 SQL injection on `id` — needs a parameterized query [escalated]
✓ rest clean (authz, paths, crypto)
1 issue needs your call before this is done.
Same code. The vulns don't make it out the door.
Not a mockup. These are actual patdown runs in Claude Code on planted-vuln code:
- Case 1 — payments: caught a hardcoded Stripe live key (critical), an SSRF, and a SQL injection — and noticed the key was already in git history, so it told you to rotate it, not just move it.
- Case 2 — auth helpers: four classes in eight lines — path traversal, a
Math.random()reset token, an IDOR (looks like a normal DB call), and an MD5 password hash. A secret-scanner catches none of these.
Full diffs + verbatim reports in CASES.md. Reproduce: install the
skill, make the change, run /patdown.
Exploit case study — the same three real attacks fired at a tiny API before
and after patdown's fixes: 3/3 exploited → 0/3. Real node:sqlite injection,
a real SSRF to an internal service, a real leaked key. Runnable e2e + video in
examples/exploit-case-study.
# macOS / Linux / WSL
curl -fsSL https://raw.githubusercontent.com/ryanda9910/patdown/main/install.sh | bash
# Windows (PowerShell)
irm https://raw.githubusercontent.com/ryanda9910/patdown/main/install.ps1 | iexFinds every coding agent you have and installs the skill into each. ~10 seconds,
safe to re-run. Add --project to also install into the current repo's
.claude/. No key, no account, no dependency.
Manual: copy skill/SKILL.md into your agent's skills/rules
directory (Claude Code: ~/.claude/skills/patdown/SKILL.md).
┌──────────────────────────────────────────────────────────┐
│ SECRETS api keys · tokens · creds in code/logs │
│ INJECTION sql · shell · template/xss · eval · deser │
│ SSRF user-controlled urls · metadata · redirects │
│ AUTHZ missing owner check · idor · open routes │
│ PATHS traversal · zip-slip · symlink follow │
│ CRYPTO weak rng/hash · disabled tls · == on tokens │
│ DOS unbounded input · no timeouts · redos │
│ LLM/AI-APP prompt injection · model output → eval/sql │
└──────────────────────────────────────────────────────────┘
It audits only the diff — the lines that changed — so it stays fast and doesn't nag about the whole repo.
It's a skill (plain instructions), not a scanner binary — so it understands the code in context instead of pattern-matching.
- You finish a coding task. Before the agent reports "done", the skill kicks in
(or you run
/patdown). - It reads the diff and runs the checklist against the changed lines.
- Safe, mechanical fixes it applies itself — parameterize the query, move the secret to env, add the allow-list, swap the weak hash.
- Anything that touches intent it escalates to you — approve, fix, or skip.
- It does not call the task done while a critical/high issue is unaddressed.
No false-alarm spam: clean lines aren't flagged. If the diff is clean, it says so in one line and gets out of the way.
Claude Code (native skill), and any agent that loads a rules/skill file — Codex, Cursor, Gemini CLI, opencode, Aider, GitHub Copilot CLI, and friends. The installer drops the skill into each one it finds.
Full docs in docs/:
- Usage — triggering,
/patdown, report format, the hard rule - Checklist reference — every category, examples, severity model
- Install — every agent, global vs project, manual, uninstall
- Customizing — edit checks, severity gate, scope, languages
- FAQ — vs SAST/linters/CI, speed, privacy, languages
- Real runs · Contributing · Security
CI catches it after you pushed. A linter pattern-matches and misses logic bugs (an IDOR looks like a normal DB call). patdown rides inside the agent that just wrote the code — it has the full intent and the diff, and it fixes in place. Use it with your scanner, not instead of it.
MIT. Frisk freely.

