Skip to content

Commit 8262fd9

Browse files
peterc3dev-uxclaude
andcommitted
docs(phase-4): mark P3 shipped (commit 8bfa48d) + P3.5 follow-up
P3 status flips from "pending" to "shipped". Action list rewrites to match what was actually built: ffuf wired as ToolKind::Ffuf gated on --active, hostname scope guard before invocation, no -follow-redirects, 20 req/sec default, bundled mini wordlist, confirmation banner with --yes / AGENTSPYBOO_ACTIVE_CONFIRMED=1 bypass. ffuf findings flow through the unified all_findings list (kind="ffuf") rather than a separate ffuf_findings field — simpler, dedup + report rendering already handle kind. P3.5 follow-ups documented: - IP-scope check (deferred until --scope-cidr exists) - Live LLM-driven E2E (needs an authorized active-fuzz target — unit tests + direct ffuf invocation cover the structural pieces) Phase 4 status overall: P1 + P2 + P3 all shipped. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
1 parent 8bfa48d commit 8262fd9

1 file changed

Lines changed: 20 additions & 15 deletions

File tree

PHASE-4-SPEC.md

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
**Drafted:** 2026-04-18
44
**P1 revised:** 2026-05-10 (post-validation ablation + cap-fix, see below)
5-
**Status:** P1 shipped (commits 42fd6a2 + cd0c375). P2 shipped (commit 4f740ec). P3 pending.
5+
**Status:** P1 shipped (42fd6a2 + cd0c375). P2 shipped (4f740ec). P3 shipped (8bfa48d). One follow-up tracked (P3.5 IP-scope).
66
**Previous phase:** Phase 3 (Pius preflight) shipped 2026-04-16 on main
77

88
---
@@ -90,25 +90,30 @@ The three changes are complementary, not redundant: dnsx for efficiency on dead-
9090

9191
### P3 — Active recon mode (ffuf)
9292

93-
**Current state:** All recon is passive. No content discovery. Nuclei scans templates but doesn't brute-force directories.
93+
**Current state (pre-P3):** All recon is passive. No content discovery. Nuclei scans templates but doesn't brute-force directories.
9494

95-
**Proposed:** ffuf as a new `ToolKind::Ffuf`, fired only when `--active` flag is set on the CLI.
95+
**As shipped (8bfa48d):** ffuf is a `ToolKind::Ffuf` that the LLM only sees in its tool list when `--active` is set. Off by default — passive runs are byte-identical to pre-P3 behavior.
9696

97-
**Safety rails (hard requirements):**
97+
**Safety rails as shipped:**
9898

99-
- **Scope enforcement — both hostname AND IP.** Ffuf only fires against hosts confirmed in scope by the existing host_in_scope check. Additional check: resolve the host's IP at ffuf-fire time and verify the IP isn't out of scope (e.g., the hostname matches but resolves to a third-party CDN edge that's technically out of authorized scope). Added 2026-04-18 per Boo2 review.
100-
- **No redirect following in active mode.** ffuf default `-follow-redirects off` stays off during active probing. Redirect chains can lead to out-of-scope hosts — blast radius risk. Added 2026-04-18 per Boo2 review.
101-
- **Active-flag gate.** Passive mode (default) never invokes ffuf. Period.
102-
- **Rate limit default.** `-rate 20` hard default (20 req/sec). Env var override `AGENTSPYBOO_FFUF_RATE`.
103-
- **Wordlist default.** Small wordlist (common.txt, ~4600 entries) by default. Large wordlists opt-in via `--ffuf-wordlist large`.
104-
- **Authorized-scope banner.** When `--active` is set, print a confirmation prompt unless `-y` or env var `AGENTSPYBOO_ACTIVE_CONFIRMED=1`.
99+
- **Hostname scope guard.** ffuf URL is run through `host_in_scope` before invocation; out-of-scope URLs are dropped with a logged warning, mirroring how subfinder/httpx already gate.
100+
- **No redirect following.** No `-r` flag passed to ffuf — redirect chains stay where they are.
101+
- **Active-flag gate.** The system prompt only describes ffuf to the LLM when `cfg.active` is true. Passive runs cannot invoke it even if a confused LLM guesses the tool name (`from_name("ffuf")` returns `Some(Ffuf)` always, but the dispatch only fires when the LLM emits the call, and the LLM only sees ffuf when active is set).
102+
- **Rate limit.** Default `-rate 20` (20 req/sec), `-t 20` threads. Env overrides: `AGENTSPYBOO_FFUF_RATE`, `AGENTSPYBOO_FFUF_THREADS`, `AGENTSPYBOO_FFUF_TIMEOUT`.
103+
- **Wordlist.** Default is a hand-curated ~100-entry mini list bundled at `assets/ffuf-common-mini.txt` via `include_str!` — covers common admin/auth/dotfile paths without large-list runtime cost. Override with `--ffuf-wordlist /path/to/SecLists/...` for deeper coverage.
104+
- **Authorized-scope banner.** `main.rs` prints a confirmation banner before the agent loop when `--active` is set; bypass via `--yes` / `-y` flag or `AGENTSPYBOO_ACTIVE_CONFIRMED=1` env var (so CI runs don't hang on stdin).
105105

106-
**Phase 4 action:**
106+
**Phase 4 action (as shipped):**
107+
108+
- **P3.1 — `src/tools/ffuf.rs`.** `exec_ffuf` (one URL at a time), `parse_ffuf_output` (severity heuristics: sensitive-path 200 = High, admin-path 200/401/403 = Medium, generic 200 = Low, 30x = Info), `resolve_wordlist` (user path or bundled mini-list). 5 unit tests.
109+
- **P3.2 — CLI flags.** `--active`, `--yes` / `-y`, `--ffuf-wordlist` on the Recon subcommand. Threaded through `Config`.
110+
- **P3.3 — react_loop dispatch.** Pulls URL from LLM args (`{"url": "..."}`) or falls back to first scoped httpx-live URL. Scope guard runs before the binary spawn.
111+
- **P3.4 — Findings.** ffuf findings flow into `all_findings` with `kind = "ffuf"`, deduplicated and severity-sorted alongside other tool output. The original spec proposed a separate `ffuf_findings` field; rejected in favor of the unified findings list because the dedup + report rendering already handle a `kind` column cleanly and a separate field would have meant a second report sub-table for no real gain.
112+
113+
**Deferred to a P3.5 follow-up:**
107114

108-
- **P3.1 — Implement `src/tools/ffuf.rs`** following the existing httpx/nuclei module pattern.
109-
- **P3.2 — Add `ActiveMode` config enum** and CLI flag `--active`.
110-
- **P3.3 — Wire into react_loop.rs** as an optional stage after nuclei, gated on active mode.
111-
- **P3.4 — Add `ffuf_findings` to `RunRecord`** as its own field (don't mix with nuclei findings — different classes of finding). Use the same confidence-scoring schema as nuclei findings for consistency across the report.
115+
- **IP-scope check.** Original spec called for resolving the URL's IP at fire time and verifying against authorized IP ranges. Shipped without this because there's no `--scope-cidr` flag yet — adding the resolver without a scope-IP set would only log, not enforce. Cleaner to land both pieces together when CIDR scope arrives.
116+
- **Live LLM-driven E2E validation.** Unit tests cover wordlist resolution (3 cases), severity classification (5 paths), and FUZZ-URL formation. Direct ffuf invocation against `peterc3-dev.github.io` confirms the binary integration works (0 results because it's a static Jekyll site with nothing under common paths). Did not exercise the agent's LLM dispatch live because peterc3-dev.github.io has no subfinder hits and the agent bails per skip rules. To validate end-to-end the user needs a target with subfinder hits + httpx-live URLs + active-fuzz authorization — left for the user when one is at hand.
112117

113118
---
114119

0 commit comments

Comments
 (0)