DEV Community

luijhy michael guerra flores
luijhy michael guerra flores

Posted on

A Claude Code /review skill that caught an auth bypass, SQL injection and a leaked secret (full SKILL.md)

Claude Code skills are Markdown files that teach Claude a repeatable procedure. You drop one in .claude/skills/<name>/SKILL.md and call it with /<name>, or Claude picks it up when your request matches its description.

Here is the code review skill I use every day, complete and free to copy, plus an unedited run of it against a deliberately broken auth refactor.

The skill

Save this as .claude/skills/review/SKILL.md in your repo (or in ~/.claude/skills/review/SKILL.md to have it everywhere):

---
name: review
description: "Reviews the current diff (or a branch) for bugs, security issues and debt, and returns prioritized findings. Use when the user says \"review\", \"code review\" or \"what do you think of these changes\"."
---

# Code review

1. Get the diff: `git diff` + `git diff --staged`, or `git diff <base>...HEAD` if the user names a branch.
2. Read the context you need from every touched file (not just the diff lines).
3. Look for, in this order:
   1. **Correctness**: edge cases, null/undefined, async without `await`, race conditions, off-by-one, error handling that swallows exceptions.
   2. **Security**: injection (SQL, shell, XSS), secrets in code, input validation, missing authorization in resolvers/endpoints, sensitive data in logs.
   3. **Data and API**: irreversible migrations, breaking contract changes (REST/GraphQL), N+1 in resolvers.
   4. **Performance**: unnecessary React renders, effects with wrong dependencies, queries in loops.
   5. **Maintainability**: duplication, confusing names, dead code, missing tests for new logic.
4. Return a table ordered by severity:

   | Sev. | File:line | Problem | Suggestion |
   |------|-----------|---------|------------|
   | ๐Ÿ”ด high / ๐ŸŸก medium / โšช minor | ... | ... | ... |

5. Only report what you can justify with a concrete scenario. If you find nothing serious, say so. Do not apply changes unless the user asks.
Enter fullscreen mode Exit fullscreen mode

Three details make it work better than "review my code":

  1. It reads the whole touched file, not just the diff. Most real bugs live in how the changed lines interact with the unchanged ones.
  2. A fixed checklist order. Correctness and security come before style, so the important findings don't get buried under naming nits.
  3. "Only report what you can justify with a concrete scenario." This one line removes most of the vague, generic advice LLM reviews tend to produce.

A real run

I made a test repo with an auth refactor that introduces three bugs on purpose: an auth bypass, a secret written to the logs, and a SQL injection. Then I staged it and typed /review. This is the output, unedited (Claude Code 2.1.293):

Sev. File:line Problem Suggestion
๐Ÿ”ด high src/middleware/auth.ts:8-9 Auth bypass. verifyToken now returns null for an invalid or expired token. The middleware still sets req.user = null and calls next(). A request with Authorization: Bearer garbage therefore passes requireAuth. Any handler that only checks the middleware, or reads req.user?.sub loosely, is exposed. After verifying, add if (!payload) return res.status(401).json({ error: "invalid token" }); before next().
๐Ÿ”ด high src/auth/service.ts:21 SQL injection. findUserByEmail interpolates email straight into the query. An input like ' OR '1'='1 returns arbitrary users, and '; DROP TABLE users;-- can run further statements, depending on the driver. Use a parameterized query, e.g. db.query("SELECT * FROM users WHERE email = $1", [email]), with the placeholder syntax your driver uses. Replace db: any with a real type, and select only the columns you need instead of *.
๐Ÿ”ด high src/auth/service.ts:4 Secret in logs. console.log("auth init", config.JWT_SECRET) writes the JWT signing secret to stdout on every start. Anyone with log access can forge valid tokens. Delete the line. If you need a startup message, log without the secret.
๐ŸŸก medium src/auth/service.ts:13-17 catch {} swallows every error and returns null. A bad token, an expired token and a misconfigured secret all look the same, which makes failures hard to diagnose. jwt.verify can also return a string payload, so callers can't rely on .sub. Return a typed result, such as `{ sub: string } \
๐ŸŸก medium {% raw %}src/middleware/auth.ts:6 replace("Bearer ", "") doesn't check the scheme. A header of Basic xyz becomes Basic xyz and is passed to verify. That is harmless once the bypass is fixed, but sloppy. Match with /^Bearer (.+)$/ and return 401 if it doesn't match.
โšช minor src/middleware/auth.ts:4 Dropping async is correct now that verifyToken is synchronous. None. This is fine as is.
โšช minor src/auth/service.ts There are no tests for verifyToken or findUserByEmail. A test for "invalid token returns 401" would have caught the bypass. Add tests for valid, expired, malformed and missing tokens.

I recommend not merging until the three ๐Ÿ”ด items are fixed. I haven't changed anything. Tell me if you want me to apply the fixes.

All three planted bugs were found, ranked first, and each came with a concrete exploit scenario and fix. It also didn't touch any code, because the skill says not to unless asked.

Make it yours

  • Add your stack's usual suspects to step 3 (e.g. "missing key in React lists", "unbounded GraphQL queries").
  • If you want it to trigger without typing /review, put the phrases you naturally use in the description ("check my changes", "anything wrong here?").
  • Keep the severity table: it makes the result scannable and easy to paste into a PR.

If you want more like this, the Starter Kit for Claude Code (US$9, unofficial) has 5 more skills in the same style (/commit, /pr, /tests, /plan, /debug), safety hooks that block rm -rf, force-push and leaked secrets (with 27 tests), CLAUDE.md templates for React, Node and GraphQL, and permission presets: https://luijhy.gumroad.com/l/starter-kit-for-claude-code

The safety hooks alone are free here: https://github.com/kailucho/claude-code-hooks-seguridad

Top comments (0)