| name | security-audit |
| description | Security Audit Skill: OWASP Top 10 and STRIDE threat modeling on changed code. MANDATORY TRIGGERS: security, audit, vulnerability, OWASP, threat model, security review, pen test, injection, XSS, CSRF, auth bypass. |
| argument-hint | <ticket ID to audit> |
Bobby Security Skill
Security audit using OWASP Top 10 and STRIDE threat modeling. Reviews changed code for vulnerabilities with concrete exploit scenarios.
Before Starting
- Check learnings — Read
.claude/skills/bobby-security/learnings.md + .claude/skills/bobby-security/learnings.local.md
- Run
git log --oneline -10 to understand what changed
- Read the ticket's
ticket.md and plan.md for context
Investigation First
<investigation_rules>
Before forming any security opinion:
- Read every file that was changed:
git diff --name-only
- For each changed file, understand the data flow: where does user input enter, how is it processed, where does it exit?
- Read adjacent files that handle auth, validation, or data access if the changed code interacts with them
- Do not flag issues in code that was not changed by this ticket unless it's a critical vulnerability the change exposed
</investigation_rules>
OWASP Top 10 Checklist
For each changed file, check:
Injection (A03:2021)
Broken Access Control (A01:2021)
Cryptographic Failures (A02:2021)
Security Misconfiguration (A05:2021)
XSS (A07:2021)
SSRF (A10:2021)
Authentication (A07:2021)
STRIDE Threat Model
For significant features (new endpoints, data flows, auth changes):
| Threat | Question | Check |
|---|
| Spoofing | Can an attacker impersonate a user or service? | Auth + session validation |
| Tampering | Can data be modified in transit or at rest? | Input validation + integrity checks |
| Repudiation | Can actions be denied? | Audit logging |
| Information Disclosure | Can sensitive data leak? | Error handling + logging |
| Denial of Service | Can the service be overwhelmed? | Rate limiting + resource bounds |
| Elevation of Privilege | Can a user gain unauthorized access? | RBAC + authorization checks |
Confidence Gate
<confidence_gate>
Only flag findings with 8/10 or higher confidence. For each finding:
- State the vulnerability type (e.g., "SQL Injection in user search")
- Show the exact code path (file:line)
- Describe a concrete exploit scenario ("An attacker could send
' OR 1=1 -- as the search query to...")
- Rate confidence 1-10
- Suggest a specific fix
Do NOT flag:
- Theoretical issues with no concrete exploit path
- Issues in unchanged code (unless the current change exposed them)
- Style preferences disguised as security issues
- Dependencies with known CVEs (that's a separate audit tool's job)
- Issues that are mitigated by framework defaults (e.g., React auto-escaping)
</confidence_gate>
False Positive Exclusions
<false_positives>
These are commonly flagged but are NOT vulnerabilities in most contexts:
- React JSX expressions (auto-escaped by default)
- ORM method calls (parameterized by default)
- Environment variables read at startup (not user input)
- Internal API calls between trusted services
- Test files using hardcoded values
- Migration files with raw SQL (one-time execution, no user input)
- Static config files
- Type definitions and interfaces
</false_positives>
Decision
Approve
If no high-confidence findings:
- Add comment:
bobby ticket comment {ID} --by bobby-security "Security audit passed. Checked: {summary of what was reviewed}"
- If you discovered a pattern:
bobby learn bobby-security "pattern" "description"
Reject
If high-confidence findings exist:
- Move back:
bobby ticket move {ID} reject "SECURITY: {vulnerability type} in {file}:{line} — {exploit scenario}. Fix: {specific remediation}"
- Be specific — the build agent needs exact file, line, and fix
`bobby ticket move TKT-042 reject "SECURITY: SQL Injection in app/models/user.rb:45 — the search_users method concatenates params[:query] directly into a SQL string. An attacker could send ' OR 1=1 -- as the query parameter to dump all user records. Fix: Use User.where('name LIKE ?', "%#{params[:query]}%") instead of string interpolation. Confidence: 9/10"`
`bobby ticket move TKT-042 reject "There might be security issues with how user input is handled"`
If Something Goes Wrong
- If you discover a critical vulnerability in existing code (not introduced by this ticket):
bobby ticket create -t "SECURITY: {vulnerability}" --type bug -p critical
- If you discover a systemic pattern:
bobby learn bobby-security "pattern" "description"
Project overrides
If .claude/skills/bobby-security/SKILL.local.md exists, read it and follow it. It holds this
project's own instructions for this skill and wins wherever it conflicts with anything
above.
SKILL.md is shipped by Bobby and is replaced on every upgrade — edits here are lost.
SKILL.local.md is yours and is never overwritten.