@eastagile/claude-scan
v1.2.0
Published
Anthropic's vulnerability scanning scaffold (Carlini, [un]prompted 2026) — parallel Claude Code security scans per file
Downloads
75
Maintainers
Readme
claude-scan
Open-source implementation of Anthropic's vulnerability scanning scaffold from Nicholas Carlini's [un]prompted 2026 talk — the method that found a 23-year-old Linux kernel bug.
Scans every source file in a project for security vulnerabilities using parallel Claude Code processes. Each file gets its own focused context window. Produces per-file vulnerability reports and an aggregated summary.
Background
At [un]prompted 2026, Anthropic researcher Nicholas Carlini showed that a surprisingly simple scaffold — claude -p "You are playing in a CTF. Find a vulnerability. hint: look at <file>" — can find critical zero-days in production software, including a 23-year-old Linux kernel bug and the first critical CVE in Ghost CMS.
The key to scaling this across a codebase is a one-line addition: hint: look at <file>, iterated over every source file in the project. Anthropic described this approach in their red team blog post but did not publish the tooling.
claude-scan is the open-source implementation of that scaffold. It handles the boring parts — file discovery, parallel process management, crash recovery, progress display — so the model can do what it's good at.
Install
npm install -g @eastagile/claude-scanPrerequisites:
- Node.js 18+
- Claude Code installed and authenticated (
claude auth login)
Quick Start
The target directory defaults to the current directory — run from inside your project:
cd ~/code/my-project
# Scan (default: current directory)
claude-scan
# Preview what files would be scanned
claude-scan --dry-run
# Scan with 8 parallel workers
claude-scan -j 8
# Only scan Python files
claude-scan --include "*.py"
# Resume after crash or Ctrl+C
claude-scan --resume
# Retry failed/timed-out files (implies --resume)
claude-scan --retry
# Re-generate summary from existing reports
claude-scan --summarize
claude-scan --summarize --model claude-sonnet-4-6
# Or pass a path explicitly
claude-scan /path/to/projectHow It Works
discover files → queue them → spawn N claude -p processes → collect reports- Discover —
git ls-files(respects.gitignore) or recursive directory walk, filtered by extension, file size, binary content, and test file patterns. Test files are excluded by default (--include-teststo opt in). No LLM calls are spent on filtering. - Fan out — spawns up to N
claude --dangerously-skip-permissions -p "<prompt>"processes in parallel, each analyzing one file. - Monitor — tracks progress, handles timeouts (default 30 min per file), saves state atomically for crash recovery.
- Summarize — spawns one final Claude process that reads all per-file reports, deduplicates issues across files, ranks by severity, and writes
summary.mdwith links to each report.
Each Claude invocation uses the exact prompt from Carlini's scaffold:
You are playing in a CTF.
Find a vulnerability.
hint: look at <file>
Write the most serious one to <report>.Output
Results go to .claude-scan/ in the target directory (or --output <dir>):
.claude-scan/
├── summary.md # Findings aggregated by severity
├── state.json # Scan state (enables --resume)
├── reports/ # One markdown report per scanned file
│ ├── src__auth__login.ts.md
│ └── src__db__queries.py.md
└── logs/ # Full conversation log per file (JSONL: prompt + stream-json events)Options
-j, --parallel <n> Parallel workers (default: 12)
-t, --timeout <seconds> Per-file timeout (default: 1800)
--resume Resume pending files from a previous scan
--retry Resume + also retry failed/timed-out files
--include-tests Include test files (excluded by default)
--summarize Re-generate AI summary from existing reports
--include <glob> Only scan matching files
--exclude <glob> Skip matching files
-o, --output <dir> Output directory (default: .claude-scan)
--model <model> Claude model to use
--max-turns <n> Max Claude turns per file (default: 100)
--max-file-size <kb> Skip files larger than (default: 100)
--retries <n> Max retries per file (default: 2)
--dry-run List files without scanning
--prompt <file> Custom prompt template
-v, --verbose Verbose output
--force Override scan lockCrash Recovery
State is saved atomically (write temp file → fsync → rename) after every file completes and every 30 seconds. If the process crashes, is killed, or you hit Ctrl+C:
claude-scan --resumeCompleted files are never re-scanned. Files that were mid-scan reset to pending.
If you run claude-scan on a repo with an incomplete previous scan, it will prompt:
Previous scan found: 42/66 completed. Resume previous scan? [y/N]To also retry files that failed or timed out:
claude-scan --retrySignal handling:
- 1st Ctrl+C — stops the queue, waits for running scans to finish
- 2nd Ctrl+C — kills all workers immediately, saves state, exits
If the API rate limit is hit, the scan pauses automatically and retries every 15 minutes until the limit clears — no manual intervention needed.
The tool prints actionable hints at exit when files are pending or failed.
Custom Prompts
Create a template with {{FILE_PATH}} and {{REPORT_PATH}} placeholders:
You are a security auditor.
Analyze {{FILE_PATH}} for OWASP Top 10 vulnerabilities.
Write a detailed report to {{REPORT_PATH}}.claude-scan --prompt my-prompt.mdSecurity Warning
This tool runs Claude Code with --dangerously-skip-permissions. Claude can execute arbitrary commands in the target directory without confirmation.
- Run in a container or VM. Docker with
--network noneis ideal. - Run on a clean checkout. Don't scan repos with secrets, credentials, or
.envfiles. - The default prompt finds and reports vulnerabilities. It does not attempt exploitation, but Claude has full tool access.
Architecture
See ARCHITECTURE.md for a guide to the codebase. Detailed design docs with Mermaid diagrams are in docs/architecture/.
License
MIT — see LICENSE.
