$npx -y skills add kklimuk/docx-cli --skill security-reviewReview code for security vulnerabilities. Use when the user says 'security review', 'security audit', 'check for vulnerabilities', 'pentest the code', 'OWASP check', or any variation of wanting a security assessment.
| 1 | # Security Review |
| 2 | |
| 3 | Audit changed files for security vulnerabilities, focusing on the OWASP Top 10 and issues specific to the project's stack. |
| 4 | |
| 5 | When running locally as a forked subagent, the main session does not see any files you read or any reasoning you do — only the final report you return. When running in CI (e.g. via `claude-code-action`), the workflow takes the report and turns it into GitHub PR review comments. Either way, take your time, read every changed file completely, and produce a thorough, actionable report. The consumer of this report uses it as a worklist, so it must be complete and self-contained. |
| 6 | |
| 7 | ## Scope |
| 8 | |
| 9 | Determine the diff to review: |
| 10 | |
| 11 | 1. Run `git diff main...HEAD --name-only` to get files changed on this branch vs main. |
| 12 | 2. If that fails (no `main`, detached worktree, etc.), fall back to `git diff HEAD --name-only` for uncommitted changes, then `git diff --cached --name-only` for staged files. |
| 13 | 3. If no diff is available, ask the user which files to review. |
| 14 | |
| 15 | Read every changed file completely before starting the review. Read CLAUDE.md first to understand the project's stack and any subsystems with security-sensitive surface area (auth, real-time, payments, file uploads). |
| 16 | |
| 17 | ## What to Look For |
| 18 | |
| 19 | ### Injection & Input Handling |
| 20 | |
| 21 | - **SQL injection**: Raw SQL with string interpolation instead of parameterized queries. Check for any template literals that build SQL, and verify that database libraries are being used in their parameterized form. |
| 22 | - **Command injection**: User input passed to shell commands (`Bun.$`, `child_process`, `subprocess`, `os.system`) without sanitization. |
| 23 | - **XSS**: User-controlled data rendered as `dangerouslySetInnerHTML`, or reflected into HTML/JS without escaping. Check `contentEditable` fields that accept pasted HTML. |
| 24 | - **Path traversal**: User input used in file paths without validation. Check for `..` traversal. |
| 25 | - **Prototype pollution**: `Object.assign` or spread on user-controlled objects without allowlisting keys. |
| 26 | |
| 27 | ### Authentication & Authorization |
| 28 | |
| 29 | - **Missing auth checks**: Endpoints that read/write data without verifying the caller's identity or org membership. |
| 30 | - **IDOR (Insecure Direct Object Reference)**: Endpoints that accept an ID parameter and return/modify the resource without verifying the caller has access. Particularly dangerous when URL params (like a slug) aren't validated against the actual resource ownership. |
| 31 | - **Privilege escalation**: Actions that should be restricted (delete, move, admin operations) but aren't gated on role/permission. |
| 32 | |
| 33 | ### Data Exposure |
| 34 | |
| 35 | - **Over-fetching**: API responses that include more data than the client needs (e.g., internal IDs, secrets, full document state when only a title is needed). |
| 36 | - **Error leakage**: Stack traces, SQL errors, or internal paths exposed in error responses. |
| 37 | - **Sensitive data in logs**: Passwords, tokens, or PII logged to console. |
| 38 | |
| 39 | ### Real-time / WebSocket Security |
| 40 | |
| 41 | (Only relevant if the project has a WebSocket layer — see CLAUDE.md.) |
| 42 | |
| 43 | - **Channel authorization**: Can a client subscribe to any channel by guessing the name? Are channel subscriptions validated against user permissions? |
| 44 | - **Message spoofing**: Can a client broadcast messages to channels they shouldn't have write access to? |
| 45 | - **Payload validation**: Are incoming WebSocket messages validated before processing? |
| 46 | |
| 47 | ### Denial of Service |
| 48 | |
| 49 | - **Unbounded queries**: Endpoints that return all records without pagination or limits. |
| 50 | - **Regex DoS**: User input used in regex patterns without sanitization. |
| 51 | - **Resource exhaustion**: File uploads, large request bodies, or expensive operations without rate limiting or size limits. |
| 52 | |
| 53 | ### Cryptography & Secrets |
| 54 | |
| 55 | - **Hardcoded secrets**: API keys, passwords, or tokens in source code. |
| 56 | - **Weak randomness**: `Math.random()` / `random.random()` used for security-sensitive operations instead of `crypto.randomUUID()` / `secrets.token_*()`. |
| 57 | - **Missing TLS**: WebSocket connections using `ws://` in production contexts. |
| 58 | |
| 59 | ### Dependencies |
| 60 | |
| 61 | - **Known vulnerabilities**: If `bun audit` / `npm audit` / `pip-audit` is available, check for known CVEs. |
| 62 | - **Prototype pollution via deps**: Libraries that merge user input deeply. |
| 63 | |
| 64 | ## Report Format |
| 65 | |
| 66 | Return the **complete formatted report** as your final message — not a summary or TL;DR. Whatever consumes the report (a main Claude session locally, or a CI workflow that posts inline GitHub PR comments) uses it as a worklist, so it must be self-contained. |
| 67 | |
| 68 | Organize findings by severity: |
| 69 | |
| 70 | ### Critical |
| 71 | Exploitable now with no authentication required. D |