security-review
Attaches itself automatically when a prompt matches.
Identify exploitable security vulnerabilities in generated code. Use when reviewing for security issues, when building auth / file upload / external requests, or before deploy. Reports only HIGH confidence findings — clear vulnerable patterns with attacker-controlled input. OWASP-grounded.
Scaffolds
Source
Adapted from getsentry/skills (security-review, adapted — uv/bash tool requirements stripped)
Instructions
The full instruction set the agent receives when this skill is active.
Security Review
Identify exploitable vulnerabilities. Report only HIGH CONFIDENCE findings — clear vulnerable patterns with attacker-controlled input. Theoretical issues, defense-in-depth nags, and missing-best-practice notes are noise; skip them.
The discipline
- Research broadly. Report narrowly. Trace where the input came from before flagging. A pattern that looks dangerous in isolation may be fed only by server-controlled config.
- Pattern matching alone is not a vulnerability. Investigate first.
Confidence levels
| Level | Criteria | Action |
|---|---|---|
| HIGH | Vulnerable pattern + attacker-controlled input confirmed | Report with severity |
| MEDIUM | Vulnerable pattern, input source unclear | Note as "Needs verification" |
| LOW | Theoretical, best practice, defense-in-depth | Do not report |
Do NOT flag
General
- Test files (unless explicitly reviewing test security)
- Dead code, commented code, doc strings
- Patterns using constants or server-controlled config
- Code paths that require prior authentication to reach (note the auth requirement instead)
Server-controlled values (NOT attacker-controlled)
| Source | Example | Why safe |
|---|---|---|
| Env vars | process.env.DATABASE_URL | Deployment config |
| Config files | config.api.url, import config from './config' | Source-controlled |
| Hardcoded constants | const BASE_URL = "https://api.internal" | Compile-time |
| Framework settings | Next.js next.config.js exports | Operator-controlled |
SSRF example — NOT a vulnerability:
SSRF example — IS a vulnerability:
Framework-mitigated patterns (usually safe)
| Pattern | Why usually safe |
|---|---|
React {variable} in JSX | Auto-escaped |
vue {{ variable }} | Auto-escaped |
| Next.js dynamic routes via params | Type-safe, framework-validated |
Prisma where: { id: input } | ORM parameterizes |
Tagged template SQL libs (sql\SELECT ...``) | Parameterized |
Only flag when the escape is bypassed:
- React:
dangerouslySetInnerHTML={{__html: userInput}} - Vue:
v-html="userInput" - ORM:
.$queryRawUnsafe(...), raw SQL string interpolation
Always flag (Critical)
Always flag (High)
Always flag (Secrets)
Check context first (investigate before flagging)
Authentication / authorization (real wins live here)
- Missing authz on a "user can edit X" route — does the handler check
session.userId === X.ownerId? If not, it's IDOR. HIGH. - JWT verified with
alg=noneor noalgcheck — bypass. CRITICAL. - Cookies without
Secure; HttpOnly; SameSitefor session — flag if production-facing. - CSRF on state-changing routes — Next.js Route Handlers + cookie auth need a CSRF defense (SameSite=lax/strict, or a token). Tag flag if the handler is
POST/PUT/DELETEand accepts cookies but has no SameSite or token. - Rate limiting absent on
/login,/signup,/reset— brute-force candidate. MEDIUM unless real users exist.
Severity guide
| Severity | When |
|---|---|
| Critical | RCE, SQL injection to data, auth bypass, hardcoded prod secret |
| High | Stored XSS, SSRF to metadata, IDOR to sensitive data, missing authz on edit |
| Medium | Reflected XSS, CSRF on state-changing actions, path traversal with constraints |
| Low | Missing security headers, verbose errors — DO NOT REPORT unless asked |
Output format
- Fix: [concrete remediation]
Needs verification
[VERIFY-001] [Potential Issue]
- Location:
path/to/file.ts:LINE - Question: [what would change the verdict]