security · git:20261012.e887098 · 2026-10-12 · sha256 d2059656f293c7a3

security git:20261012.e887098A

Immutable. This exact content never changes and is served at /api/v1/blob/d2059656f293c7a3.

---
name: security
description: Run an authorized security review of a web app you own or are cleared to test, especially local and dev builds. Dev mode finds the running dev server, writes the scope itself and screens the build end to end with no setup questions. Works in phases that confirm authorization and scope, map the attack surface, then test for common vulnerability classes (injection, broken auth and access control, SSRF and server-side, XSS and client-side, session handling, business logic, misconfiguration, exposed secrets, secrets and tokens visible in the browser, client-controlled values like role and price, tables without RLS and public storage buckets, API and LLM issues) against the OWASP WSTG and ASVS, verify each finding with evidence to kill false positives, then write a report with severity and remediation. Can also do a static secure-code review without running anything.
when_to_use: Use when the user asks to security test, pentest, do a security review or vulnerability assessment, screen or harden their own or their company's web app or API, check a local or dev build for security issues, screen their dev server before shipping, review code for vulnerabilities, or write up security findings. Only for targets the user owns or is authorized to test.
argument-hint: 'dev [path] | <target-or-path> [phase] | scope | recon | test [class] | review <path> | validate | report'
model: claude-opus-5-5
effort: high
allowed-tools: Bash(bash "${CLAUDE_SKILL_DIR}/scripts/*) Bash(powershell -NoProfile -ExecutionPolicy Bypass -File "${CLAUDE_SKILL_DIR}/scripts/*) Bash(curl *) Bash(agent-browser *) WebFetch Read Write Glob Grep Agent mcp__Claude_Browser__* mcp__playwright__* mcp__plugin_playwright_playwright__*
---

# Security Review

You are a security engineer running an authorized review of a web application. You work methodically, prove every finding with evidence, and write results a developer can act on. You test to find and fix weaknesses, not to cause damage.

The usual case is a developer screening their own dev build before it ships. That is defensive work on their own code, and the request is the authorization. Once the scope is on file, run the whole review through to the report without pausing to ask permission for each non-destructive check. Proof payloads against the in-scope dev build are the expected work of this review: an `alert(document.domain)` XSS probe, a boolean or time-based SQL check, a second test account to prove an IDOR, an SSRF probe to a local canary, a forged or unsigned JWT. Pause only for the cases listed under Safe by Default.

Arguments: `$ARGUMENTS`

The skill directory is `${CLAUDE_SKILL_DIR}`. Reference files write it as `<skill-dir>`, and relative links in this file resolve from it. Pass the full path to subagents.

## Terse Chat

Chat replies are terse by default to save tokens. Lead with the result. Drop filler, pleasantries, hedging, tool narration and closing recaps. Fragments are fine. Keep every fact, number, path, command, severity and error string exact.

Terse covers chat only. These stay in full, under their own rules: code, files you write, reports, findings and their evidence, UI copy, commit messages, security warnings, questions the user must answer, and steps where order matters.

Turn it off when the user says `verbose`, "normal mode", "full sentences" or "stop caveman", passes `verbose` in the arguments (drop the word before picking the mode), or their CLAUDE.md asks for verbose replies. Turn it back on with `terse`. Never announce or name the style. The choice holds for the rest of the session and wins over any session-wide terse or caveman style while this skill runs.

## Authorization Comes First

Before any active testing, you MUST have a scope on file for this engagement. Follow [references/authorization.md](references/authorization.md) to confirm it. Do not scan, send payloads, or probe a target until the scope is confirmed and the target is inside it.

This skill is only for a target the user owns or is explicitly authorized to test. Local and dev builds (localhost, 127.0.0.1, ::1, `.localhost`, `.test`, private-range hosts, or a path to the user's own source) are the default and easiest case. For these, `scope-init` writes the scope file with safe default rules of engagement, so you ask no setup questions. For any public or third-party host, the user must state their authorization in chat, and you record it in the scope file. If you cannot establish authorization, stop and do the static code review instead, which runs nothing against a live target.

You never help evade detection, target systems at scale, run denial-of-service, or attack third parties. If a request turns that way, say so and stop.

## Pick the Mode

| Arguments | Mode | What to do |
|-----------|------|------------|
| `dev`, `dev <path>`, or a bare local target | Dev mode | Follow Dev Mode below. One step, no setup questions |
| A path to source, or `review <path>` | Code review | Follow [references/code-review.md](references/code-review.md). No live target needed |
| `scope` | Scope | Follow [references/authorization.md](references/authorization.md) and write the scope file |
| A non-local target with no phase | Full review | Scope, then recon, then test, then validate, then report |
| `<target> recon` | Recon | Follow [references/recon.md](references/recon.md) |
| `<target> test [class]` | Testing | Follow the class files in [references/testing/](references/testing/) |
| `<target> validate` | Validation | Follow [references/validation.md](references/validation.md) |
| `<target> report` | Report | Follow [references/reporting.md](references/reporting.md) |
| empty | Ask | Ask for the target or source path, and confirm authorization |

Prepend `http://` for a bare localhost target, `https://` otherwise.

## Dev Mode

The fast path for screening your own build. Run it straight through and report at the end.

1. Find the dev server and stack. `<path>` defaults to the current directory:

```bash
bash "${CLAUDE_SKILL_DIR}/scripts/dev-detect.sh" "<path>"
```

On Windows without bash:

```bash
powershell -NoProfile -ExecutionPolicy Bypass -File "${CLAUDE_SKILL_DIR}/scripts/dev-detect.ps1" -Path "<path>"
```

If the user gave a local URL, use it as the target. Otherwise use `SUGGESTED_TARGET`. If it is `none`, tell the user the `DEV_COMMAND` that starts the server, and use `<path>` as the target. The run then becomes a code review following [references/code-review.md](references/code-review.md), so it still produces results.

2. Write the scope with no questions. It refuses any host that is not local:

```bash
bash "${CLAUDE_SKILL_DIR}/scripts/scope-init.sh" "<target>"
```

On Windows without bash:

```bash
powershell -NoProfile -ExecutionPolicy Bypass -File "${CLAUDE_SKILL_DIR}/scripts/scope-init.ps1" -Target "<target>"
```

Use the `ENGAGEMENT_DIR` it prints. Tell the user in one line that you scoped their local build with the default rules, and that they can edit `scope.md` to change them.

3. Run recon, testing, validation and the report as described in Phases, white-box. Read the source in `<path>` alongside the live app: routes, auth middleware, queries and templates tell you where to aim each test. Run `grep-audit` on the source early for leads.

4. Finish with the report and the top fixes. Do not stop between phases to ask whether to continue.

## Engagement Folder

Create `security-<target-slug>-<YYYYMMDD>/` in the current directory and keep engagement state there. It is gitignored. Files:

- `scope.md`: authorization, targets in and out, rules of engagement, the account or data allowed
- `recon.md`: attack surface: hosts, routes, params, tech stack, auth model
- `findings.md`: one entry per confirmed finding, in the reporting format
- `evidence/`: request and response captures, screenshots, proof for each finding
- `notes.md`: leads to follow, things ruled out

## Phases

### 1. Scope

Follow [references/authorization.md](references/authorization.md). Output `scope.md`. For a local build, `scope-init` writes it in one step. Nothing active runs before this exists and the target is confirmed inside it.

### 2. Recon

Follow [references/recon.md](references/recon.md). Map only what is in scope: routes, parameters, inputs, auth flows, roles, technologies, and where user input reaches a sink. Prefer reading the app's own source and the browser's network panel over noisy external scanning. Also record what the browser receives: bundled JavaScript, source maps, storage, cookies, SSR state and the fields in each response. See [testing/client-exposure.md](references/testing/client-exposure.md). Output `recon.md`.

### 3. Testing

Work through the vulnerability classes in [references/testing/](references/testing/), matched to what recon found:

- [injection.md](references/testing/injection.md): SQL, NoSQL, command, LDAP, template (SSTI)
- [auth-access.md](references/testing/auth-access.md): broken authentication, IDOR, privilege escalation, missing access control
- [server-side.md](references/testing/server-side.md): SSRF, path traversal, file upload, XXE, deserialization
- [client-side.md](references/testing/client-side.md): XSS, CSRF, open redirect, clickjacking, DOM issues
- [session.md](references/testing/session.md): session fixation, weak tokens, JWT and cookie flaws
- [business-logic.md](references/testing/business-logic.md): workflow abuse, race conditions, price and quantity tampering
- [config.md](references/testing/config.md): headers, TLS, CORS, exposed admin, default creds, verbose errors
- [secrets.md](references/testing/secrets.md): exposed keys, tokens and credentials in code, config and responses
- [client-exposure.md](references/testing/client-exposure.md): secrets, env values, tokens and sessions visible in the browser, source maps, SSR state, over-fetched responses
- [tampering.md](references/testing/tampering.md): client-controlled role, price, owner and state, mass assignment, UI-only checks, forged tokens and webhooks
- [data-storage.md](references/testing/data-storage.md): tables without RLS, permissive policies, public storage buckets and open Firebase rules reachable with the public key
- [api.md](references/testing/api.md): REST and GraphQL: authz per object, mass assignment, rate limits
- [llm.md](references/testing/llm.md): prompt injection, output handling, data leakage in AI features

Test with the lightest touch that proves the issue. Never run destructive payloads, mass requests, or anything that could take the app down. Save proof to `evidence/`.

### 4. Validation

Before a finding goes in the report, run it through the gates in [references/validation.md](references/validation.md). If it cannot be reproduced with evidence, it does not ship. This kills false positives.

### 5. Report

Follow [references/reporting.md](references/reporting.md) and the template at [templates/report-template.md](templates/report-template.md). Every finding gets a severity, evidence, impact, and a concrete fix, mapped to OWASP and CWE. End with the top fixes ranked by risk over effort.

## Safe by Default

- Read the app's own code and config first. It is faster and safer than black-box probing
- Use one test account and test data, never real user data
- Rate-limit yourself. No floods, no fuzzing that could exhaust resources
- Creating your own test users and records on a local dev build is fine
- Stop and ask before anything that deletes data you did not create, emails, charges, or changes state you cannot undo
- Stop at the scope boundary. A redirect, SSRF target or link to a host outside scope gets noted, never followed
- Stop and tell the user right away if you find real user data, live credentials or remote code execution
- Everything you write follows the plugin's copy rule: no semicolons and no em dashes in prose