Date: 2026-06-13 | Target: Gitea (self-hosted, localhost) | Result: 2 high-severity classes WALK CLEAN (SSRF + label-IDOR), 1 finding earlier (feed token-scope) | Method: parallel fleet (2 Explore agents) + operator-side empirical verification
Parallel white-box fan-out on independent surfaces of an already-stood-up target = cheap, broad coverage. Two Explore agents (SSRF, IDOR/BOLA) read the local clone concurrently (no build, no RAM), each returning file:line candidates + a live-test recipe. Zero new setup cost because the instance + source were already up from the token-scope hunt.
NEVER trust a subagent's candidate - re-derive from code, then confirm live (Pattern-08 discipline). Both agents returned plausible "vulnerabilities." Both were pruned on verification:
- SSRF: agent flagged migration ALLOWED_DOMAINS-resolves-to-127.0.0.1 + OIDC discovery URL. Both are admin-gated (an admin can already make the server fetch anything) -> not a privilege-boundary crossing, and the migration case is a documented in-code TODO caveat. Webhooks are properly validated (DialContext re-validates resolved IP on every connect = DNS-rebind/redirect-proof). CLEAN for a non-admin attacker.
- Label IDOR: agent flagged AddIssueLabels/DeleteIssueLabel loading labels via GetLabelsByIDs/GetLabelByID (raw WHERE id IN(...), no repo_id filter) - a REAL unscoped router load. BUT empirically: attaching a private-repo label by ID to your own issue returns []/200 (silent no-op), discloses nothing. Root cause of the SAFETY: models/issues/issue_label.go filters every label with if l.RepoID != issue.RepoID && l.OrgID != issue.Repo.OwnerID { continue } (lines 97/128/435/443). The ownership check lives in the MODEL layer, not the router.
A handler loading an object by user-supplied ID without a repo/owner-equality check is only an IDOR if NO downstream layer (service/model/query) re-enforces ownership before the sensitive read/write/disclosure. Trace the full path: router-load -> service -> model/SQL -> response serialization. The bug is real ONLY if the unscoped object reaches a sink (returned to attacker, written, or its fields disclosed). Confirm with a live 3-state test: (1) attacker can't access object legitimately (control = 404), (2) attacker performs the cross-tenant op, (3) check the RESPONSE/DB for the victim object's data. If step 3 is empty -> downstream guard exists -> prune (defense-in-depth nit, not a vuln). This prevents the "unscoped-load = IDOR" overclaim that static analysis (and LLM subagents) love to produce.
Contrast with the REAL finding same session (feed token-scope bypass): there the unscoped path reached the sink (private commit data WAS returned). The difference between finding and false-positive is always "does it reach the sink," proven live - not "is the load unscoped," read statically.
Stopped after these 2 classes (Pattern-09 cost-governor): token-scope cluster fully audited (1 find), SSRF clean, IDOR/label clean. Diminishing returns on this target on this box; held rather than spawning more fleet rounds.