Vulnerability Research
v2 Phase Architecture (DuckDB-Persisted Pipeline)
The skill now runs an explicit, DuckDB-persisted phase pipeline. Every artifact (sources, sinks, defenses, slices, agent steps, findings, refutations, audit outcomes, critic notes, knowledge chunks, defense bypasses) lives in a single DuckDB database keyed by stable hashes. Schema: db/schema.sql. Forward-only migrations: db/migrations/. Oversize payload sidecars: db/sidecars/ (any payload > 16 KB stored on disk, referenced by payload_sidecar_path).
| Phase |
Name |
Writers |
What it produces |
| 0 |
Decompose |
orchestrator |
sources, sinks, defenses, phase0_priorities, intended_feature_classification (Semgrep + LLM batch) |
| 0.5 |
Plan |
orchestrator |
input_slices, scheduled agent_steps |
| 1 |
Hunt |
swarm → queue → orchestrator flush |
gr_findings (status=candidate) |
| 2 |
Confirm |
swarm → queue → orchestrator flush |
gr_findings status updates + refutations |
| 3 |
Bypass-Hunt |
swarm → queue → orchestrator flush |
defense_bypasses + cascade triggers |
| 4 |
Proof |
swarm → queue → orchestrator flush |
gr_findings.payload, audit_outcomes |
| 5 |
Report |
critic agent → orchestrator |
critic_findings; final report |
Single-writer rule (load-bearing). The orchestrator is the only DuckDB writer. Swarm agents emit row-shaped JSON events to an in-memory queue; the orchestrator flushes per phase under one transaction. This preserves idempotency (every NK has a UNIQUE constraint, every payload row has a stable hash) and lets re-runs over the same commit_sha update rather than duplicate.
Doctrine for S2 bypass-hunting: "there always is a bypass." A bypass lane reporting exhausted MUST have evidence it iterated every applicable corpus family on the target defense_type. The LLM in Stage 2 acts as a corpus-anchored oversight agent — it may not detach from the known-bypass corpus to invent novel categories. Categories, payload patterns, and parsed_logic_json triggers live in a global DuckDB catalogue (bypasses table), separate from per-target audit DBs. Source data: db/catalogue/bypasses.json; schema + loader: db/catalogue/schema.sql + db/catalogue/load.sql; tiered fetch protocol that keeps payloads out of agent context until attempt time: references/bypass-catalogue.md.
REPORT critic. Every confirmed finding goes through three checks (comprehension / eligibility / attack-scenario). WARNING is stored structurally; CRITICAL blocks the report. Rubric with worked examples: references/critic-rubric.md.
Canonical name: the findings table is gr_findings; confirmed_vulns is a view selecting confirmation_status = 'confirmed'.
Full spec lives in .omc/specs/deep-interview-vr-v2-consolidated.md. Do not inline the schema here — link to db/schema.sql.
Think Beyond This Document
This skill is a structured starting point, not a ceiling. Real-world vulnerabilities
and CTF challenges routinely defy checklists. The best exploit chains come from
creative, unconstrained thinking — connecting behaviors the developer never imagined
interacting. Do not limit your research to what is cataloged here. Treat every
assumption as testable, every "impossible" path as merely untested, and every
protection as a puzzle to be solved. The most dangerous bugs live in the gaps
between documented categories. Read the code. Understand the runtime. Invent your
own attack classes.
Philosophy
Find the bug. Prove the bug. Chain the bug. Every claim needs a working exploit or it's noise.
The Bitter Lesson, applied: Vulnerability research has historically been 20% computer science and 80% solving giant, domain-specific jigsaw puzzles — learning font internals, memory allocator behavior, protocol edge cases. LLMs are universal jigsaw solvers. They encode the complete library of documented bug classes and vast correlations across source code. The structured methodology below channels this capability; the Agent Sweep mode unleashes it. Use both.
Attention was load-bearing: Much of the Internet's security has rested not on sound engineering alone, but on the scarcity of elite attention. Most code has never been seriously audited. Agent sweep economics change this — you can aim at everything, not just high-status targets.
The phases below are a recommended workflow, not a rigid sequence — skip, reorder, or loop as the target demands. The sink catalogs are representative, not exhaustive — new frameworks ship new dangerous functions daily. If you find a sink not listed here, it's still a sink. The checklists exist to prevent forgetting the obvious, not to replace thinking.
Mode Selection
Choose a mode based on scope and intent before starting work:
| Mode |
When to Use |
Flow |
| Targeted Audit |
Scoped engagement, specific components, compliance-driven |
Phase 0 → Phases 1–7 below (existing workflow) |
| Agent Sweep |
Full source tree available, maximize coverage, "find me everything" |
Phase 0 → Phases S1–S4 → feeds into Phase 6 (Chaining) + Phase 7 (Gate) |
| Hybrid |
Best of both — sweep for discovery, structured for exploitation |
Phase 0 → Agent Sweep for discovery → Crown Jewel Mapping on findings → Phases 5–7 |
| Swarm Pipeline |
Multi-agent SAST with effort tiers; invoked via /vuln-swarm <path> [--effort=low|medium|deep] [--freeform=detached|grounded] |
See references/swarm-pipeline.md § Effort Tiers. LOW = Phase 0 + freeform + Phase 3-lite; MEDIUM = full module fan-out + 2-check; DEEP = static-first lane + slice-type fan-out + 3-check + cross-slice reconciliation. |
Phase 0 (Latest Commits Security Review) runs first in every mode whenever the target has git history — a brownfield-only recency pass executed by a single focused subagent before the broader audit begins. See Phase 0 below.
Weakness Registry under v2 is DuckDB-native — gr_findings rows with confirmation_status = 'confirmed' ARE the registry. Cross-audit priors are recovered by querying the per-target DuckDB on target_id (or targets.repo_url) before Phase 1; variant-of / enables / co-occurs-with edges are derived at read time from (finding_kind, sink_id, source_id) overlap rather than persisted as a second store. The legacy on-disk JSONL+Markdown registry at <target>/.vuln-registry/ is read-only fallback: load references/weakness-registry.md only when working with a pre-v2 target that still has that directory.
Default routing:
- "audit this codebase" / "find vulns" (unscoped) → Hybrid
- "check the auth module" / specific component → Targeted Audit
- "find me zero days" / "sweep everything" → Agent Sweep
Tooling Constraints
LSP for understanding, Grep/Glob for discovery.
When tracing where a symbol is defined or finding all references to it, prefer LSP (goToDefinition, findReferences, hover) when available. LSP gives exact results; Grep gives text matches.
Use Grep/Glob for discovery (finding files, searching patterns). Use LSP for understanding (definitions, references, type info), then read the surrounding source needed to understand framework wiring, guards, decorators, module configuration, and dynamic dispatch.
Avoid raw whole-repo dumps; do not avoid local file context that affects exploitability.
Agent Sweep Mode (Phases S1–S4)
Load references/agent-sweep.md for full prompt templates, scoring rubrics, and integration details.
When the goal is maximum coverage across a full source tree, use file-iteration with independent verification instead of domain-partitioned analysis. This is the Carlini methodology adapted for Claude Code.
Phase S1: Source Tree Segmentation
- Enumerate all source files — exclude vendored/generated code (
node_modules/, vendor/, dist/, generated protobuf)
- Partition into work units by directory/module (not by attack domain — that's Targeted mode)
- Prioritize by Attention Deficit Score (see Phase 2 addition below) — least-examined, highest-exposure code first
- Include test files — they reveal expected invariants that may not be enforced
Phase S2: Discovery Loop
For each source file (or small cluster), spawn a parallel agent:
"You are performing a security audit. Find exploitable vulnerabilities starting from ${FILE}. Consider all bug classes — memory corruption, injection, logic flaws, auth bypass, deserialization, race conditions, type confusion, integer mishandling. Trace inputs from this file's entry points through the program. Write findings to ${FILE}.vuln.md with: vuln type, affected function, source→sink trace, exploitability assessment, suggested payload.
Tooling: Prefer LSP (goToDefinition, findReferences, hover) when available for symbol definitions, callers, and type info — exact resolution reduces same-name false positives from Grep text matches. Use Grep/Glob for discovery (locating files, searching patterns), then read the local file context needed for decorators, route registration, middleware, guards, module config, and dynamic dispatch."
Design properties:
- File-anchored, not domain-anchored — each agent starts from a file, not "look for SQLi." The LLM's latent bug-class knowledge drives discovery, not a checklist
- Stochastic by construction — different starting files produce different inference paths; running the same file twice may surface different bugs due to sampling
- Follow imports — agents aren't limited to their starting file; the file is the anchor that seeds exploration direction
- Parallelizable — agents are independent; scale linearly with compute
Phase S3: Verification Loop
Feed each .vuln.md back through a fresh agent (not the discoverer — avoids confirmation bias):
"You received an inbound vulnerability report in ${FILE}.vuln.md. Verify this is actually exploitable. Trace the source→sink path yourself. Confirm controllability. Identify defense layers that might block it. Classify: Confirmed / Plausible-Needs-Dynamic / False Positive.
Tooling: Prefer LSP (goToDefinition, findReferences, hover) when available to verify symbol definitions and callers. Use Grep/Glob for discovery, then read enough surrounding file context to confirm guards, framework wiring, and dynamic behavior."
Expected filtration: ~40–60% of discovery findings survive verification.
2-check variant (higher-confidence audits)
For audits that warrant stronger verification, upgrade the single-agent check to two distinct checks executed as separate agent calls with separate prompts. The two agents must not share a context window, and must not be told of each other's verdicts.
RE-TRACE — an independent source→sink walk. The agent receives the finding's location and is asked: does the path exist as claimed? Can the source be controlled? Does the taint survive the transforms? The agent produces its own trace from scratch without trusting the report's.
JUDGE — a semantic-correctness review. The agent receives the finding and its claimed root cause and is asked: is the diagnosis correct? Is the bug class label accurate? Is the alleged data flow actually reachable in practice? Is the impact as stated, or over/under-claimed?
Combine the two verdicts:
- pass BOTH →
Confirmed
- pass ONE →
Candidate (flag the disagreement in the report)
- fail BOTH →
False Positive
Keeping the checks as separate agent calls with separate prompts is load-bearing. A single agent asked both questions collapses them into one mental pass and loses the independence that gives 2-check its precision. The full richer treatment — including how this plugs into weighted scoring — is in references/swarm-pipeline.md § Weighted Scoring.
Structured JUDGE variant. Instead of asking JUDGE "is this finding correct?" in free text, instruct it to build a DAG from scratch against the cited code: extract source nodes, build intermediate nodes with parent IDs and primitives, run the 12-pattern check, converge on a sink. A JUDGE pass that cannot close the graph from an untrusted source to a verified_sink is a False Positive verdict — no hedging. See references/dag-reasoning.md § "Phase S3 — Agent-Sweep Verification" for the exact prompt.
Phase S4: Dedup, Cluster, Feed Forward
- Deduplicate findings pointing to the same root cause from different starting files
- Cluster by bug class and affected component
- Feed verified findings into Phase 6 (Chaining) and Phase 7 (Exploitability Gate)
- The sweep finds the raw bugs; the existing methodology scores, chains, and proves them
Domain Reference Map
Load references on-demand based on the active testing domain. Do not load all files at once.
| Domain |
Reference File |
Load When |
| SQLi, NoSQL, SSTI, CRLF, LDAP, XPath, LaTeX Injection, CSV Injection, XSLT Injection |
references/injection-attacks.md |
Testing injection vectors |
| XSS, Prototype Pollution, CORS, CSTI, postMessage, DOM Clobbering, CSS Injection, Cookie Tossing |
references/client-side-attacks.md |
Testing client-side attacks |
| XS-Leaks, Clickjacking, CSP Bypass, Browser Desync, HTML Smuggling, Reverse Tabnabbing |
references/browser-attacks.md |
Testing browser security model attacks |
| RCE, SSRF, XXE, File Ops, Deserialization |
references/server-side-attacks.md |
Testing server-side attacks |
| Auth, Access Control, OAuth, Logic, Race, Crypto |
references/auth-access-logic.md |
Testing auth & business logic |
| Smuggling, Cache, WebSocket, GraphQL, DNS, Cloud, Encoding, ReDoS, HTML Smuggling, Prompt Injection |
references/protocol-infra-attacks.md |
Testing protocols & infrastructure |
| CI/CD Pipelines, GitHub Actions, Supply Chain, Runner Security, Workflow Poisoning |
references/cicd-supply-chain.md |
Testing CI/CD and supply chain attacks |
| n8n, Zapier, Make.com, Power Automate, iPaaS, Webhooks, Workflow RCE, Credential Theft |
references/automation-platform-attacks.md |
Testing automation/iPaaS platforms |
| Traefik, Nginx, HAProxy, Reverse Proxy Bypass, Terraform State, Docker Socket, Container Escape |
references/infra-misconfig-attacks.md |
Testing infrastructure misconfigurations (proxy, IaC, containers) |
| OpenTelemetry, Prometheus, Grafana, Log Pipelines, Telemetry Poisoning, Collector SSRF, Cardinality Bombs |
references/observability-telemetry-attacks.md |
Testing observability/monitoring infrastructure |
| Sinks router + SAST/DAST rules |
references/sinks-catalog.md |
Code audit entry point — routes to per-language sink files |
| PHP sinks |
references/sinks/php.md |
PHP code audit (exec, callbacks, type juggling, phar deser) |
| Python sinks |
references/sinks/python.md |
Python code audit (exec, pickle, SSTI, subprocess) |
| Node.js sinks |
references/sinks/javascript.md |
JS/Node code audit (child_process, prototype pollution) |
| Java sinks |
references/sinks/java.md |
Java code audit (Runtime, JNDI, ysoserial, format-specific deser) |
| Scala sinks |
references/sinks/scala.md |
Scala code audit (ToolBox.eval, LazyList/TrieMap deser, Akka, Play, Slick/Doobie/Quill SQLi, Spark, effect systems, build system) |
| Ruby sinks |
references/sinks/ruby.md |
Ruby code audit (system/eval, Marshal, ActiveRecord) |
| .NET sinks |
references/sinks/dotnet.md |
.NET code audit (Process.Start, BinaryFormatter, Json.NET) |
| Systems sinks (Go/Rust/C/Elixir) |
references/sinks/systems.md |
Systems code audit (memory corruption, os/exec, ETF deser) |
| Mobile sinks (Android/iOS) |
references/sinks/mobile.md |
Mobile code audit (WebView, intents, URL schemes) |
| Scala sinks |
references/sinks/scala.md |
Scala code audit (ToolBox.eval, LazyList/TrieMap deser, Akka, Play, Slick/Doobie/Quill SQLi, Spark, effect systems, build system) |
| Binary / RE / firmware / kernel: triage, static RE, fuzzing, memory-corruption classes, binary-level races, patch diffing, exploit primitives, mitigations |
references/binary-code-analysis.md (thin index → binary-triage-and-re.md, binary-bug-classes.md, binary-exploit-and-specialties.md) |
Target is a compiled binary, firmware image, kernel/driver, closed-source blob, or native source whose ABI/compiler/ordering behavior matters. Load only the lifecycle file the active trigger cites (see Phase 3.5). |
| Vulnerability chaining, scanning tools, blind spots |
references/chaining-advanced-techniques.md |
Building exploit chains, tool augmentation |
| Formal audit, PoC development, report writing |
references/audit-poc-report.md |
On-demand only — when asked for audit/PoC/report |
| Agent sweep methodology, file iteration, verification loops |
references/agent-sweep.md |
Running Agent Sweep or Hybrid mode |
| Swarm pipeline: module decomposition, orthogonal strategies, three-stage pass, analog cascade, weighted scoring, Phase 4 continuous-learning |
references/swarm-pipeline.md |
Running the Swarm Pipeline command / hypothesis-driven multi-agent audit |
| DAG-structured vulnerability reasoning (DAGVul): source/intermediate/sink nodes, 12 failure-pattern taxonomy, logical closure |
references/dag-reasoning.md |
Writing a finding's source→sink trace, running the Swarm JUDGE check, or mechanically answering Phase 7 Exploitability Gate Q1–Q3 |
Weakness Registry: per-target persistent graph of Confirmed weaknesses (JSONL nodes + edges), prior-injection for future audits, dedup-by-deterministic-id, edge types (variant-of, co-occurs-with, enables, bypasses) |
references/weakness-registry.md |
Starting an audit on a target with .vuln-registry/, OR after Phase 7 marks any finding Confirmed (Phase 8 promotion writes to the registry) |
DuckDB schema (16 tables + confirmed_vulns view) — persistence layer for the v2 phase pipeline |
db/schema.sql (DDL) + db/migrations/0001-initial.sql (forward-only) + db/sidecars/ (>16 KB payload BLOBs) |
v2 pipeline runs — load when wiring orchestrator writes, debugging FK/CHECK failures, or migrating the database |
| Critic rubric for Phase 5 REPORT critic — comprehension / eligibility / attack_scenario checks, WARNING vs CRITICAL, 17 worked examples |
references/critic-rubric.md |
Phase 5 critic runs, or hand-classifying a finding's critic verdicts |
Bypass catalogue for Phase 3 (S2) — global DuckDB bypasses table (sanitizer / blacklist / allowlist / generic families) with tag-indexed parsed-logic triggers + tiered fetch protocol |
db/catalogue/bypasses.json (data) + db/catalogue/schema.sql (DDL) + db/catalogue/load.sql (idempotent loader) + references/bypass-catalogue.md (3-stage fetch protocol) |
Bypass-hunting lanes (defense_base_lane, defense_context_verification_lane, isolation_fuzz_lane) — Stage A enumerate labels, Stage B record skip-with-reason, Stage C lazy-fetch one family's payloads at attempt time |
Confirmation Rigor Doctrine (C1) — the four gates (taint reach / defense gap / intended-feature filter / reproduction artifact w/ config_state) for promoting gr_findings.confirmation_status from candidate → confirmed, plus refutation row shape |
references/confirmation-rigor-doctrine.md |
Phase 2 confirm runs, gate-by-gate refutation triage, or gr_findings.config_state column wiring |
Forward-Slicing Lanes (C2) — slice tuple + slice_kind discriminator (forward_taint / backward_sink / defense_callsite), lane lifecycle, coverage_json shape, cascade-on-bypass + cascade-on-reach semantics |
references/forward-slicing-lanes.md |
Spawning lanes, debugging success_without_artifact / incomplete_coverage rewrites, or reasoning about cascade scheduling |
Autoloading Knowledge Layer (C3) — seed (top-K=10) vs expand (cap 50, version-pinned), tri-signal acceptance (ref_count, repeat_suppressions, growth_rate, staleness_days), bootstrap rule R8 for first-audit single-signal admit, decay sweep |
references/autoloading-knowledge-layer.md |
Wiring autoload_seed_lane / autoload_expand_lane, or debugging why a chunk did/didn't graduate to core |
REPORT Critic Phase (C4) — three checks (comprehension / eligibility / attack-scenario), config_state eligibility table (vanilla Pass / non_vanilla WARNING / unknown CRITICAL), severity storage contract that demotes CRITICAL findings to refuted at orchestrator flush |
references/report-phase.md |
Phase 5 critic runs, debugging blocked-report flushes, or deciding WARNING-vs-CRITICAL on a borderline critic_findings row |
Phase 0: Latest Commits Security Review
Before the broad audit begins, spawn one focused subagent to perform a narrow-scope security review of the repository's most recent commits. Recent diffs are the highest-signal starting surface in a brownfield target: they concentrate attacker-reachable new code, often touch security-adjacent paths (auth, routing, input parsing, config), and receive less scrutiny than older, stable modules. Reviewing them first primes the rest of the audit with concrete findings and calibrates the attack surface before Phase 1 (Recon) runs.
This is intentionally single-agent and narrow-scope — whole-tree coverage belongs in Agent Sweep (Phases S1–S4). Phase 0 exploits the recency signal without drifting into full-sweep territory. A swarm would dilute focus across the small commit surface and produce duplicated, low-signal findings.
Subagent Prompt
Spawn exactly one agent with this prompt:
You are performing a focused, narrow-scope security review of this repository's most recent commits. Inspect repo signals first — tag recency, branch divergence from main/master, commit cadence, CHANGELOG or release notes — then choose the most informative commit range yourself (e.g., last N commits, since last tag, or branch diff against main). State the chosen range and justification before reviewing.
For every file touched by the selected commits, analyze only the changed hunks and their immediate call graph. Do not audit code the commits did not touch — that is Phase 3's and Agent Sweep's job, not yours. Consider all bug classes — injection, memory corruption, auth bypass, deserialization, race conditions, type confusion, logic flaws, missing authorization, unsafe defaults, exposed secrets, regressions that reintroduce previously-fixed CVEs, and weakened security controls (removed validators, loosened regex, new @ts-ignore/# type: ignore on security-adjacent code).
For each finding write: vuln type, affected function/file, source→sink trace, controllability, exploitability assessment (High/Medium/Low), and a suggested payload or PoC direction. Flag commits that touch security-adjacent paths (auth, crypto, input parsing, session handling, access control, deser, SSRF-prone callers) even when no bug is found — the auditor needs to know where recent changes raise risk.
Fix-bypass analysis (n-day vector): when a commit fixes a security bug, do not trust the fix. Enumerate inputs, encodings, types, code paths, and state-machine transitions the patch does not cover (e.g., alternate decoder, sibling endpoint, case/normalization differential, race window, deeper nesting, non-string type, second-order sink) and attempt to reach the original sink despite the patch. Incomplete patches are one of the highest-yield n-day sources — treat every security fix as a hypothesis "this specific path is now blocked," then try to falsify it.
Stay very accurate and very focused: no speculation, no "theoretical" findings without a controllability trace, no drift into untouched code. If the chosen range surfaces no real vulnerabilities, say so explicitly and list which security-adjacent files were examined so the rest of the audit can trust the recency pass.
Tooling: Prefer LSP (goToDefinition, findReferences, hover) when available for resolving the call graph of changed hunks — recency review is high-signal precisely because it stays anchored to actually-touched call sites. Use Grep/Glob for discovery (locating files, finding string patterns), then read enough surrounding context to validate framework wiring, guards, and dynamic dispatch.
Optional Deliverable: PATCH SEEDS
When a downstream phase will fan out parallel agents (Agent Sweep, Swarm Pipeline, or any multi-agent audit that benefits from hypothesis templates), Phase 0 can emit a second artifact alongside the findings: a PATCH SEEDS list extracted from the same commit range. Each seed is a recently-fixed bug or tightened control that downstream agents use as a hypothesis template — "is an unfixed variant of this pattern present elsewhere in the tree?"
Each PATCH SEED record:
| Field |
Content |
affected_file |
Path touched by the fix commit |
affected_hunk |
Hunk range or line numbers of the actual fix |
fix_summary |
One sentence describing what the patch changed and why |
bug_class |
Canonical class label (e.g., sql-injection, missing-authz, path-traversal) |
variant_query |
A grep-friendly or structural-search-friendly string downstream agents can use to locate analogous sites |
Emit seeds only for commits that actually fix a bug or tighten a control — not refactors, not style changes, not dependency bumps unless the bump closes a CVE. A seed without a clear variant_query is low-value; drop it rather than weaken the set.
Fallbacks
| Condition |
Behavior |
No .git directory / no git history |
Skip Phase 0, proceed to Phase 1 |
| Fewer than 3 commits in history |
Skip Phase 0, proceed to Phase 1 |
| Recent commits are docs-only or generated files only |
Record NO_CODE_CHANGES with touched paths, proceed to Phase 1 |
| Subagent fails or times out |
Log the failure, proceed to Phase 1 — do not retry inline |
Feed-Forward
Phase 0 findings plug into the same downstream pipeline as Agent Sweep output:
- Dedup against later Phase 3 (Source Audit) and any Agent Sweep results
- Feed surviving findings into Phase 6: Vulnerability Chaining
- Gate each finding through Phase 7: Exploitability Gate before reporting
Do not promote a Phase 0 finding to a reported vulnerability without passing Phase 7 — the exploitability gate applies equally to commit-sourced findings.
Phase 1: Recon
Identify the full technology stack before touching anything:
- Language, runtime version, framework, template engine
- ORM / database layer and database engine
- Web server and its configuration (Apache, Nginx, Caddy, IIS, LiteSpeed)
- Reverse proxy / load balancer (HAProxy, Traefik, AWS ALB — each parses HTTP differently)
- Auth mechanism (session, JWT, OAuth, SAML, WebAuthn, custom)
- File upload support, allowed types, size limits
- API style (REST, GraphQL, SOAP, JSON-RPC, gRPC-Web, WebSocket)
- Debug mode status, verbose error pages, stack traces
- PHP version (5.x / 7.x / 8.x) — gates which sinks are exploitable:
assert() evals strings only in < 8.0, preg_replace /e only in < 7.0, loose type juggling 0 == "string" only in < 8.0, libxml_disable_entity_loader() removed in 8.0 (XXE defaults safe), hex numeric strings "0x1A" == 26 only in < 7.0. Always qualify PHP findings with the version gate.
- PHP config:
allow_url_include, allow_url_fopen, disable_functions, open_basedir, display_errors, file_uploads, session.upload_progress.enabled
- Node.js:
--inspect port, NODE_ENV, prototype pollution surface
- Python: debug mode (Werkzeug debugger PIN), pickle usage, SSTI surface
- Java: JNDI enabled, deserialization libraries, Expression Language version
- Container context: privileged mode, mounted volumes, exposed docker socket, inter-container network, environment secrets, Kubernetes service account tokens
- CDN / WAF fingerprint (Cloudflare, Akamai, ModSecurity rules — know what you're bypassing)
- Client-side: JS frameworks (React, Angular, Vue), bundler (webpack, vite), source maps available
- Dependency manifest:
package.json, composer.json, requirements.txt, Gemfile, pom.xml, go.mod, Cargo.toml, mix.exs
patch-package / pnpm patch / yarn patch overlays (patches/*.patch, patches_*/*.patch): read every patch in the tree and treat each removed/added hunk as security-relevant by default. Overlays silently mutate vendored SDK invariants (scoring rules, crypto surface, consent UX) and do not show up in dependency scanners. A patch that exports a previously-private crypto method, adjusts an auth scoreFlow, or deletes a Confirm* modal is a finding-generator by itself.
- Known CVEs in detected versions (check NVD, Snyk DB, GitHub Advisories)
Map every user input vector:
- URL parameters, path segments, fragments
- Request body (form-encoded, JSON, XML, multipart)
- HTTP headers (Host, X-Forwarded-For, Referer, User-Agent, Accept-Language, custom headers)
- Cookies
- File upload content and metadata (filename, content-type, EXIF)
- WebSocket messages
- DNS records (for DNS rebinding)
- API field names (for mass assignment)
Map every endpoint. Build a table of routes, methods, auth requirements, and parameters before testing.
Phase 2: Crown Jewel Mapping
Before testing, identify maximum-damage targets:
- Data assets: PII stores, payment processing, admin credentials, API keys
- Privilege boundaries: admin panels, role escalation paths, multi-tenant isolation
- Trust transitions: internal services, SSO providers, cloud metadata endpoints
- Business logic: financial operations, state machines, approval workflows
Attack the highest-value targets first.
Attention Deficit Mapping
After identifying crown jewels, identify the least-examined code — where bugs survive because nobody looked, not because the code is sound:
| Signal |
High Attention (lower bug probability) |
Low Attention (higher bug probability) |
| Security commits |
Has fix: security, CVE references, audit comments |
No security-related commits in history |
| Fuzzing/testing |
Fuzz targets exist, high test coverage |
No fuzz corpus, low/no test coverage |
| Code glamour |
Auth module, crypto, payment processing |
Parser, format handler, protocol adapter, config loader, migration script |
| External exposure |
Behind auth wall, internal-only |
Processes attacker-controlled input (uploads, webhooks, public API) |
| Code age |
Recently written/reviewed |
Legacy code, "don't touch" modules, vendored-then-forgotten |
Prioritize: high exposure + low attention. These are the targets that have never seen a fuzzer. The crown jewels approach finds the highest-impact targets; attention deficit mapping finds the highest-probability targets. Use both.
Quick heuristics:
git log --format='%s' -- <path> | grep -ic 'secur\|vuln\|cve\|xss\|sqli\|inject' — zero hits = never audited
- Check for adjacent
*_test.*, *_spec.*, fuzz_* files — absence = untested
git log --diff-filter=M --since="2 years ago" -- <path> — no recent changes = stale, possibly forgotten
Phase 3: Source Audit
Run parallel agents, each focused on one attack domain. Every agent traces source to sink — user input reaching a dangerous function.
| Attack Category |
Key Targets |
Reference |
| Injection (SQLi, NoSQL, SSTI, CRLF, LDAP, XPath) |
Query builders, template renders, header construction |
injection-attacks.md |
| Client-Side (XSS, Proto Pollution, CORS, CSTI, DOM Clobbering, CSS Injection) |
Output contexts, deep merge, origin validation |
client-side-attacks.md |
| Browser (XS-Leaks, Clickjacking, CSP Bypass, Browser Desync, HTML Smuggling) |
Cross-origin side channels, UI redressing, CSP evasion |
browser-attacks.md |
| Server-Side (RCE, SSRF, XXE, File Ops, Deser) |
Command exec, URL fetching, XML parsing, file I/O, object deser |
server-side-attacks.md |
| Auth & Logic (Auth, ACL, OAuth, Race, Crypto) |
Session mgmt, role checks, token flows, concurrent ops, key mgmt |
auth-access-logic.md |
| Protocol & Infra (Smuggling, Cache, WS, GraphQL, DNS, Cloud) |
HTTP parsing, cache keys, WS handlers, query depth, metadata |
protocol-infra-attacks.md |
Every module agent MUST conclude its report with a Blind Spots block: files it did not read, components absent from the repo but referenced elsewhere (other-repo Rust halves, dynamically-fetched configs, production-only artifacts), runtime states it could not observe (OIDC discovery docs, feature-flag evaluation), and dependencies whose behavior gates its findings' severity. Blind spots are first-class output, not footnotes. Phase 6 chain synthesis consumes this list to flag findings whose severity depends on external evidence.
Phase 3.5: Technology Stack Discovery (Sink Loading)
Before taint analysis, identify every language and framework in the stack — most targets are polyglot:
- Enumerate languages: scan file extensions, shebangs,
package.json/composer.json/pom.xml/go.mod/Cargo.toml/mix.exs/Gemfile/requirements.txt
- Identify the stack layers: e.g., PHP backend + Node.js build tooling + Python microservice + Java auth service
- Load matching sink files: for each language present, load the corresponding
references/sinks/<lang>.md — load multiple if the target is polyglot
- Load the SAST/DAST router:
references/sinks-catalog.md for cross-language Semgrep/CodeQL/SonarQube rules
Example: a Laravel app with React SSR and a Python ML microservice → load sinks/php.md + sinks/javascript.md + sinks/python.md
Do not skip minor languages in the stack — the weakest link is often the least-reviewed service.
Binary / native artifacts in the stack — tiered loading across three lifecycle files. Source-level sinks stop at the compiler; ABI, memory ordering, calling conventions, packers, and machine-level race windows require binary audit. The binary reference is split into three lifecycle files — orient, find bugs, prove and report — plus a thin routing index at references/binary-code-analysis.md. Load only what the trigger cites; never the whole triad by default.
| Trigger (any match → load) |
File(s) and section(s) to read first |
| Target artifact is ELF / PE / Mach-O / WASM / dex / firmware blob / kernel module / bootloader / TEE payload |
references/binary-triage-and-re.md § 1 → § 2 → § 2b |
Source audit hit a .so / .dll / .dylib / static .a with no matching source |
references/binary-triage-and-re.md § 2–4, then references/binary-bug-classes.md § 10 |
Source is present but contains C / C++ / Rust unsafe / Go cgo / Zig / Objective-C / inline asm! where ABI or ordering changes semantics |
references/binary-bug-classes.md § 6 + § 7 + § 15 |
| Hypothesis involves memory layout, stack alignment, calling convention, endianness, signal delivery mid-instruction, syscall atomicity, double-fetch, weak memory model |
references/binary-bug-classes.md § 7 + § 8 + § 15 |
| N-day work: public advisory + patched vs. unpatched binary, no source diff |
references/binary-exploit-and-specialties.md § 11 |
Crash found but no source explanation — the bug may live in compiler output / linker glue / TLS callback / .init_array |
references/binary-triage-and-re.md § 4 + references/binary-bug-classes.md § 15 |
| Packed, VM-protected, anti-debug, or otherwise obfuscated sample |
references/binary-exploit-and-specialties.md § 13b |
| Building or claiming an exploit primitive (ROP/SROP/ret2dlresolve/JOP/heap grooming) |
references/binary-exploit-and-specialties.md § 13 + § 14 |
| Firmware image / IoT / router / printer / camera / automotive ECU |
references/binary-exploit-and-specialties.md § 12.1 |
| Kernel / driver / hypervisor / TEE target |
references/binary-exploit-and-specialties.md § 12.2–12.5 + § 14 |
| Writing a fuzz harness or running dynamic analysis |
references/binary-bug-classes.md § 5 |
| Building a binary-level taint DAG |
references/binary-bug-classes.md § 10 |
| Writing a binary finding report |
references/binary-exploit-and-specialties.md § 16 (DAG block required — ties back to Phase 7 Gate) |
Do not load the whole triad by default. On targets with no native component, none of the above triggers fire and these files stay off the token budget. On triggered targets, load only the subfile(s) the matched trigger cites. When no single trigger dominates, start with references/binary-code-analysis.md (thin index, ~60 lines) and fan out from there.
Binary findings integrate with the source pipeline unchanged: they feed Phase 6 Chaining as primitives (info-leak / arb-read / arb-write / control-flow) and pass Phase 7 Exploitability Gate via the same DAG form as source findings — with primitive ∈ {taint, cfg, alias, constraint, abi} and abi nodes citing the calling convention / register / struct layout being relied on. See references/binary-bug-classes.md § 10 (Binary-Level Taint Framework) and references/binary-exploit-and-specialties.md § 16 (Output Format) for the binary-specific DAG vocabulary.
Tool-Integration Matrix (CPG / SAST / AST tooling)
For DEEP-tier Swarm Pipeline runs and any audit where a mechanical pre-pass is available, select in priority order:
| Priority |
Tool |
Representation |
When to use |
| 1 |
Joern |
Code Property Graph (AST + CFG + DFG + call graph) |
Full inter-procedural taint, PDG cuts, call-chain slicing. Best when a queryable graph justifies indexing cost (large C/C++/Java/JS/Python targets). |
| 2 |
CodeQL |
Relational AST + dataflow library |
Path queries from stdlib sources to sinks. SARIF output. Use when a pre-built query pack matches the stack. |
| 3 |
Semgrep + ast-grep |
Semantic patterns (Semgrep) + structural AST matching (ast-grep) |
Cheapest rule-writing path. Semgrep for dataflow-aware rules; ast-grep for language-agnostic structural hunts. |
| 4 |
Fallback: sinks/<lang>.md grep |
Plain text |
No CPG/SAST tooling available — the per-language sink files are ripgrep-ready. |
Outputs from layers 1–3 are packaged as SecuritySlice input packets (see references/dag-reasoning.md § SecuritySlice Input Packet) for LLM consumption. LLM agents treat tool hits as hypotheses to verify, never as findings to rubber-stamp.
Why CPG over AST-first: Raw AST lacks the security-relevant edges — data dependencies, control dependencies, call targets, aliasing. A CPG merges all four, which means one query answers "does untrusted input reach this sink under these guards?" without re-implementing dataflow per rule. See references/swarm-pipeline.md § Slice Types for the 11 slice cuts the tooling can emit.
Phase 4: Taint Analysis
Three strategies — choose based on codebase size:
| Strategy |
When |
Method |
| Source-forward |
Small codebase, few entry points |
Trace from user input → through transforms → to sinks |
| Sink-backward |
Large codebase, known dangerous functions |
Start at sinks (see sinks-catalog.md) → trace backward to find controllable inputs |
| Hybrid |
Medium codebase, complex data flow |
Combine both: forward from sources AND backward from sinks, meet in the middle |
| **Circulatory tracing |
|
|
…(truncated)
1---2name: vuln-research3description: Use when performing vulnerability research, security auditing, code analysis, bug bounty hunting, CTF challenges, penetration testing, or exploit development. Covers source audit across 30+ attack domains, sink analysis for 12 languages, SAST/DAST integration, vulnerability chaining, and proof-of-concept development. Triggers: vuln assessment, pentest, bug bounty, security audit, find vulns, exploit, ctf, code audit, hunt bugs, 0-day, SAST, DAST, taint analysis, CI/CD pipeline security, GitHub Actions, Terraform, Traefik, n8n workflow, OpenTelemetry, supply chain attack, agent sweep, find me zero days, sweep everything, automated vuln discovery, binary analysis, reverse engineering, firmware audit, kernel driver, memory corruption, ROP, fuzzing harness, patch diffing.4---56# Vulnerability Research78## v2 Phase Architecture (DuckDB-Persisted Pipeline)910The skill now runs an explicit, DuckDB-persisted phase pipeline. Every artifact (sources, sinks, defenses, slices, agent steps, findings, refutations, audit outcomes, critic notes, knowledge chunks, defense bypasses) lives in a single DuckDB database keyed by stable hashes. Schema: [`db/schema.sql`](db/schema.sql). Forward-only migrations: [`db/migrations/`](db/migrations/). Oversize payload sidecars: [`db/sidecars/`](db/sidecars/) (any payload > 16 KB stored on disk, referenced by `payload_sidecar_path`).1112| Phase | Name | Writers | What it produces |13|---|---|---|---|14| **0** | Decompose | orchestrator | `sources`, `sinks`, `defenses`, `phase0_priorities`, `intended_feature_classification` (Semgrep + LLM batch) |15| **0.5** | Plan | orchestrator | `input_slices`, scheduled `agent_steps` |16| **1** | Hunt | swarm → queue → orchestrator flush | `gr_findings` (status=candidate) |17| **2** | Confirm | swarm → queue → orchestrator flush | `gr_findings` status updates + `refutations` |18| **3** | Bypass-Hunt | swarm → queue → orchestrator flush | `defense_bypasses` + cascade triggers |19| **4** | Proof | swarm → queue → orchestrator flush | `gr_findings.payload`, `audit_outcomes` |20| **5** | Report | critic agent → orchestrator | `critic_findings`; final report |2122**Single-writer rule (load-bearing).** The orchestrator is the only DuckDB writer. Swarm agents emit row-shaped JSON events to an in-memory queue; the orchestrator flushes per phase under one transaction. This preserves idempotency (every NK has a UNIQUE constraint, every payload row has a stable hash) and lets re-runs over the same `commit_sha` update rather than duplicate.2324**Doctrine for S2 bypass-hunting: "there always is a bypass."** A bypass lane reporting `exhausted` MUST have evidence it iterated every applicable corpus family on the target defense_type. The LLM in Stage 2 acts as a corpus-anchored oversight agent — it may not detach from the known-bypass corpus to invent novel categories. Categories, payload patterns, and `parsed_logic_json` triggers live in a **global DuckDB catalogue** (`bypasses` table), separate from per-target audit DBs. Source data: [`db/catalogue/bypasses.json`](db/catalogue/bypasses.json); schema + loader: [`db/catalogue/schema.sql`](db/catalogue/schema.sql) + [`db/catalogue/load.sql`](db/catalogue/load.sql); tiered fetch protocol that keeps payloads out of agent context until attempt time: [`references/bypass-catalogue.md`](references/bypass-catalogue.md).2526**REPORT critic.** Every confirmed finding goes through three checks (comprehension / eligibility / attack-scenario). WARNING is stored structurally; CRITICAL blocks the report. Rubric with worked examples: [`references/critic-rubric.md`](references/critic-rubric.md).2728**Canonical name:** the findings table is `gr_findings`; `confirmed_vulns` is a view selecting `confirmation_status = 'confirmed'`.2930> Full spec lives in `.omc/specs/deep-interview-vr-v2-consolidated.md`. Do not inline the schema here — link to `db/schema.sql`.3132---3334> **Think Beyond This Document**35>36> This skill is a structured starting point, not a ceiling. Real-world vulnerabilities37> and CTF challenges routinely defy checklists. The best exploit chains come from38> creative, unconstrained thinking — connecting behaviors the developer never imagined39> interacting. **Do not limit your research to what is cataloged here.** Treat every40> assumption as testable, every "impossible" path as merely untested, and every41> protection as a puzzle to be solved. The most dangerous bugs live in the gaps42> between documented categories. Read the code. Understand the runtime. Invent your43> own attack classes.4445## Philosophy4647Find the bug. Prove the bug. Chain the bug. Every claim needs a working exploit or it's noise.4849**The Bitter Lesson, applied:** Vulnerability research has historically been 20% computer science and 80% solving giant, domain-specific jigsaw puzzles — learning font internals, memory allocator behavior, protocol edge cases. LLMs are universal jigsaw solvers. They encode the complete library of documented bug classes and vast correlations across source code. The structured methodology below channels this capability; the Agent Sweep mode unleashes it. Use both.5051**Attention was load-bearing:** Much of the Internet's security has rested not on sound engineering alone, but on the scarcity of elite attention. Most code has never been seriously audited. Agent sweep economics change this — you can aim at everything, not just high-status targets.5253The phases below are a **recommended workflow, not a rigid sequence** — skip, reorder, or loop as the target demands. The sink catalogs are **representative, not exhaustive** — new frameworks ship new dangerous functions daily. If you find a sink not listed here, it's still a sink. The checklists exist to prevent forgetting the obvious, not to replace thinking.5455---5657## Mode Selection5859Choose a mode based on scope and intent before starting work:6061| Mode | When to Use | Flow |62|------|-------------|------|63| **Targeted Audit** | Scoped engagement, specific components, compliance-driven | Phase 0 → Phases 1–7 below (existing workflow) |64| **Agent Sweep** | Full source tree available, maximize coverage, "find me everything" | Phase 0 → Phases S1–S4 → feeds into Phase 6 (Chaining) + Phase 7 (Gate) |65| **Hybrid** | Best of both — sweep for discovery, structured for exploitation | Phase 0 → Agent Sweep for discovery → Crown Jewel Mapping on findings → Phases 5–7 |66| **Swarm Pipeline** | Multi-agent SAST with effort tiers; invoked via `/vuln-swarm <path> [--effort=low\|medium\|deep] [--freeform=detached\|grounded]` | See `references/swarm-pipeline.md` § Effort Tiers. LOW = Phase 0 + freeform + Phase 3-lite; MEDIUM = full module fan-out + 2-check; DEEP = static-first lane + slice-type fan-out + 3-check + cross-slice reconciliation. |6768**Phase 0 (Latest Commits Security Review)** runs first in every mode whenever the target has git history — a brownfield-only recency pass executed by a single focused subagent before the broader audit begins. See Phase 0 below.6970**Weakness Registry** under v2 is DuckDB-native — `gr_findings` rows with `confirmation_status = 'confirmed'` ARE the registry. Cross-audit priors are recovered by querying the per-target DuckDB on `target_id` (or `targets.repo_url`) before Phase 1; `variant-of` / `enables` / `co-occurs-with` edges are derived at read time from `(finding_kind, sink_id, source_id)` overlap rather than persisted as a second store. The legacy on-disk JSONL+Markdown registry at `<target>/.vuln-registry/` is read-only fallback: load `references/weakness-registry.md` only when working with a pre-v2 target that still has that directory.7172**Default routing:**73- "audit this codebase" / "find vulns" (unscoped) → **Hybrid**74- "check the auth module" / specific component → **Targeted Audit**75- "find me zero days" / "sweep everything" → **Agent Sweep**7677---7879## Tooling Constraints8081**LSP for understanding, Grep/Glob for discovery.**8283When tracing where a symbol is defined or finding all references to it, prefer LSP (`goToDefinition`, `findReferences`, `hover`) when available. LSP gives exact results; Grep gives text matches.8485Use Grep/Glob for discovery (finding files, searching patterns). Use LSP for understanding (definitions, references, type info), then read the surrounding source needed to understand framework wiring, guards, decorators, module configuration, and dynamic dispatch.8687Avoid raw whole-repo dumps; do not avoid local file context that affects exploitability.8889---9091## Agent Sweep Mode (Phases S1–S4)9293> Load `references/agent-sweep.md` for full prompt templates, scoring rubrics, and integration details.9495When the goal is maximum coverage across a full source tree, use file-iteration with independent verification instead of domain-partitioned analysis. This is the Carlini methodology adapted for Claude Code.9697### Phase S1: Source Tree Segmentation98991. **Enumerate** all source files — exclude vendored/generated code (`node_modules/`, `vendor/`, `dist/`, generated protobuf)1002. **Partition** into work units by directory/module (not by attack domain — that's Targeted mode)1013. **Prioritize** by Attention Deficit Score (see Phase 2 addition below) — least-examined, highest-exposure code first1024. **Include test files** — they reveal expected invariants that may not be enforced103104### Phase S2: Discovery Loop105106For each source file (or small cluster), spawn a parallel agent:107108> "You are performing a security audit. Find exploitable vulnerabilities starting from `${FILE}`. Consider all bug classes — memory corruption, injection, logic flaws, auth bypass, deserialization, race conditions, type confusion, integer mishandling. Trace inputs from this file's entry points through the program. Write findings to `${FILE}.vuln.md` with: vuln type, affected function, source→sink trace, exploitability assessment, suggested payload.109>110> **Tooling:** Prefer LSP (`goToDefinition`, `findReferences`, `hover`) when available for symbol definitions, callers, and type info — exact resolution reduces same-name false positives from Grep text matches. Use Grep/Glob for discovery (locating files, searching patterns), then read the local file context needed for decorators, route registration, middleware, guards, module config, and dynamic dispatch."111112**Design properties:**113- **File-anchored, not domain-anchored** — each agent starts from a file, not "look for SQLi." The LLM's latent bug-class knowledge drives discovery, not a checklist114- **Stochastic by construction** — different starting files produce different inference paths; running the same file twice may surface different bugs due to sampling115- **Follow imports** — agents aren't limited to their starting file; the file is the *anchor* that seeds exploration direction116- **Parallelizable** — agents are independent; scale linearly with compute117118### Phase S3: Verification Loop119120Feed each `.vuln.md` back through a **fresh agent** (not the discoverer — avoids confirmation bias):121122> "You received an inbound vulnerability report in `${FILE}.vuln.md`. Verify this is actually exploitable. Trace the source→sink path yourself. Confirm controllability. Identify defense layers that might block it. Classify: **Confirmed** / **Plausible-Needs-Dynamic** / **False Positive**.123>124> **Tooling:** Prefer LSP (`goToDefinition`, `findReferences`, `hover`) when available to verify symbol definitions and callers. Use Grep/Glob for discovery, then read enough surrounding file context to confirm guards, framework wiring, and dynamic behavior."125126Expected filtration: ~40–60% of discovery findings survive verification.127128#### 2-check variant (higher-confidence audits)129130For audits that warrant stronger verification, upgrade the single-agent check to **two distinct checks executed as separate agent calls with separate prompts**. The two agents must not share a context window, and must not be told of each other's verdicts.1311321. **RE-TRACE** — an independent source→sink walk. The agent receives the finding's location and is asked: *does the path exist as claimed? Can the source be controlled? Does the taint survive the transforms?* The agent produces its own trace from scratch without trusting the report's.1331342. **JUDGE** — a semantic-correctness review. The agent receives the finding and its claimed root cause and is asked: *is the diagnosis correct? Is the bug class label accurate? Is the alleged data flow actually reachable in practice? Is the impact as stated, or over/under-claimed?*135136Combine the two verdicts:137- **pass BOTH** → `Confirmed`138- **pass ONE** → `Candidate` (flag the disagreement in the report)139- **fail BOTH** → `False Positive`140141Keeping the checks as **separate agent calls with separate prompts** is load-bearing. A single agent asked both questions collapses them into one mental pass and loses the independence that gives 2-check its precision. The full richer treatment — including how this plugs into weighted scoring — is in `references/swarm-pipeline.md` § Weighted Scoring.142143**Structured JUDGE variant.** Instead of asking JUDGE "is this finding correct?" in free text, instruct it to build a DAG from scratch against the cited code: extract source nodes, build intermediate nodes with parent IDs and primitives, run the 12-pattern check, converge on a sink. A JUDGE pass that cannot close the graph from an untrusted source to a `verified_sink` is a **False Positive** verdict — no hedging. See `references/dag-reasoning.md` § "Phase S3 — Agent-Sweep Verification" for the exact prompt.144145### Phase S4: Dedup, Cluster, Feed Forward1461471. **Deduplicate** findings pointing to the same root cause from different starting files1482. **Cluster** by bug class and affected component1493. **Feed verified findings** into Phase 6 (Chaining) and Phase 7 (Exploitability Gate)1504. The sweep finds the raw bugs; the existing methodology scores, chains, and proves them151152---153154## Domain Reference Map155156Load references on-demand based on the active testing domain. **Do not load all files at once.**157158| Domain | Reference File | Load When |159|--------|---------------|-----------|160| SQLi, NoSQL, SSTI, CRLF, LDAP, XPath, LaTeX Injection, CSV Injection, XSLT Injection | `references/injection-attacks.md` | Testing injection vectors |161| XSS, Prototype Pollution, CORS, CSTI, postMessage, DOM Clobbering, CSS Injection, Cookie Tossing | `references/client-side-attacks.md` | Testing client-side attacks |162| XS-Leaks, Clickjacking, CSP Bypass, Browser Desync, HTML Smuggling, Reverse Tabnabbing | `references/browser-attacks.md` | Testing browser security model attacks |163| RCE, SSRF, XXE, File Ops, Deserialization | `references/server-side-attacks.md` | Testing server-side attacks |164| Auth, Access Control, OAuth, Logic, Race, Crypto | `references/auth-access-logic.md` | Testing auth & business logic |165| Smuggling, Cache, WebSocket, GraphQL, DNS, Cloud, Encoding, ReDoS, HTML Smuggling, Prompt Injection | `references/protocol-infra-attacks.md` | Testing protocols & infrastructure |166| CI/CD Pipelines, GitHub Actions, Supply Chain, Runner Security, Workflow Poisoning | `references/cicd-supply-chain.md` | Testing CI/CD and supply chain attacks |167| n8n, Zapier, Make.com, Power Automate, iPaaS, Webhooks, Workflow RCE, Credential Theft | `references/automation-platform-attacks.md` | Testing automation/iPaaS platforms |168| Traefik, Nginx, HAProxy, Reverse Proxy Bypass, Terraform State, Docker Socket, Container Escape | `references/infra-misconfig-attacks.md` | Testing infrastructure misconfigurations (proxy, IaC, containers) |169| OpenTelemetry, Prometheus, Grafana, Log Pipelines, Telemetry Poisoning, Collector SSRF, Cardinality Bombs | `references/observability-telemetry-attacks.md` | Testing observability/monitoring infrastructure |170| Sinks router + SAST/DAST rules | `references/sinks-catalog.md` | Code audit entry point — routes to per-language sink files |171| PHP sinks | `references/sinks/php.md` | PHP code audit (exec, callbacks, type juggling, phar deser) |172| Python sinks | `references/sinks/python.md` | Python code audit (exec, pickle, SSTI, subprocess) |173| Node.js sinks | `references/sinks/javascript.md` | JS/Node code audit (child_process, prototype pollution) |174| Java sinks | `references/sinks/java.md` | Java code audit (Runtime, JNDI, ysoserial, format-specific deser) |175| **Scala sinks** | **`references/sinks/scala.md`** | **Scala code audit (ToolBox.eval, LazyList/TrieMap deser, Akka, Play, Slick/Doobie/Quill SQLi, Spark, effect systems, build system)** |176| Ruby sinks | `references/sinks/ruby.md` | Ruby code audit (system/eval, Marshal, ActiveRecord) |177| .NET sinks | `references/sinks/dotnet.md` | .NET code audit (Process.Start, BinaryFormatter, Json.NET) |178| Systems sinks (Go/Rust/C/Elixir) | `references/sinks/systems.md` | Systems code audit (memory corruption, os/exec, ETF deser) |179| Mobile sinks (Android/iOS) | `references/sinks/mobile.md` | Mobile code audit (WebView, intents, URL schemes) |180| Scala sinks | `references/sinks/scala.md` | Scala code audit (ToolBox.eval, LazyList/TrieMap deser, Akka, Play, Slick/Doobie/Quill SQLi, Spark, effect systems, build system) |181| Binary / RE / firmware / kernel: triage, static RE, fuzzing, memory-corruption classes, binary-level races, patch diffing, exploit primitives, mitigations | `references/binary-code-analysis.md` (thin index → `binary-triage-and-re.md`, `binary-bug-classes.md`, `binary-exploit-and-specialties.md`) | Target is a compiled binary, firmware image, kernel/driver, closed-source blob, or native source whose ABI/compiler/ordering behavior matters. Load only the lifecycle file the active trigger cites (see Phase 3.5). |182| Vulnerability chaining, scanning tools, blind spots | `references/chaining-advanced-techniques.md` | Building exploit chains, tool augmentation |183| Formal audit, PoC development, report writing | `references/audit-poc-report.md` | **On-demand only** — when asked for audit/PoC/report |184| Agent sweep methodology, file iteration, verification loops | `references/agent-sweep.md` | Running Agent Sweep or Hybrid mode |185| Swarm pipeline: module decomposition, orthogonal strategies, three-stage pass, analog cascade, weighted scoring, Phase 4 continuous-learning | `references/swarm-pipeline.md` | Running the Swarm Pipeline command / hypothesis-driven multi-agent audit |186| DAG-structured vulnerability reasoning (DAGVul): source/intermediate/sink nodes, 12 failure-pattern taxonomy, logical closure | `references/dag-reasoning.md` | Writing a finding's source→sink trace, running the Swarm JUDGE check, or mechanically answering Phase 7 Exploitability Gate Q1–Q3 |187| Weakness Registry: per-target persistent graph of Confirmed weaknesses (JSONL nodes + edges), prior-injection for future audits, dedup-by-deterministic-id, edge types (`variant-of`, `co-occurs-with`, `enables`, `bypasses`) | `references/weakness-registry.md` | Starting an audit on a target with `.vuln-registry/`, OR after Phase 7 marks any finding Confirmed (Phase 8 promotion writes to the registry) |188| **DuckDB schema** (16 tables + `confirmed_vulns` view) — persistence layer for the v2 phase pipeline | `db/schema.sql` (DDL) + `db/migrations/0001-initial.sql` (forward-only) + `db/sidecars/` (>16 KB payload BLOBs) | v2 pipeline runs — load when wiring orchestrator writes, debugging FK/CHECK failures, or migrating the database |189| **Critic rubric** for Phase 5 REPORT critic — comprehension / eligibility / attack_scenario checks, WARNING vs CRITICAL, 17 worked examples | `references/critic-rubric.md` | Phase 5 critic runs, or hand-classifying a finding's critic verdicts |190| **Bypass catalogue** for Phase 3 (S2) — global DuckDB `bypasses` table (sanitizer / blacklist / allowlist / generic families) with tag-indexed parsed-logic triggers + tiered fetch protocol | `db/catalogue/bypasses.json` (data) + `db/catalogue/schema.sql` (DDL) + `db/catalogue/load.sql` (idempotent loader) + `references/bypass-catalogue.md` (3-stage fetch protocol) | Bypass-hunting lanes (`defense_base_lane`, `defense_context_verification_lane`, `isolation_fuzz_lane`) — Stage A enumerate labels, Stage B record skip-with-reason, Stage C lazy-fetch one family's payloads at attempt time |191| **Confirmation Rigor Doctrine (C1)** — the four gates (taint reach / defense gap / intended-feature filter / reproduction artifact w/ `config_state`) for promoting `gr_findings.confirmation_status` from `candidate` → `confirmed`, plus refutation row shape | `references/confirmation-rigor-doctrine.md` | Phase 2 confirm runs, gate-by-gate refutation triage, or `gr_findings.config_state` column wiring |192| **Forward-Slicing Lanes (C2)** — slice tuple + `slice_kind` discriminator (`forward_taint` / `backward_sink` / `defense_callsite`), lane lifecycle, `coverage_json` shape, cascade-on-bypass + cascade-on-reach semantics | `references/forward-slicing-lanes.md` | Spawning lanes, debugging `success_without_artifact` / `incomplete_coverage` rewrites, or reasoning about cascade scheduling |193| **Autoloading Knowledge Layer (C3)** — seed (top-K=10) vs expand (cap 50, version-pinned), tri-signal acceptance (`ref_count`, `repeat_suppressions`, `growth_rate`, `staleness_days`), bootstrap rule R8 for first-audit single-signal admit, decay sweep | `references/autoloading-knowledge-layer.md` | Wiring `autoload_seed_lane` / `autoload_expand_lane`, or debugging why a chunk did/didn't graduate to core |194| **REPORT Critic Phase (C4)** — three checks (comprehension / eligibility / attack-scenario), `config_state` eligibility table (`vanilla` Pass / `non_vanilla` WARNING / `unknown` CRITICAL), severity storage contract that demotes CRITICAL findings to `refuted` at orchestrator flush | `references/report-phase.md` | Phase 5 critic runs, debugging blocked-report flushes, or deciding WARNING-vs-CRITICAL on a borderline `critic_findings` row |195196---197198## Phase 0: Latest Commits Security Review199200Before the broad audit begins, **spawn one focused subagent** to perform a narrow-scope security review of the repository's most recent commits. Recent diffs are the highest-signal starting surface in a brownfield target: they concentrate attacker-reachable new code, often touch security-adjacent paths (auth, routing, input parsing, config), and receive less scrutiny than older, stable modules. Reviewing them first primes the rest of the audit with concrete findings and calibrates the attack surface before Phase 1 (Recon) runs.201202This is intentionally **single-agent and narrow-scope** — whole-tree coverage belongs in Agent Sweep (Phases S1–S4). Phase 0 exploits the recency signal without drifting into full-sweep territory. A swarm would dilute focus across the small commit surface and produce duplicated, low-signal findings.203204### Subagent Prompt205206Spawn exactly one agent with this prompt:207208> You are performing a **focused, narrow-scope** security review of this repository's most recent commits. Inspect repo signals first — tag recency, branch divergence from `main`/`master`, commit cadence, CHANGELOG or release notes — then choose the most informative commit range yourself (e.g., last N commits, since last tag, or branch diff against main). **State the chosen range and justification before reviewing.**209>210> For every file touched by the selected commits, analyze **only the changed hunks and their immediate call graph**. Do not audit code the commits did not touch — that is Phase 3's and Agent Sweep's job, not yours. Consider all bug classes — injection, memory corruption, auth bypass, deserialization, race conditions, type confusion, logic flaws, missing authorization, unsafe defaults, exposed secrets, regressions that reintroduce previously-fixed CVEs, and weakened security controls (removed validators, loosened regex, new `@ts-ignore`/`# type: ignore` on security-adjacent code).211>212> For each finding write: vuln type, affected function/file, source→sink trace, controllability, exploitability assessment (High/Medium/Low), and a suggested payload or PoC direction. Flag commits that touch security-adjacent paths (auth, crypto, input parsing, session handling, access control, deser, SSRF-prone callers) even when no bug is found — the auditor needs to know where recent changes raise risk.213>214> **Fix-bypass analysis (n-day vector):** when a commit *fixes* a security bug, do not trust the fix. Enumerate inputs, encodings, types, code paths, and state-machine transitions the patch does **not** cover (e.g., alternate decoder, sibling endpoint, case/normalization differential, race window, deeper nesting, non-string type, second-order sink) and attempt to reach the original sink despite the patch. Incomplete patches are one of the highest-yield n-day sources — treat every security fix as a hypothesis "this specific path is now blocked," then try to falsify it.215>216> Stay **very accurate and very focused**: no speculation, no "theoretical" findings without a controllability trace, no drift into untouched code. If the chosen range surfaces no real vulnerabilities, say so explicitly and list which security-adjacent files were examined so the rest of the audit can trust the recency pass.217>218> **Tooling:** Prefer LSP (`goToDefinition`, `findReferences`, `hover`) when available for resolving the call graph of changed hunks — recency review is high-signal precisely because it stays anchored to actually-touched call sites. Use Grep/Glob for discovery (locating files, finding string patterns), then read enough surrounding context to validate framework wiring, guards, and dynamic dispatch.219220### Optional Deliverable: PATCH SEEDS221222When a downstream phase will fan out parallel agents (Agent Sweep, Swarm Pipeline, or any multi-agent audit that benefits from hypothesis templates), Phase 0 can emit a second artifact alongside the findings: a **PATCH SEEDS** list extracted from the same commit range. Each seed is a recently-fixed bug or tightened control that downstream agents use as a hypothesis template — "is an unfixed variant of this pattern present elsewhere in the tree?"223224Each PATCH SEED record:225226| Field | Content |227|-------|---------|228| `affected_file` | Path touched by the fix commit |229| `affected_hunk` | Hunk range or line numbers of the actual fix |230| `fix_summary` | One sentence describing what the patch changed and why |231| `bug_class` | Canonical class label (e.g., `sql-injection`, `missing-authz`, `path-traversal`) |232| `variant_query` | A grep-friendly or structural-search-friendly string downstream agents can use to locate analogous sites |233234Emit seeds only for commits that actually fix a bug or tighten a control — not refactors, not style changes, not dependency bumps unless the bump closes a CVE. A seed without a clear `variant_query` is low-value; drop it rather than weaken the set.235236### Fallbacks237238| Condition | Behavior |239|-----------|----------|240| No `.git` directory / no git history | Skip Phase 0, proceed to Phase 1 |241| Fewer than 3 commits in history | Skip Phase 0, proceed to Phase 1 |242| Recent commits are docs-only or generated files only | Record `NO_CODE_CHANGES` with touched paths, proceed to Phase 1 |243| Subagent fails or times out | Log the failure, proceed to Phase 1 — do not retry inline |244245### Feed-Forward246247Phase 0 findings plug into the same downstream pipeline as Agent Sweep output:2482491. **Dedup** against later Phase 3 (Source Audit) and any Agent Sweep results2502. **Feed** surviving findings into **Phase 6: Vulnerability Chaining**2513. **Gate** each finding through **Phase 7: Exploitability Gate** before reporting252253Do not promote a Phase 0 finding to a reported vulnerability without passing Phase 7 — the exploitability gate applies equally to commit-sourced findings.254255---256257## Phase 1: Recon258259Identify the full technology stack before touching anything:260- Language, runtime version, framework, template engine261- ORM / database layer and database engine262- Web server and its configuration (Apache, Nginx, Caddy, IIS, LiteSpeed)263- Reverse proxy / load balancer (HAProxy, Traefik, AWS ALB — each parses HTTP differently)264- Auth mechanism (session, JWT, OAuth, SAML, WebAuthn, custom)265- File upload support, allowed types, size limits266- API style (REST, GraphQL, SOAP, JSON-RPC, gRPC-Web, WebSocket)267- Debug mode status, verbose error pages, stack traces268- PHP version (5.x / 7.x / 8.x) — gates which sinks are exploitable: `assert()` evals strings only in < 8.0, `preg_replace /e` only in < 7.0, loose type juggling `0 == "string"` only in < 8.0, `libxml_disable_entity_loader()` removed in 8.0 (XXE defaults safe), hex numeric strings `"0x1A" == 26` only in < 7.0. **Always qualify PHP findings with the version gate.**269- PHP config: `allow_url_include`, `allow_url_fopen`, `disable_functions`, `open_basedir`, `display_errors`, `file_uploads`, `session.upload_progress.enabled`270- Node.js: `--inspect` port, `NODE_ENV`, prototype pollution surface271- Python: debug mode (Werkzeug debugger PIN), pickle usage, SSTI surface272- Java: JNDI enabled, deserialization libraries, Expression Language version273- Container context: privileged mode, mounted volumes, exposed docker socket, inter-container network, environment secrets, Kubernetes service account tokens274- CDN / WAF fingerprint (Cloudflare, Akamai, ModSecurity rules — know what you're bypassing)275- Client-side: JS frameworks (React, Angular, Vue), bundler (webpack, vite), source maps available276- Dependency manifest: `package.json`, `composer.json`, `requirements.txt`, `Gemfile`, `pom.xml`, `go.mod`, `Cargo.toml`, `mix.exs`277- `patch-package` / `pnpm patch` / `yarn patch` overlays (`patches/*.patch`, `patches_*/*.patch`): read every patch in the tree and treat each removed/added hunk as security-relevant by default. Overlays silently mutate vendored SDK invariants (scoring rules, crypto surface, consent UX) and do not show up in dependency scanners. A patch that `export`s a previously-private crypto method, adjusts an auth scoreFlow, or deletes a `Confirm*` modal is a finding-generator by itself.278- Known CVEs in detected versions (check NVD, Snyk DB, GitHub Advisories)279280Map every user input vector:281- URL parameters, path segments, fragments282- Request body (form-encoded, JSON, XML, multipart)283- HTTP headers (Host, X-Forwarded-For, Referer, User-Agent, Accept-Language, custom headers)284- Cookies285- File upload content and metadata (filename, content-type, EXIF)286- WebSocket messages287- DNS records (for DNS rebinding)288- API field names (for mass assignment)289290Map every endpoint. Build a table of routes, methods, auth requirements, and parameters before testing.291292---293294## Phase 2: Crown Jewel Mapping295296Before testing, identify maximum-damage targets:2972981. **Data assets**: PII stores, payment processing, admin credentials, API keys2992. **Privilege boundaries**: admin panels, role escalation paths, multi-tenant isolation3003. **Trust transitions**: internal services, SSO providers, cloud metadata endpoints3014. **Business logic**: financial operations, state machines, approval workflows302303Attack the highest-value targets first.304305### Attention Deficit Mapping306307After identifying crown jewels, identify the **least-examined** code — where bugs survive because nobody looked, not because the code is sound:308309| Signal | High Attention (lower bug probability) | Low Attention (higher bug probability) |310|--------|---------------------------------------|---------------------------------------|311| **Security commits** | Has `fix: security`, CVE references, audit comments | No security-related commits in history |312| **Fuzzing/testing** | Fuzz targets exist, high test coverage | No fuzz corpus, low/no test coverage |313| **Code glamour** | Auth module, crypto, payment processing | Parser, format handler, protocol adapter, config loader, migration script |314| **External exposure** | Behind auth wall, internal-only | Processes attacker-controlled input (uploads, webhooks, public API) |315| **Code age** | Recently written/reviewed | Legacy code, "don't touch" modules, vendored-then-forgotten |316317**Prioritize: high exposure + low attention.** These are the targets that have never seen a fuzzer. The crown jewels approach finds the highest-*impact* targets; attention deficit mapping finds the highest-*probability* targets. Use both.318319Quick heuristics:320- `git log --format='%s' -- <path> | grep -ic 'secur\|vuln\|cve\|xss\|sqli\|inject'` — zero hits = never audited321- Check for adjacent `*_test.*`, `*_spec.*`, `fuzz_*` files — absence = untested322- `git log --diff-filter=M --since="2 years ago" -- <path>` — no recent changes = stale, possibly forgotten323324---325326## Phase 3: Source Audit327328Run parallel agents, each focused on one attack domain. Every agent traces **source to sink** — user input reaching a dangerous function.329330| Attack Category | Key Targets | Reference |331|----------------|-------------|-----------|332| **Injection** (SQLi, NoSQL, SSTI, CRLF, LDAP, XPath) | Query builders, template renders, header construction | `injection-attacks.md` |333| **Client-Side** (XSS, Proto Pollution, CORS, CSTI, DOM Clobbering, CSS Injection) | Output contexts, deep merge, origin validation | `client-side-attacks.md` |334| **Browser** (XS-Leaks, Clickjacking, CSP Bypass, Browser Desync, HTML Smuggling) | Cross-origin side channels, UI redressing, CSP evasion | `browser-attacks.md` |335| **Server-Side** (RCE, SSRF, XXE, File Ops, Deser) | Command exec, URL fetching, XML parsing, file I/O, object deser | `server-side-attacks.md` |336| **Auth & Logic** (Auth, ACL, OAuth, Race, Crypto) | Session mgmt, role checks, token flows, concurrent ops, key mgmt | `auth-access-logic.md` |337| **Protocol & Infra** (Smuggling, Cache, WS, GraphQL, DNS, Cloud) | HTTP parsing, cache keys, WS handlers, query depth, metadata | `protocol-infra-attacks.md` |338339Every module agent MUST conclude its report with a **Blind Spots** block: files it did not read, components absent from the repo but referenced elsewhere (other-repo Rust halves, dynamically-fetched configs, production-only artifacts), runtime states it could not observe (OIDC discovery docs, feature-flag evaluation), and dependencies whose behavior gates its findings' severity. Blind spots are first-class output, not footnotes. Phase 6 chain synthesis consumes this list to flag findings whose severity depends on external evidence.340341---342343## Phase 3.5: Technology Stack Discovery (Sink Loading)344345Before taint analysis, identify **every language and framework in the stack** — most targets are polyglot:3463471. **Enumerate languages**: scan file extensions, shebangs, `package.json`/`composer.json`/`pom.xml`/`go.mod`/`Cargo.toml`/`mix.exs`/`Gemfile`/`requirements.txt`3482. **Identify the stack layers**: e.g., PHP backend + Node.js build tooling + Python microservice + Java auth service3493. **Load matching sink files**: for each language present, load the corresponding `references/sinks/<lang>.md` — load multiple if the target is polyglot3504. **Load the SAST/DAST router**: `references/sinks-catalog.md` for cross-language Semgrep/CodeQL/SonarQube rules351352**Example**: a Laravel app with React SSR and a Python ML microservice → load `sinks/php.md` + `sinks/javascript.md` + `sinks/python.md`353354Do not skip minor languages in the stack — the weakest link is often the least-reviewed service.355356**Binary / native artifacts in the stack — tiered loading across three lifecycle files.** Source-level sinks stop at the compiler; ABI, memory ordering, calling conventions, packers, and machine-level race windows require binary audit. The binary reference is split into three lifecycle files — **orient**, **find bugs**, **prove and report** — plus a thin routing index at `references/binary-code-analysis.md`. Load only what the trigger cites; never the whole triad by default.357358| Trigger (any match → load) | File(s) and section(s) to read first |359|---|---|360| Target artifact is ELF / PE / Mach-O / WASM / dex / firmware blob / kernel module / bootloader / TEE payload | `references/binary-triage-and-re.md` § 1 → § 2 → § 2b |361| Source audit hit a `.so` / `.dll` / `.dylib` / static `.a` with no matching source | `references/binary-triage-and-re.md` § 2–4, then `references/binary-bug-classes.md` § 10 |362| Source is present but contains C / C++ / Rust `unsafe` / Go `cgo` / Zig / Objective-C / inline `asm!` where ABI or ordering changes semantics | `references/binary-bug-classes.md` § 6 + § 7 + § 15 |363| Hypothesis involves memory layout, stack alignment, calling convention, endianness, signal delivery mid-instruction, syscall atomicity, double-fetch, weak memory model | `references/binary-bug-classes.md` § 7 + § 8 + § 15 |364| N-day work: public advisory + patched vs. unpatched binary, no source diff | `references/binary-exploit-and-specialties.md` § 11 |365| Crash found but no source explanation — the bug may live in compiler output / linker glue / TLS callback / `.init_array` | `references/binary-triage-and-re.md` § 4 + `references/binary-bug-classes.md` § 15 |366| Packed, VM-protected, anti-debug, or otherwise obfuscated sample | `references/binary-exploit-and-specialties.md` § 13b |367| Building or claiming an exploit primitive (ROP/SROP/ret2dlresolve/JOP/heap grooming) | `references/binary-exploit-and-specialties.md` § 13 + § 14 |368| Firmware image / IoT / router / printer / camera / automotive ECU | `references/binary-exploit-and-specialties.md` § 12.1 |369| Kernel / driver / hypervisor / TEE target | `references/binary-exploit-and-specialties.md` § 12.2–12.5 + § 14 |370| Writing a fuzz harness or running dynamic analysis | `references/binary-bug-classes.md` § 5 |371| Building a binary-level taint DAG | `references/binary-bug-classes.md` § 10 |372| Writing a binary finding report | `references/binary-exploit-and-specialties.md` § 16 (DAG block required — ties back to Phase 7 Gate) |373374**Do not load the whole triad by default.** On targets with no native component, none of the above triggers fire and these files stay off the token budget. On triggered targets, load only the subfile(s) the matched trigger cites. When no single trigger dominates, start with `references/binary-code-analysis.md` (thin index, ~60 lines) and fan out from there.375376**Binary findings integrate with the source pipeline unchanged:** they feed **Phase 6 Chaining** as primitives (info-leak / arb-read / arb-write / control-flow) and pass **Phase 7 Exploitability Gate** via the same DAG form as source findings — with `primitive ∈ {taint, cfg, alias, constraint, abi}` and `abi` nodes citing the calling convention / register / struct layout being relied on. See `references/binary-bug-classes.md` § 10 (Binary-Level Taint Framework) and `references/binary-exploit-and-specialties.md` § 16 (Output Format) for the binary-specific DAG vocabulary.377378### Tool-Integration Matrix (CPG / SAST / AST tooling)379380For DEEP-tier Swarm Pipeline runs and any audit where a mechanical pre-pass is available, select in priority order:381382| Priority | Tool | Representation | When to use |383|----------|------|----------------|-------------|384| 1 | **Joern** | Code Property Graph (AST + CFG + DFG + call graph) | Full inter-procedural taint, PDG cuts, call-chain slicing. Best when a queryable graph justifies indexing cost (large C/C++/Java/JS/Python targets). |385| 2 | **CodeQL** | Relational AST + dataflow library | Path queries from stdlib sources to sinks. SARIF output. Use when a pre-built query pack matches the stack. |386| 3 | **Semgrep + ast-grep** | Semantic patterns (Semgrep) + structural AST matching (ast-grep) | Cheapest rule-writing path. Semgrep for dataflow-aware rules; ast-grep for language-agnostic structural hunts. |387| 4 | **Fallback: `sinks/<lang>.md` grep** | Plain text | No CPG/SAST tooling available — the per-language sink files are ripgrep-ready. |388389Outputs from layers 1–3 are packaged as SecuritySlice input packets (see `references/dag-reasoning.md` § SecuritySlice Input Packet) for LLM consumption. LLM agents treat tool hits as **hypotheses to verify**, never as findings to rubber-stamp.390391**Why CPG over AST-first:** Raw AST lacks the security-relevant edges — data dependencies, control dependencies, call targets, aliasing. A CPG merges all four, which means one query answers "does untrusted input reach this sink under these guards?" without re-implementing dataflow per rule. See `references/swarm-pipeline.md` § Slice Types for the 11 slice cuts the tooling can emit.392393---394395## Phase 4: Taint Analysis396397Three strategies — choose based on codebase size:398399| Strategy | When | Method |400|----------|------|--------|401| **Source-forward** | Small codebase, few entry points | Trace from user input → through transforms → to sinks |402| **Sink-backward** | Large codebase, known dangerous functions | Start at sinks (see `sinks-catalog.md`) → trace backward to find controllable inputs |403| **Hybrid** | Medium codebase, complex data flow | Combine both: forward from sources AND backward from sinks, meet in the middle |404| **Circulatory tracing405406…(truncated)