rust-review
Performs comprehensive Rust security review for safe/unsafe boundary issues, memory safety in unsafe blocks, concurrency hazards, panic-induced DoS, FFI safety, and async runtime mistakes
Install / Use
npx skills add trailofbits/skills --skill rust-reviewInstalls into whichever agent you are using.
SKILL.md
Installable skill definition
Quality Score
Category
SecuritySupported Platforms
Our assessment of rust-review
rust-review scores 87/100 on our quality scale, 492nd of 774 Security skills we index.
Its SKILL.md is 43 KB long, well organised into 43 sections with 11 code examples: long enough that it reads more like full documentation than a focused instruction file, which agents can find harder to follow.
With 7,225 GitHub stars, it is one of the more widely adopted skills in the catalogue.
Maintenance, license and trust
- The repository was last updated 4 days ago, so rust-review is actively maintained.
- It is released under the CC-BY-SA-4.0 license; check its terms before commercial use.
- Its trust signals score 100/100, with no cautions. These come from repository metadata, not a code audit — read the skill file before letting an agent act on it.
rust-review compared with similar skills
All 4 of these similar skills score higher than rust-review; compare them before choosing.
| Skill | Score | Stars | Updated | Format |
|---|---|---|---|---|
| rust-review (this skill)by trailofbits | 87 | 7.2k | 4d ago | SKILL.md |
| algorithmic-artby anthropics | 100 | 177.9k | 5d ago | SKILL.md |
| pptxby anthropics | 100 | 177.9k | 5d ago | SKILL.md |
| designby nextlevelbuilder | 100 | 130.2k | 6d ago | SKILL.md |
| ui-ux-pro-maxby nextlevelbuilder | 100 | 130.2k | 6d ago | SKILL.md |
Frequently asked questions
- How do I install rust-review?
- Run
npx skills add trailofbits/skills --skill rust-review. The install tabs above show the steps for each supported agent. - Which AI agents does rust-review work with?
- It is written for Universal, as a SKILL.md file. Other agents that read the same format can often use it too.
- Is rust-review safe to use?
- It is CC-BY-SA-4.0-licensed and scores 100/100 on trust signals. Skills are instructions an agent will follow, so read the file before installing it and do not approve commands you do not understand.
- Is rust-review still maintained?
- The repository was last updated 4 days ago, so rust-review is actively maintained.
Skill content
View source on GitHubname: rust-review
description: Performs comprehensive Rust security review for safe/unsafe boundary issues, memory safety in unsafe blocks, concurrency hazards, panic-induced DoS, FFI safety, and async runtime mistakes. Use when auditing Rust crates, services, or libraries — particularly those with unsafe, FFI, or concurrent code.
allowed-tools: Agent AskUserQuestion SendMessage TaskCreate TaskUpdate TaskList Read Write Bash
Rust Security Review
Runs in the main conversation (invoke via /rust-review:rust-review). Orchestrator owns the Task* ledger as bookkeeping for retries; workers and judges have no Task tools. Workers and judges are named plugin subagents (rust-review:rust-review-worker, rust-review:rust-review-dedup-judge, rust-review:rust-review-fp-judge); tool sets are declared in plugins/rust-review/agents/*.md. Findings are exchanged via markdown-with-YAML files in a shared output directory.
When to Use
Rust application/library security review: safe/unsafe boundary auditing, memory safety in unsafe blocks, concurrency hazards, panic-induced DoS on servers, FFI safety, async-runtime mistakes.
When NOT to Use
- Pure-C / pure-C++ codebases — use
c-reviewinstead. - Smart contracts (Solana programs / NEAR contracts / Ink!) — use
solana-vulnerability-scanneror the contract-specific skill. - Kernel-mode Rust drivers without userspace allocator — coverage is incomplete; flag as advisory only.
- Secrets/key memory hygiene (zeroization,
Zeroize/ZeroizeOnDrop/secrecyusage, lingering stack/heap copies) — use thezeroize-auditskill; rust-review does not cover memory zeroization.
Subagents
| Subagent type | Purpose | Tool set |
|---|---|---|
| rust-review:rust-review-worker | Run assigned cluster, write findings | Read, Write, Edit, Bash |
| rust-review:rust-review-dedup-judge | Merge duplicates (runs first) | Read, Write, Edit, Glob |
| rust-review:rust-review-fp-judge | FP + severity + final reports (runs second) | Read, Write, Edit, Bash |
Tools come from each agent's frontmatter at spawn time. The orchestrator's Task*/Agent/Bash/etc. come from this skill's allowed-tools. Search-tool / Bash interaction: in current Claude Code, an agent granted Bash is not also granted the dedicated Glob or Grep tools (the calls return No such tool available; the harness expects find/grep/rg via Bash instead). So only the dedup-judge — the one agent that holds no Bash — uses Glob; the worker, fp-judge, and the orchestrator resolve and search paths with Read / Bash find / rg / grep / test -f instead. Because the cluster/finder prompt seeds are written in ripgrep regex syntax (\s, \d, \b), Bash-holding agents must run them with rg. If rg is not installed its call fails loudly (command not found) — fall back to grep -E with POSIX classes (\s→[[:space:]], \d→[[:digit:]], drop \b), never a raw-\s grep whose silent empty becomes a bad cleared. Do not reintroduce Glob/Grep into a Bash-holding agent's protocol.
Architecture
coordinator: write context.md → build_run_plan.py → TaskCreate × M
→ spawn primer (foreground) → spawn M workers (parallel)
→ classify Phase-7 outcomes + write findings-index.txt
→ dedup-judge → fp-judge → report safety net (SARIF + REPORT.md) → return REPORT.md
Output directory contains: context.md, plan.json, worker-prompts/, findings/, findings-index.d/ (per-worker shards), findings-index.txt, coverage/ (per-worker coverage-gate files), run-summary.md, dedup-summary.md, fp-summary.md, REPORT.md, REPORT.sarif.
Path convention: every later phase shells out to ${RUST_REVIEW_PLUGIN_ROOT}/scripts/*.py, so resolve that variable first to the plugin directory that contains prompts/clusters/unsafe-boundary.md (and scripts/build_run_plan.py). Try in order, first hit wins:
- Native Claude Code —
${CLAUDE_PLUGIN_ROOT}, accepted ifBash: ls "${CLAUDE_PLUGIN_ROOT}/prompts/clusters/unsafe-boundary.md"resolves. - Codex —
${CODEX_PLUGIN_ROOT}(set it the same way if that var is present and resolves the marker). - Fallback search — covers Codex installs under
~/.codex, Claude installs under~/.claude, and a local checkout / repo run:Bash: find ~/.claude ~/.codex . -path '*/plugins/rust-review/prompts/clusters/unsafe-boundary.md' -print -quit 2>/dev/null. Take the match and strip the trailing/prompts/clusters/unsafe-boundary.mdto get the root (the home dirs are searched before.so an installed copy wins over any vendored copy in the audited repo).
Set RUST_REVIEW_PLUGIN_ROOT to the resolved root. If all three fail, abort with a message naming the roots searched — do not enter Phase 4 with an empty variable (every uv run --no-project "${RUST_REVIEW_PLUGIN_ROOT}/scripts/..." call would fail with a confusing path error).
Scope convention: keep two scopes separate throughout the run:
finding_scope_root— the user-requested audit subtree. Workers may only file findings whose vulnerable location is inside this subtree.context_roots— read-only repo roots/files workers and judges may inspect to verify reachability, callers, wrappers, build flags, mitigations, and threat-model details. Default to.unless the user explicitly forbids broader context. Reading context outsidefinding_scope_rootis allowed; filing findings there is not.
Rationalizations to Reject
- "
unsafeis rare, so hand-skip the memory-safety cluster." Don't edit the cluster list — sethas_unsafeaccurately in Phase 1 and letbuild_run_plan.pydecide. Every memory-safety bug class (UAF, double-free, uninitialized reads,Vec::set_len, union UB) requiresunsafe, so the planner runs the wholememory-safetycluster whenhas_unsafe=trueand correctly omits it whenfalse— there is no "run it anyway." The unsafe-boundary cluster is different: it has norequiresand always runs (consolidated; its safety-doc andrepr(C)hygiene apply to FFI declarations even without visibleunsafe { }blocks). - "The compiler caught it." The borrow checker proves absence of safe-code data races; it proves nothing about unsafe blocks, panic reachability, ABBA deadlocks, atomic-load/store sequencing, or FFI ABI mismatch.
- "
unwrap()is fine if it's// SAFETY: documented infallible."// SAFETY:documentsunsafeoperations, not infallibility claims. Anunwrap()on documented-infallible input is still risky if the documentation is wrong — file as low severity and let the FP judge decide. - "
has_unsafe=falseso skip the run." Pure safe-Rust crates still have panic-DoS, atomic races, drop-panics, and trait-implementation hazards. Run the always-on clusters. - "Background spawns parallelize the workers." They do not —
Agentcalls in a single assistant message already run concurrently.run_in_background=truedefeats the Phase 6a primer cache, so every worker pays full cache-creation (cache_read_input_tokens=0) and the ~15 K-token primer is wasted M times. Default: omitrun_in_backgroundfrom worker spawns. - "I'll re-derive the cluster list / paths / pass prefixes inline instead of running
build_run_plan.py." The script is the only authority for selection and rendering. Paraphrasing it drops fields that the worker self-check requires, producingworker-N abort: spawn prompt malformed. Always run the script andRead plan.json. - "The run partially succeeded — I'll just write
REPORT.mdfrom what completed." Hiding partial runs behind a successful report is a correctness bug. If any Phase-5 cluster task is notcompleted, surface it prominently inrun-summary.mdand the final response. - "Zero findings — skip Phase 8." Always run both judges and Phase 8b: dedup-judge writes a minimal no-op
dedup-summary.mdon an empty index, fp-judge writes emptyREPORT.md/REPORT.sarif, and Phase 8b's SARIF generator emitsresults: []for the empty case. SARIF consumers depend on a stable artifact set. - "
Bash: ls README*is fine for the preflight." Under zsh, an unmatched glob aborts the whole compound command before2>/dev/nullruns. Usefind(never fails on no-match) — and notGlob, which is unavailable to an agent that also holdsBash.
Orchestration Workflow
Run these phases in the main conversation.
Phase 0: Parameter Collection
Entry: skill invoked. Exit: threat_model, worker_model, severity_filter resolved; scope_subpath resolved or set to "."; finding_scope_root=scope_subpath; context_roots resolved.
The skill is invoked directly (no command wrapper). Parse any free-text arguments the user passed on the /rust-review:rust-review line (e.g. flamenco only, high severity only, use haiku) and pre-fill the answers they imply — then ask for any missing required parameters with one AskUserQuestion call. Never silently default the required parameters.
Required parameters:
| Parameter | Values | How to infer from args |
|---|---|---|
| threat_model | REMOTE / LOCAL_UNPRIVILEGED / BOTH | Words like "remote", "network", "attacker" → REMOTE; "local", "unprivileged" → LOCAL_UNPRIVILEGED; otherwise ask. |
| worker_model | haiku / sonnet / opus | Explicit model name in args. Otherwise ask (no silent default). |
| severity_filter | all / medium / high | "all", "every", "noisy" → all; "medium and above" → medium; "high only", "criticals only" → high. Otherwise ask — no silent default. |
| scope_subpath | repo-relative directory (optional) | Phrases like "X only", "just audit X/", "review subdirectory X" → src/X/ or the matching subdir. Apply fuzzy matching against top-level subdirectories of the repo. If absent, set "."; if ambiguous, ask. |
Call AskUserQuestion exactly once with only unresolved required parameters (threat_model, worker_model, severity_filter) plus scope_subpath only when the user explicitly requested a narrowed scope but it is ambiguous. If the required parameters were all pre-filled and scope is absent or resolved, skip the question.
After resolving scope_subpath, set finding_scope_root="${scope_subpath:-.}". Set context_roots="." by default so workers can verify callers/build settings outside a narrowed subtree without filing out-of-scope findings. If the user explicitly asks to forbid broader context, set context_roots="${finding_scope_root}" and note that reachability confidence may be lower.
Phase 1: Prerequisites
Entry: Phase 0 complete. Exit: has_unsafe, has_ffi, has_concurrency, has_async, has_packed_repr, has_fs_io flags determined. Abort with a clear message if no *.rs files exist under ${finding_scope_root}.
First confirm uv is present (command -v uv) — every helper script from Phase 4 onward runs
through it. If missing, abort and tell the user to install it (brew install uv or
the official installer); nothing downstream can run without it.
Probe within ${finding_scope_root:-.} with the Bash commands below (non-empty output ⇒ flag true). The dedicated Grep/Glob tools are unavailable to this orchestrator because it holds Bash — use grep/rg/find via Bash. (The probe regexes use \s/\b; if your grep lacks GNU \s support, run them with rg -uu — which honors \s and still searches ignored files — or, if rg is not installed either, replace \s→[[:space:]] and drop \b. Widening is safe here: a false-positive capability flag only adds a harmless extra worker, whereas a missed match would skip a whole pass.)
# Rust source presence (precondition)
find "${finding_scope_root:-.}" -name '*.rs' -print -quit
# has_unsafe
grep -rlE '\bunsafe\s+(extern|fn|impl|trait)\b|\bunsafe\s*\{' --include='*.rs' "${finding_scope_root:-.}" | head -
Truncated for display — read the full file on GitHub.
Related Skills
algorithmic-art
177.9kCreating algorithmic art using p5.js with seeded randomness and interactive parameter exploration. Use this when users request creating art using code, generative art, algorithmic art, flow fields, or particle systems.
pptx
177.9kUse this skill any time a .pptx or .potx file is involved in any way — as input, output, or both. This includes: creating slide decks, pitch decks, or presentations; reading, parsing, or extracting text from any .pptx or .potx file (even if the extracted content will be used elsewhere, like in an em…
design
130.2kComprehensive design skill: brand identity, design tokens, UI styling, logo generation (55 styles, Gemini, Atlas Cloud, or MuAPI AI), corporate identity program (50 deliverables, CIP mockups), HTML presentations (Chart.js), banner design (22 styles, social/ads/web/print), icon design (15 styles, SVG…
ui-ux-pro-max
130.2kUI/UX design intelligence for web, mobile, and desktop. This skill should be used when designing, building, reviewing, or fixing interfaces, including pages, components, design systems, accessibility, interaction, responsive layout, typography, color, charts, and stack-specific UI implementation.
Languages
Trust signals
From repository metadata: license, adoption, age and documentation. Not a code audit — see the Safety scan above for what the skill file itself contains.
