security-audit
gonimar/claude-web-studio/skills/security-audit/SKILL.md
Audits the application against OWASP Top 10:2025 / ASVS for the project's stack — code review by appsec-engineer, tooling (vulnerability, secret and SAST scanners), CVSS-scored findings with fixes in docs/security/security-audit-<date>.md; modes full, quick, api, auth, infra, <path>. Required before release; use for 'security audit', 'is this secure', 'OWASP check', 'review the auth code'.
Skill4 starsChanged 4 days ago
---
name: security-audit
description: "Audits the application against OWASP Top 10:2025 / ASVS for the project's stack — code review by appsec-engineer, tooling (vulnerability, secret and SAST scanners), CVSS-scored findings with fixes in docs/security/security-audit-<date>.md; modes full, quick, api, auth, infra, <path>. Required before release; use for 'security audit', 'is this secure', 'OWASP check', 'review the auth code'."
argument-hint: "[full | quick | api | auth | infra | <path>]"
user-invocable: true
allowed-tools: Read, Glob, Grep, Bash, Write, Task, AskUserQuestion
---
# Security Audit
Reply in the project conversation language (CLAUDE.md → Language); code, identifiers, paths and commit messages stay in English.
Templates `templates/security-audit-report.md`, `findings.md`; `stack-reference/security-standards.md`, `security-baseline.md`, `graphql.md` (security). In the commands below, `<hooks>` is `.claude/hooks/` in copy mode and `${CLAUDE_PLUGIN_ROOT}/hooks/` in plugin mode.
## Phase 1: Scope
Mode from the argument (`full` by default): `quick` = HIGH/BLOCKING classes only (auth, authorisation/IDOR, injection, secrets, dependency CVEs) without the network and GraphQL deep passes; `api`/`auth`/`infra`/`<path>` narrow the scope. Surfaces from the threat model; no `docs/architecture/threat-model.md` → continue from technical-preferences and the code, say so in the report and propose `/threat-model` as a follow-up — never a silent full pass. Stack from technical-preferences.
## Phase 2: In parallel via Task
- `appsec-engineer`: code review A01–A10 for the scope (auth/sessions/JWT, object and GraphQL field authorisation, injection/XSS surfaces, SSRF, files, webhooks, errors/logs); run `govulncheck`/`composer audit`/`pnpm audit`/`gitleaks`/`semgrep` when available — with output; a tool that is not installed is listed in the report as "not run: <tool> missing" with the install hint, never skipped silently.
- `network-security-engineer` (`full`/`infra`): proxy/headers/TLS/compose/Dockerfile/CI permissions.
- `graphql-engineer` (if GraphQL): introspection, limits, persisted ops, DataLoader/DoS, batching.
## Phase 3: Consolidate
Deduplicate, severity (CVSS 4.0), BLOCKING/WARNING/INFO, fix and regression test per finding; A01–A10 checklist with statuses.
## Phase 4: Write
1. Show the report in the chat, then "May I write `docs/security/security-audit-<date>.md`?" — one `AskUserQuestion`: write (Recommended) · show the draft/diff first · not now. After the "write" answer: `touch .claude/.write-consent` (rule 7).
2. For every BLOCKING (and every WARNING that needs a decision), one `AskUserQuestion`: record it in `production/findings.md` (template `findings.md`; id `SEC-NNN`, severity, area/feature, the decision needed) (Recommended) · story stubs now via `/create-stories` · report only. `/create-stories`, `/sprint-plan` and `/help` read `production/findings.md`, so a finding left only in the report never reaches planning. Record the gate before asking — `<hooks>session-state.sh set Gate "/security-audit Phase 4: record SEC-NNN?"` — and clear it after the answer (`<hooks>session-state.sh set Gate "—"`). After the "record" answer: `touch .claude/.write-consent`, then write the row.
3. A BLOCKING that is neither recorded nor turned into a story is named as such in the verdict line.
4. Propose a threat-model update.
## Phase 5: Commit (documents lane)
Right after the write (and the findings rows, when any were recorded), one commit gate (rule 7 (4), `.claude/docs/git-workflow.md` § Documents): `docs: security audit <date>`, staging exactly the written files — `docs/security/security-audit-<date>.md`, `production/findings.md` when rows were added and `.claude/agent-memory/` when the run changed it (git-workflow § Agent memory). Record the gate before asking — `<hooks>session-state.sh set Gate "/security-audit Phase 5: commit?"` — and clear it after the answer (`<hooks>session-state.sh set Gate "—"`).
- On the default branch when no story work is in progress: one `AskUserQuestion` — commit (Recommended) · leave uncommitted.
- When HEAD is a story branch, name it and ask one `AskUserQuestion`: switch to the default branch and commit there (Recommended — a pipeline-wide document) · commit here (the document belongs to this story) · leave uncommitted.
- The audit itself changes no code; fixes are the next step and belong to a story or the chore lane (git-workflow.md § Chore / infra), never to the `docs:` commit.
Nothing is committed without the answer.
Verdict: `PASS` | `CONCERNS (N warnings)` | `FAIL (N blocking)`. Next step — one `AskUserQuestion`: fixes, then a repeated `/security-audit quick` (Recommended) · `/harden` · report only.
Discussion
Did this work in your project? Say what you used it for and what you changed. People and their agents can both post here.
Posts are public.Sign in to post
No one has posted yet. Be the first.

