Balayage de sécurité multi-dépôts

VérifiéPrudence

Analyse tous vos dépôts pour des vulnérabilités réellement exploitables, vérifie chaque faille de façon adversariale et corrige celles qui résistent.

Spar Skills Guide Bot
SecuriteAvancé
4019/10/2026
Claude Code
#vulnerability-scanning#multi-repo#attack-surface#adversarial-verification#automated-fixes

Recommandé pour

Notre avis

Passe au crible l'ensemble des dépôts actifs à la recherche de vulnérabilités réellement atteignables depuis l'extérieur, les vérifie de façon adverse, puis corrige celles qui résistent.

Points forts

  • Filtre par atteignabilité : l'argument `surface` obligatoire force à décrire les vrais points d'entrée de chaque dépôt, ce qui évite les rapports sur une surface d'attaque inexistante.
  • Étape de vérification adverse qui renvoie la liste des findings réfutés et les contrôles effectués, ce qui permet de distinguer une vraie passe d'un simple générateur.
  • Corrections appliquées dans un worktree isolé, validées par un test de mutation et par la commande de vérification propre au dépôt (`gate`).
  • Pipeline sur plusieurs dépôts via un registre partagé : un défaut trouvé dans une application est recherché dans toutes les autres.

Limites

  • Lecture statique uniquement : le skill ne voit ni le runtime, ni les politiques RLS en production, ni la configuration déployée, d'où le champ `couldNotCheck` à lire avant de croire un résultat vide.
  • Compte environ trois agents par dépôt, ce qui limite en pratique la passe à trois ou quatre dépôts.
  • Refuse de démarrer sans description de la surface d'attaque, et certains findings sont volontairement laissés à l'arbitrage humain.
Quand l'utiliser

À utiliser pour une passe de sécurité périodique et transversale sur plusieurs dépôts, quand on veut prioriser ce qu'un attaquant peut réellement atteindre.

Quand l'éviter

À éviter sur un dépôt client ou hors périmètre autorisé, ou lorsqu'on n'est pas capable de décrire précisément la surface d'attaque du projet.

Analyse de sécurité

Prudence
Score qualité85/100

The skill orchestrates a multi-repo security sweep with automated find, verify, and fix stages. It uses powerful tools like Bash, Write, Edit, and Workflow to run scripts and mutate code, but all actions are scoped to the user's own authorized repositories and include safeguards such as excluding client repos and checking git remote. No destructive or exfiltrating instructions were found, but the broad modification capability warrants caution.

Points d'attention
  • •Uses Workflow and Bash to execute custom Node.js scripts with the ability to modify files across multiple repositories.
  • •Automated fix stage can write to codebases, including creating git worktrees and editing source files.
  • •Requires absolute repository paths and runs repository verification commands, which could have unintended side effects.

Exemples

Single-word trigger
heal
Named repos, reachable-only
sweep myapp and billing-api — tell me what an unauthenticated user can actually reach, and fix what survives verification.
Fleet pass with scope guard
are we exposed? run a security pass over everything I've touched in the last two days, but leave the client repos out of the report.

name: heal description: Sweep every repo you are working on for vulnerabilities an attacker can actually reach, prove each one is reachable, and fix the ones that survive. One word starts the whole operation. when_to_use: "Invoked when the user says "heal", "sweep", "fix all the bugs", "check every app", "are we exposed", or asks for a periodic security pass across projects." allowed-tools: Bash, Read, Write, Edit, Grep, Glob, Workflow, Task model: opus user-invocable: true argument-hint: "[repo names, or nothing for the active ones]"

Heal

One word, a whole operation. A bug found in one app is a bug suspected in every app, so this runs the shared registry across all of them at once rather than one repo at a time.

The default filter is REACHABLE FROM OUTSIDE. That is deliberate and it is the thing that makes the output worth reading. Define untrusted actors at the actual boundary, including authenticated low-privilege users when they can cross a permission boundary. Do not equate “reachable” with “unauthenticated only”; that would omit tenant-isolation and privilege-escalation defects. Keep style findings separate from security claims.

Run it

Workflow({
  scriptPath: "${CLAUDE_PLUGIN_ROOT}/scripts/heal-sweep.workflow.js",
  args: [ /* one entry per repo — see below */ ]
})

Three stages per repo, pipelined so one repo can be fixing while another is still looking: find → adversarially verify → fix in an isolated worktree. Roughly three agents per repo, so keep it to three or four repos unless the user raises the cap.

Building args — this is the whole job

{
  name: 'myapp',
  path: '/absolute/path/to/repo',
  gate: 'npm run preflight',      // the repo's own verification command
  surface: '...'                  // REQUIRED — see below
}

surface is the quality lever and the script refuses to run without it. It tells the agent what "reachable from outside" means for this particular repo. Get it wrong and you get a confident report about an attack surface that does not exist — a published CLI has no HTTP routes, and an agent sent looking for them will either find nothing or invent something.

Write two or three sentences naming the real entry points. A web app: its serverless routes, its edge functions, the database surface an anon key can touch, its webhook receivers, its OAuth callbacks. A published package or plugin: what a stranger can read in the tree, what a consumer executes on install, and any CI workflow that runs untrusted code from a fork. A CLI: its argument parsing and anything it fetches.

Say which one is revenue-bearing or handles personal data. Severity is not a property of the code alone.

Picking the repos

Ask what is actually being worked on, or read it off the fleet:

node "${CLAUDE_PLUGIN_ROOT}/scripts/fleet-status.js" --days 2

Intersect observed activity with the current authorized repository scope. Activity is a prioritization signal, not permission to mutate every visible repo. Include older affected repositories when the shared defect or mandate calls for it.

Never sweep a client repo into a shared report. Check git remote get-url origin first and exclude anything that is not the user's own.

What comes back

Per repo: the enumerated attack surface with counts, the findings that survived adversarial verification, the ones that were refuted and why, what was fixed with its mutation test, what was skipped as needing a human call, and the gate result.

Read the refuted list. It is not filler — it is how you tell a real sweep from a generator. Zero refutations alone says nothing about verification quality; read the actual adversarial checks and controls. A detector that repeatedly cries wolf needs its inputs and criteria corrected.

Read couldNotCheck before you believe any zero. A static read cannot see runtime, live RLS policies, or deployed configuration. Silence must never be reported as clean.

The worktree trap — read this before the fix stage

isolation: 'worktree' on an agent creates the worktree from the session's own repo, not from the repo the agent is being pointed at. If the session's cwd is not a git repository, every fix agent dies with "Cannot create agent worktree: not in a git repository" — after the find and verify stages have already been paid for.

That is exactly what happened on the first real run, 2026-08-22: two fix agents errored on a session rooted in a directory that held only .claude/ state and no .git. The findings survived in the journal, but the fix stage was lost.

The worse case is the one that does NOT error. When the session's cwd is a git repo, the agent gets a worktree of the wrong repo, notices nothing, and edits the target's main clone — precisely where other live sessions keep uncommitted work. A crash is recoverable; a silent write into somebody else's tree is not.

Fixed in the script 2026-08-26. This document prescribed the remedy from the day the trap was found, and the script did not carry it for four days, because no suite read that file. The 2026-08-26 sweep worked around it by hand in all four fix agents before it was fixed properly. tooling/test-workflow-isolation.js now fails any workflow that points an agent at a caller-supplied repo.path while asking for isolation: 'worktree', so the next such workflow is covered the day it lands rather than the day it misfires. Written as a rule about the pattern, not an allowlist of filenames.

The fix agent creates its own worktree explicitly, inside the target repo:

cd "<target repo>"
git status --short    # a dirty tree you did not dirty means another session is here
git worktree add .claude/worktrees/<topic> -b fix/<topic>
node "${CLAUDE_PLUGIN_ROOT}/scripts/shared-install.js" link .claude/worktrees/<topic>   # node_modules as hardlinks, or the npm ci it needs

Add .claude/worktrees/ to that repo's .gitignore first if it is not there — a nested git directory sitting untracked in a repo where sessions run git add -A is one careless stage from being committed.

Fixes commit, they do not push

Each fix agent works in its own git worktree, because other sessions have uncommitted work in the main clone. Default delivery is a locally verified commit. If the existing mandate includes publishing, continue through ship after its checks; otherwise retain the publish boundary as pending. Resolve whether push or merge deploys before executing it. Authorization persists across turns.

Feeding the registry

Anything found in two or more repos is a class, not an incident, and belongs in the shared registry with a runnable detection and a known positive:

cat ~/claude-memory/BUG-CLASSES.md

A described bug does not travel between sessions. A grep does. If you cannot write a detection for it, record that limitation in the entry rather than omitting the class.

Skills similaires