Threat-model-driven security review of a change, feature, or subsystem. Runs a STRIDE-style pass (Spoofing, Tampering, Repudiation, Info disclosure, Denial of service, Elevation of privilege), examines the actual code, and produces a filing-ready report with severity, exploit scenario, and concrete remediation. Use when asked to "security review", "threat model", "check for vulnerabilities", "audit this for security", "secure this", or before shipping any change that touches auth, input handling, data access, or external surfaces.
77
96%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Passed
No findings from the security scan
Invocation points:
Do NOT use for:
review)code-optimizer)
<core_principle> CODE BEFORE CHECKLISTS. A threat model that doesn't read the code is theater. Find the actual input source, the actual validation (or absence), the actual sink. Cite file:line for every finding.
THREAT, NOT HYPOTHETICAL. "SQL injection is possible in theory" is useless. "If an attacker passes ' OR 1=1-- to getUser(name) at src/db/users.ts:42, the query becomes SELECT … WHERE name='' OR 1=1--', returning every row" is actionable.
READ-ONLY. Don't patch while reviewing — you conflate reviewer and author and lose the audit trail. Report, let the user act. </core_principle>
Identify what to review:
src/auth/, the webhook handler, etc.)If the scope is vague, ask one round of clarifying questions (1–3 questions). Otherwise proceed.
Before STRIDE: identify every untrusted entry point in the scope:
For each, note: who can reach this surface? (public internet, authenticated user, same-host process, admin-only).
For each attack surface, walk STRIDE:
Use Agent(subagent_type=Explore) in parallel if the scope is large — one sub-agent per STRIDE category over the same surface list.
If the scope includes web surfaces, confirm against the top OWASP patterns that STRIDE doesn't cleanly cover:
For each present, find the code path. Same standard: cite file:line.
For each finding, assign:
Severity × Exploitability = priority. Sort findings by priority.
## Security Review — <scope>
### Summary
<1–3 sentences — biggest finding and overall posture>
### Findings
#### CRITICAL-1: SQL injection in `getUser`
**Location:** `src/db/users.ts:42`
**Category:** Tampering / Info disclosure (STRIDE) + OWASP A03 Injection
**Exploit:** Passing `' OR 1=1--` to the `name` parameter produces the query `SELECT * FROM users WHERE name='' OR 1=1--'`, returning every row. `name` arrives from `POST /api/search` without validation.
**Reachability:** Remote unauthenticated (endpoint has no auth).
**Remediation:** Use a parameterized query. The codebase's `db.prepare` helper at `src/db/util.ts:17` handles this — switch `getUser` to it.
#### HIGH-2: ...
### Non-findings considered
<brief: what you checked and ruled out — prevents repeat reviews>
### Out of scope
<what wasn't reviewed>Offer to file as a GitHub issue — requires explicit confirmation per the outward-action rule. Sensitive findings should stay in .gsd/security-reviews/ and not be pushed to a public tracker; check the repository's security policy first.
If the review found CRITICAL or HIGH issues:
/gsd start hotfix if it's in the scope of active work..gsd/DECISIONS.md if the remediation involves an architectural change.<anti_patterns>
</anti_patterns>
<success_criteria>
</success_criteria>
33c00aa
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.