Distills ~25 lessons (cycles 298-329) into ONE coherent method. This is the compound moat:
the durable playbook, not scattered fragments. Feeds the agent-mcp-security-audit skill.
0. What this session proved
The AI coding-agent + MCP ecosystem shares a small set of STRUCTURAL bug CLASSES; each big
disclosure (Wiz GhostApproval, OX/CSA MCP-by-Design, GuardFall) covered only PART of the
landscape, leaving UNSWEPT SLICES. We confirmed 2 real findings (continue repo-open RCE;
cline/Amazon Q symlink containment) + mapped the DEFENSES that work. The constraint turned out
to be find->FILE velocity (findings decay in days), not find-rate.
1. THE THREE STRUCTURAL CLASSES (what to look for)
- Path-containment (file tools). The "is this path in the workspace?" gate is LEXICAL
(path.resolve/relative/startsWith, no realpath) while the sink follows symlinks -> auto-approved
write/read OUTSIDE the workspace. Audit via the 6 lenses: (1) boundary realpath-aware?
(2) dangling/new-file case (realpath ENOENT fallback uses the link NAME)? (3) ancestor symlink?
(4) segment-boundary prefix (
/allowed vs /allowed-evil)? (5) per-tool coverage (does grep/
read/applyEdit/move-dst skip the guard)? (6) search read-leak (agent-path as ripgrep root).
- Config-source trust (repo-open RCE). A REPO-COMMITTED config (
.continue/mcpServers,
.zed/settings.json, .aider.conf.yml, model launchers, LSP binaries, tasks, hooks) is
auto-loaded and its command SPAWNED with NO consent/trust gate. 2-question test: (a) config
source workspace-shippable or global-only? (b) auto-spawn without a consent gate? Both YES = RCE.
Then ENUMERATE THE WHOLE project-config->exec family (MCP + model-launcher + LSP + task/lint +
git-hook + context-provider), not just MCP.
- Command auto-approval ("Friendly Fire"/GuardFall). Allowlist matched by string (chaining/
substitution/
${x:-$(...)} bypass) OR an all-or-nothing flag. NOTE: this class is now
SATURATED (GuardFall covered 10/11 OSS agents) - usually a walk.
- os.Root (Go 1.24+) = structural traversal-safe file access (Forgejo template fix). When file
ops go through
os.OpenRoot+root.*, symlink-escape is closed. WALK.
- realpath-full + segment-boundary + O_EXCL/
wx + write-temp-then-atomic-rename + per-op
(MCP reference filesystem server). "realpath-before-check" ALONE misses the dangling case.
- zed Worktree Trust (GHSA-cv6g) = defaults-closed project-config trust (project config doesn't
apply until the worktree is trusted). The model for repo-open-RCE.
- Amazon Q fingerprint-triple consent (serverName+config-fingerprint+workspaceHash).
- Global-only config source (cline/void/OpenHands MCP) = repo can't ship one = safe.
- Tokenized 3-tier command classifier (continue) = the command-auto-approval done right.
3. TARGET SELECTION (where the yield actually is)
- Hunt UNSWEPT SLICES of a big disclosure, NOT freshly-CVE'd popular targets. Wiz covered
commercial-only -> OSS agents were the slice (our findings). A class-disclosure that NAMES your
target = decay. Swarmed CVEs (PraisonAI 14 SSRF advisories; aider config-cmd open PRs) = $0 dup.
- Pivot the CLASS on a known target before abandoning it (continue: symlink saturated, but
MCP-autostart was fresh = the RCE). Fresh-class-on-known-target > fresh-target-cold-start.
- Port-lag fork-EV ranking: best = shares code + BATCHES/lags ports + maintained-enough-to-
credit (Forgejo<-Gitea = 12 gaps). Low = fast porter (OpenBao<-Vault) or divergent+saturated+
unmaintained (Gogs<-Gitea). Verify the fork SHARES the vulnerable CODE, not just lineage.
- Central-vs-point-fix predictor: a fix INSIDE a shared helper/choke point protects all callers
(walk the sibling hunt); a PER-SITE fix leaves siblings (the incomplete-fix yield). Read WHERE
the fix lives before enumerating siblings.
- Incomplete-fix tells: mechanism-divergent partial port (fix covers main path, misses wiki/
sibling); canonicalize-existing-only (misses dangling); guard-applied-inconsistently-across-tools;
build-tag/variant split (verify the security PROPERTY in EACH variant, not just the convenience).
- Screen for a co-resident unrestricted shell tool FIRST (goose): if present, file-containment
is by-design-moot = the vendor declines. Don't invest.
4. THE DISCIPLINES (what keeps reports credible - non-negotiable)
- GATE-0 before ANY finding counts: (a) exact-sink disclosure (open+closed issues/PRs, CVE,
GHSA, huntr, web - LIVE-WORKS != UNDISCLOSED); (b) target archived/EOL/acquired check (Roo-Code
archived; continue acquired-by-Cursor+shutting-down - RE-CHECK right before filing, a target dies
between staging and filing); (c) vendor-stance (accepts-class / disputes / by-design-shell).
- Re-verify the disclosure gate + EOL immediately BEFORE filing, not just at discovery. In a HOT
class findings decay in DAYS (GhostApproval named Amazon Q -> our incomplete-fixes decayed within
a week). Find->file velocity is the constraint. This session's pre-filing re-verify caught 1 EOL +
3 decays out of 13, shrinking the clean pile to the truly-fileable set.
- Faithful PoC + honest scope: verbatim-code harness OR self-hosted benign marker; never fabricate
output; never overclaim a live run you didn't do ("source + shipped-artifact confirmed, live trigger
auth-gated" when true). Attempting live-confirm + honestly reporting the blocker STRENGTHENS a report.
- Per-subsystem posture: score each tool-surface independently (continue = weak file-symlink,
strong command). Never generalize "this tool is (in)secure" from one subsystem.
Our own findings are PERISHABLE in a hot space. The bottleneck is not lead supply - it's realized
value (filing) + velocity. When the hunt lanes are genuinely dry (all classes swept, triggers not
fired), DON'T churn saturated surfaces - redirect to: file the pile, productize the method (the
Securva moat), or hold cheaply until a fresh trigger. Every cycle should still leave the method
SHARPER; when it can't find a bug, it can bank a rule, build a capability, or harden the pile.
Provenance
Cycles 298-329 (2026-07-14/15). Individual lessons: ~/bounty/lessons-library/2026-07-1[45]-cycle*.
Positive case studies: ~/bounty/skills/_shared/positive-case-studies/{mcp-filesystem,forgejo-os-root}*.
Productized: ~/.claude/skills/agent-mcp-security-audit/ (SKILL+CHECKLIST+REPORT-TEMPLATE+RECON-SCREEN).