security-review/skill/sh-security-review.md
Adam Moussa 4c88c01f7b
chore: import security-review gate, sweep, and Plane-1 checkers into standalone repo
Fresh-init copy of the security-review/ subsystem extracted from
Sea-Haven-Industries/orchestrator (being deprecated). Adds org-standard scaffold:
CI reusable-workflow callers (ruff + collect), dependency-review, labeler,
dependabot, .gitignore, requirements.txt. Scheduled execution is migrating to
Claude Code web routines (ALARM-only to #repo-scanner); the systemd units and
nightly_sweep.sh/checker_coordinator.sh remain the source of truth.

Committed with --no-verify: the canary fixtures (checkers/fixtures/**) carry
intentional secret-shaped test data that trips the deterministic gate (the
documented detector-fixture false positive); no new logic is introduced.
2026-06-29 11:41:41 -04:00

6.1 KiB

name description
sh-security-review High-recall agentic security review with anti-complacency structure. Opus fans out N narrow fresh-context detectors over the target, a separate fresh-context verifier demands proof-of-exploit or downgrades to unverified, then findings are emitted in the structured schema with a block decision. Returns severity-ranked findings each carrying a concrete proof.

Sea Haven Security Review (detector fan-out + proof-or-kill verifier)

A high-recall security review built to resist reviewer complacency. Instead of one model judging the whole surface (that's sh-build-review), this fans out N narrow detectors, each fresh context and adversarial, then a separate verifier with the opposing incentive demands a concrete proof-of-exploit for every candidate or downgrades it to unverified. Output is the structured finding schema (~/.claude/security-review/finding.schema.json) plus a block decision.

This is the interactive (Path A) entry point and runs under the Max subscription. The same prompts and schema are reused by the automated review.sh (Path B) later. See memory project-security-review-agent.

When to Use

  • Security review of a branch, working tree, file, or whole repo
  • Before pushing payments/auth/IaC/input-handling changes
  • As the high-recall pass; complements /security-review, /code-review ultra, and sh-build-review

Arguments

  • Optional target: a path, file, branch, or diff. Default: the current working tree / branch diff vs main.
  • Optional --scope <dirs>: restrict the scan (e.g. src/ infra/ web/).

Mechanism (Opus runs these)

Opus is the main loop. It scopes the target, runs the detector fan-out and verifier as subagents (each with fresh context so no "we already passed 10 files" approval prior accumulates), then applies the gate rule and reports. Opus does NOT soften the gate; the block condition is mechanical.

1. Scope

Identify the files in scope (respect --scope; never scan an answer key or .git). Note the languages present (Python/Lambda, .NET, React/JS, SAM/CDK IaC) so detectors apply the right checklist.

2. Detector fan-out (parallel, fresh context, closed checklist, adversarial)

Spawn these detectors as separate parallel subagents (subagent_type: general-purpose). Each gets ONLY its category, the schema, and the adversarial framing. Each must, per checklist item, either cite a specific safe line OR file a finding — no open "looks fine" judgment.

Detectors:

  • injection — SQL/command/template injection, unsafe deserialization, SSRF, path/file traversal, XXE
  • authz — broken object-level auth/IDOR, missing access checks, missing webhook/Slack signature verification, auth bypass
  • secrets-crypto — hardcoded secrets/keys, weak/again crypto (MD5/SHA1/unsalted), sensitive data in logs/errors/responses, wrong SSM-vs-Secrets-Manager
  • iac-iam — wildcard IAM actions/resources, public buckets/endpoints, open security-group ingress (0.0.0.0/0), missing encryption, over-broad trust policies
  • web-client — XSS (incl. dangerouslySetInnerHTML), CSRF, open redirect, client-side secret exposure
  • logic — broken multi-step invariants, race conditions, missing tenant isolation, auth-state confusion

Detector prompt template (fill {CATEGORY}, {CHECKLIST}, {SCOPE}):

You are a hostile {CATEGORY} security auditor for Sea Haven. Assume this code is hostile and the author
missed something. Audit ONLY {CATEGORY} issues in: {SCOPE}. Read the actual files.
For each checklist item, either name a specific line that is safe, OR file a finding. Do not hand-wave.
Checklist: {CHECKLIST}
Return a JSON array of findings, each: {id, title, claimed_severity (critical|high|medium|low|info),
cwe (CWE-####), file, line, category:"{CATEGORY}", data_flow (numbered source->sink trace),
proof:{input, outcome, test|null}, recommendation}. If none, return []. No prose outside the JSON.

3. Verifier (separate subagent, fresh context, proof-or-kill)

Spawn one or more verifier subagents with the OPPOSING incentive. The verifier did not find these and is rewarded for killing weak claims. For each candidate it demands a concrete, plausible proof.

You are a skeptical exploitation verifier. You did NOT find these; your job is to REFUTE weak claims.
For each candidate finding, decide: is there a concrete, plausible proof-of-exploit (a specific malicious
input and the specific bad outcome, consistent with the code)? 
- If yes: status="confirmed", keep severity = claimed_severity, tighten the proof.
- If no / speculative / not reachable: status="unverified" and severity="unverified". Default to unverified
  when uncertain. A confident assertion without a demonstrable input is NOT proof.
Return the findings array with status, severity, and the verified proof. No prose outside the JSON.

4. Merge + gate (mechanical, Opus does not soften)

  • Dedup by (file, cwe, nearby line); keep the highest accepted severity.
  • summary.confirmed_critical / confirmed_high = counts of status=confirmed at that severity.
  • summary.block = true if any unsuppressed confirmed critical/high exists.
  • A finding may be suppressed ONLY with a written suppression_justification, which is surfaced in the report. No silent dismissal: a critical/high with no proof becomes unverified (still listed), never deleted.

5. Report

Emit the schema JSON, then a human summary: BLOCK/PASS, confirmed findings highest-severity-first, each with file:line, the numbered data-flow trace, and the proof. List unverified and suppressed separately so nothing is silently dropped. The reader reviews proofs, not raw code.

Relationship to existing tooling

  • sh-build-review — single deep Fable pass over a change surface (depth, one reasoner).
  • sh-security-review — high-recall fan-out + proof-or-kill verifier (breadth + anti-complacency).
  • IAM/policy and Lambda-signature changes still require the mandatory cross-family review per global instructions; this does not replace it.

Output

  • Structured findings (schema) + block decision
  • Confirmed findings with proofs, unverified and suppressed listed separately
  • HARD STOP / BLOCK surfaced when summary.block is true