Skip to content
Security
Skill

/c-review

Performs comprehensive C/C++ security review for memory corruption, integer overflows, race conditions, and platform-specific vulnerabilities. Use when auditing native C/C++ applications, reviewing daemons or services for memory safety, or hunting integer overflow /

From plugin
trailofbits-skills
7.1k81 skills30 agents8 commands2 MCP
Install
$ npx -y skills add trailofbits/skills --skill c-review --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/c-review

Context preview

The summary Claude sees to decide when to auto-load this skill.

Performs comprehensive C/C++ security review for memory corruption, integer overflows, race conditions, and platform-specific vulnerabilities. Use when auditing native C/C++ applications, reviewing daemons or services for memory safety, or hunting integer overflow /

SKILL.md

c-review.SKILL.md
name: c-review
description: Performs comprehensive C/C++ security review for memory corruption, integer overflows, race conditions, and platform-specific vulnerabilities. Use when auditing native C/C++ applications, reviewing daemons or services for memory safety, or hunting integer overflow / use-after-free / race conditions in userspace code.
allowed-tools: Workflow AskUserQuestion Bash Read

C/C++ Security Review

Resolve four parameters, make one `Workflow` call, return the report. The workflow owns concurrency, retries and result collection.

**Use for:** native C/C++ userspace — memory safety, integer overflow, races, type confusion, Linux/macOS daemons, Windows services.

**Not for:** kernel drivers or modules; managed languages (Java, C#, Python, Go, Rust); embedded or bare-metal code with no libc.

Phase 0 — Parameters

Parse any free text on the invocation line (`flamenco only`, `high severity only`, `use haiku`) and pre-fill what it implies. Then make **one** `AskUserQuestion` call for whatever is still unresolved. Never silently default a required parameter.

| Parameter | Values | Inferring it from the invocation | |---|---|---| | `threat_model` | `REMOTE` / `LOCAL_UNPRIVILEGED` / `BOTH` | "remote", "network", "attacker" → `REMOTE`; "local", "unprivileged" → `LOCAL_UNPRIVILEGED`; otherwise ask | | `worker_model` | `haiku` / `sonnet` / `opus` / `inherit` | An explicit model name. Otherwise ask. `inherit` uses the session model | | `severity_filter` | `all` / `medium` / `high` | "all", "every", "noisy" → `all`; "medium and above" → `medium`; "high only" → `high`; otherwise ask | | `scope_subpath` | repo-relative directory, optional | "X only", "just audit X/" → the matching subdirectory, fuzzy-matched against top-level dirs. Absent → `.`. Ambiguous → ask |

Two scopes stay separate for the whole run:

  • **`finding_scope_root`** = `scope_subpath` (default `.`) — a finding must live inside

it, and it is the tree the unit list is generated from.

  • **`context_roots`** = `.` — read freely to establish callers, build flags and

reachability. Narrow it to `finding_scope_root` only if the user explicitly forbids wider reading, and say that reachability confidence drops when you do.

Phase 1 — Resolve paths

root="${CLAUDE_PLUGIN_ROOT:-}"
if [ -z "$root" ] || [ ! -f "$root/workflows/c-review.js" ]; then
  # Fallback for a cache layout that does not set the variable. ~/.claude ONLY — never `.`:
  # `.` is the AUDITED repository, and a tree that vendors or mirrors this marketplace would
  # win the traversal and run its copy of the scripts, with a different question set and
  # nothing saying which copy ran. Let find's stderr through; a missing ~/.claude is a real
  # failure to report, not noise to hide.
  hit="$(find "$HOME/.claude" -path '*/c-review/workflows/c-review.js' -print -quit)"
  root="${hit%/workflows/c-review.js}"
fi
[ -n "$root" ] && [ -f "$root/workflows/c-review.js" ] && echo "PLUGIN ROOT: $root"

Stop if neither resolves, rather than running with an empty path — and say which path you resolved, so a copy other than the installed plugin is visible before eight agents run against it.

# The workflow cannot call Date.now(), so the timestamp is made here.
output_dir="$(pwd)/.c-review-results/$(date -u +%Y%m%dT%H%M%SZ)"
mkdir -p "$output_dir"; echo "$output_dir"

# A Workflow script has no filesystem APIs, and `assemble_findings.py` resolves `--scope`
# against ITS OWN cwd. Resolve it once here and pass BOTH spellings, or the workflow strips
# `src/` from a finding's path while the assembler strips `/repo/src/`, and the two disagree
# about which findings are duplicates of each other.
scope_abs="$(cd "${scope_subpath:-.}" && pwd)" || echo "scope_subpath does not exist"
echo "$scope_abs"

`uv` must be on PATH: Detect runs the unit enumerator and Assemble runs `assemble_findings.py`. If `uv` is missing, say so and stop — the whole review is partitioned from that unit list.

Phase 2 — Run the workflow

Invoking this skill **is** the opt-in to multi-agent orchestration — call `Workflow` without asking again. A review of a real codebase also runs past any default workflow size guideline; that guideline is advisory and this is the case it exempts. Do not shrink the fan-out to fit it, and do not substitute hand-spawned `Agent` calls.

One `Workflow` call. `scriptPath` takes the absolute path resolved in Phase 1; `args` must be a real JSON object, not a JSON-encoded string.

Workflow({
  scriptPath: "<plugin_root>/workflows/c-review.js",
  args: {
    outputDir:        "<output_dir>",
    pluginRoot:       "<plugin_root>",
    threatModel:      "REMOTE",
    severityFilter:   "all",
    findingScopeRoot: "expat/lib",
    findingScopeRootAbs: "/abs/path/to/repo/expat/lib",
    contextRoots:     ".",
    workerModel:      "sonnet"
  }
})

`findingScopeRootAbs` is the `scope_abs` from Phase 1 and is not optional in practice: omitted, the workflow tells the assembler no absolute root is known and a finding filed as `/repo/expat/lib/xmlparse.c` stops merging with the same bug filed as `xmlparse.c`.

Six further arguments are optional. Omitted, each takes its default; passed with the wrong TYPE, the workflow throws with the field name rather than defaulting. Pass them only when the user asks or when running an evaluation:

| Argument | Default | What it is for | |---|---|---| | `maxUnitLines` | `150` | Cap on a review unit; a larger function is split at syntactic seams. Raising it reintroduces the saturation the cap prevents | | `linesPerAgent` | `1500` | Source lines per review agent. **A no-op on a small tree** — `--agent-min` (default 4) floors the derived count, so two very different values can produce identical assignments. Use `reviewAgents` to pin the fan-out | | `reviewAgents` | derived | Pins the review fan-out, subject to the same floor as the derived count: both are clamped to 4–14, and an explicit value above 14 raises th

Read more
Ships withtrailofbits-skills

A Claude Code plugin marketplace from Trail of Bits providing skills to enhance AI-assisted security analysis, testing, and development workflows. Codex can load this marketplace through its Claude marketplace compatibility.

Get the whole plugin

Other skills on trailofbits-skills.