From ceej-skills
Use when reviewing code for security — threat-modeling a change or service, auditing untrusted-input handling, secrets or PHI exposure, injection, auth, crypto, panics-as-DoS, or supply-chain risk. Triggers on "security review", "is this safe to expose", "threat model this", "check for vulnerabilities", "audit before it takes untrusted input", "HIPAA review". Rust-shaped but applies to any language. Produces ranked, exploitable-first findings with an attacker path, a CWE reference, and the smallest fix.
How this skill is triggered — by the user, by Claude, or both
Slash command
/ceej-skills:rust-security-reviewThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
The security counterpart to `rust-project-review` and `rust-change-review`. Same evidence
The security counterpart to rust-project-review and rust-change-review. Same evidence
discipline — file, line, smallest fix — but the lens is "what can an attacker do?" rather than
"is this clean code?". Can run over a whole service or a single diff; the threat surface scales
to the scope.
Core principle: every finding needs an attacker path, not a theory. "Uses format! in a
query" is not a finding; "src/repo.rs:88 interpolates the user-supplied tenant into the SQL
string via format!, and tenant arrives unvalidated from the /search query param
(handlers.rs:31) — SQL injection, CWE-89" is. A vulnerability nobody can reach is, at most, a
defense-in-depth note — mark it as such and rank it below anything exploitable.
Security review drowns in theoretical findings if you let it. The job is to find the handful of things an attacker can actually do, ranked, with the smallest fix for each — not to recite the OWASP list.
Establish what's under review and, crucially, where the trust boundary sits:
gh pr diff / git diff. Ask the narrower question: does this change
add attacker-reachable surface, weaken an existing control, or handle a new asset (PHI,
secrets, tokens)? A diff that touches none of those is a short review — say so.Review only. Don't fix in this pass. And never paste a real secret or real PHI into the findings — reference the location, redact the value.
Four questions, answered explicitly at the top of the output:
sqlx bind params / query macros, never format!/+ into SQL
(CWE-89). Watch dynamic ORDER BY/identifiers — those need allow-listing, not binding.std::process::Command with attacker args (CWE-78); path
joins from user input without canonicalize + prefix check (path traversal, CWE-22); any
user-controlled format/template string.serde over untrusted input with no size/shape limits;
zip/gzip/JSON bombs; unbounded Vec/String allocation from a length field (CWE-502, CWE-400)..env; secrets not
leaking through a derived Debug/Display, an error message, or a log line (CWE-532, CWE-798)..unwrap()/.expect()/arr[i]/integer overflow in
a server is a denial-of-service vector, not a style nit (CWE-248, CWE-400). Bounds-checked
access, checked_*/saturating_* arithmetic on attacker-influenced numbers.unsafe on attacker bytes — any unsafe touching untrusted input is a top finding unless
the // SAFETY: invariant provably holds for hostile input. transmute of attacker bytes is a
red flag.ring, rustls, aws-lc-rs); no MD5/SHA-1 for security
(CWE-327); constant-time comparison for secrets/MACs (CWE-208); CSPRNG (OsRng) for keys/tokens,
not a fast PRNG; TLS verification never disabled "to make it work" (CWE-295).cargo audit (RUSTSEC advisories), cargo deny check (advisories + bans + licenses +
sources). Eyeball Cargo.lock churn for unexpected new transitive deps; watch typosquatted
crate names; treat a new build.rs or proc-macro dependency as code that runs on your machine
(CWE-1357).Run, scoped to the touched crate(s) where possible:
cargo audit — RUSTSEC advisories. Blocking for anything network-facing or pre-release.cargo deny check — advisories + bans + licenses + sources in one gate.cargo-geiger (if available) — unsafe surface across the dependency tree.semgrep / cargo-vet pass if configured.If a tool isn't installed or the code won't build, say so explicitly — don't silently skip a supply-chain gate.
Use the standard security tiers, not the project-review ones:
CVSS is the one number allowed — and only on Critical/High, because it's an external standard, not a vibe. No invented "security score out of 10". Always attach a CWE id; it makes the finding searchable and unambiguous.
## Scope & threat model
- Under review: <service / diff / commit range>
- Trust boundaries: <where untrusted data enters>
- Assets: <PHI, secrets, tokens, availability, …>
- Attacker assumed: <unauth remote / cross-tenant / malicious upstream / build-time>
## What's solid
<One or two sentences on controls that are correctly in place — so the fixes land in context.>
## Findings (ranked, exploitable-first)
**Critical**
1. `<file:line>` — <vuln> (CWE-NNN[, CVSS x.x]). **Attack path:** <how it's reached>.
**Fix:** <smallest change that closes it>. **Verify:** <how to confirm it's closed>.
**High** / **Medium** / **Low — hardening**
...
## Tooling
- `cargo audit`: ...
- `cargo deny check`: ...
(One line each. "Not run — <reason>" is acceptable.)
## Verdict
<"Safe to expose", "One critical must-fix before it takes untrusted input", etc.>
## Recommended next action
<Single concrete step, or "None — no exploitable issue found.">
| Don't | Why |
|---|---|
| List a vuln with no attacker path | If nothing can reach it, it's a hardening note at most. Rank it accordingly or cut it. |
| Dump the OWASP / CWE catalog | Recite-the-list isn't review. Find the few things reachable here. |
| Inflate severity to look thorough | Critical means exploitable now. Crying wolf gets the whole review ignored. |
| Recommend adopting a security framework | This is a review. Name the smallest fix for the concrete hole. |
| Paste the secret or PHI you found | Reference the location, redact the value — the finding shouldn't leak the asset. |
| Invent a numeric "security score" | Feels rigorous, isn't. CWE always, CVSS where it helps, no vibe grades. |
| Manufacture findings on safe code | If the attack surface is clean, "no exploitable issue found" is the review. |
| Conflate defense-in-depth with exploitable-now | Both are worth saying — but not at the same severity. Keep them in separate tiers. |
Replace with notes for the repository under review. Default posture for these projects is HIPAA, so unless told otherwise:
.env; confirm they don't
surface through a derived Debug.npx claudepluginhub ceejbot/ceej-skills --plugin ceej-skillsGuides creation, editing, and verification of skills for AI coding agents using test-driven development with subagent scenarios. Use when authoring or debugging skills.