Threat model
This page enumerates the threats the catalog is designed to defend against, the controls in place today, and — honestly — the residual risk for each. If you’re a security reviewer evaluating whether to adopt this marketplace, this is the page that tells you what we model and what we don’t.
Status conventions:
- ✅ Implemented — the control exists and is exercised on every PR or build.
- ⚠️ Partial — the control exists but isn’t fully CI-enforced, or it relies on human review of free-form content.
- ❌ Pending — the control is named but not yet shipped.
T1 — Supply chain via plugin install
Section titled “T1 — Supply chain via plugin install”Background. A user runs claude plugin install <plugin> and the plugin contains a hook, skill, or MCP server config that exfiltrates credentials or takes unauthorized actions on first run. Real incidents in the last 12 months have shown that cloning untrusted Claude Code repos can leak data before any trust dialog appears.
Attacker. A malicious or compromised plugin author. May be external, may be an account on a different marketplace the user has added.
Impact. Credential theft (API keys, tokens, OAuth refresh secrets); arbitrary file read; arbitrary tool invocation in the user’s session.
Boundary crossed. Marketplace ↔ user workstation.
Controls in place.
- Plugin bundles in this marketplace go through PR review against CLAUDE.md and the standards pages.
scripts/validate-bundles.mjsenforces structural rules on every PR — no bareBash, no credential paths in tool patterns, no missing required files, noWebFetch(domain:*)wildcard.- gitleaks scans every PR diff for committed secrets.
- The marketplace JSON is regenerated from
plugins/at build time — there is no path to add a plugin to the marketplace without it appearing underplugins/first.
Status: ⚠️ Partial. The above protects what’s inside this marketplace. It does not protect users who install plugins from other marketplaces. Enterprise deployments should pin an allowedMarketplaces list in managed settings — that is enterprise-deployment territory and lives outside this repo.
Residual risk. A determined attacker who compromises a maintainer account could push a malicious commit; branch protection and CODEOWNERS narrow this but don’t eliminate it. A user who explicitly trusts an untrusted marketplace bypasses every catalog-side control.
T2 — Confused-deputy via MCP connectors
Section titled “T2 — Confused-deputy via MCP connectors”Background. An MCP server holds credentials with broader scope than the user does — a service account with cross-tenant access, a write-capable token in a “read-only” workflow, an admin role bound to a normally-restricted user. Claude, at the user’s request, calls a tool on that server, and the request is answered with data the user shouldn’t have had access to (or worse, performs a write).
Attacker. Anyone who can write the user’s prompts or feed the user content that gets processed through Claude. Not necessarily malicious — also includes honest users accidentally exceeding their own access.
Impact. Information disclosure across trust boundaries; cross-tenant data leak; unauthorized writes.
Boundary crossed. User permission scope ↔ MCP service-account scope.
Controls in place.
- The MCP server standards require default-deny against a single scoped namespace and no production writes by default. Mutating tools against production require an explicit confirmation env var.
- Secrets ship via env vars or keychain, never embedded in the committed config.
- Every tool documents its side effects in the README so reviewers can spot scope creep at PR time.
Status: ⚠️ Partial. The standards rules are author-side. There is no runtime enforcement that an MCP server is actually default-deny — only that the published config and documentation say so.
Residual risk. A bundled MCP server whose code does not match its documented behavior is invisible to the validator. Reviewers reading the server’s source code is the only check. The plan is to add an MCP gateway in enterprise deployments that pins per-server scopes at the network boundary — that work is out of scope for the catalog and tracked separately.
T3 — Prompt injection via skill content
Section titled “T3 — Prompt injection via skill content”Background. A SKILL.md or resource file in the catalog contains instructions that cause Claude to take an action the user did not intend — exfiltrating data, running a destructive command, chaining into another skill — when the user invokes it.
Attacker. A malicious contributor, or an account whose maintainer access predates a turn to hostility.
Impact. Anything within the tool allowlist of the affected skill. The blast radius is bounded by allowed-tools.
Boundary crossed. Author intent ↔ user intent.
Controls in place.
- Every
SKILL.mdis read by a human reviewer against the standards page before merge. - Tool allowlist scope means a skill restricted to
Read, Grepcannot write files or execute shell, even if its prompt tells Claude to. - The 500-line
SKILL.mdlimit forces depth into supporting files, which are loaded on demand — limiting the volume of attacker-controlled instructions Claude reads on first invocation. - CLAUDE.md rule 3 (least-privilege) is enforced by the validator on every PR.
Status: ⚠️ Partial. Code review catches obvious injections; subtle ones (encoded instructions, chains across multiple files, instructions hidden in supporting content the body tells Claude to read) require careful reading.
Residual risk. A clever prompt injection that passes review. Mitigation depends on the tool allowlist limiting the damage. See also the prompt security training module for direct, indirect, and zero-click variants and the user-side practices that complement this control.
T6 — Credential exposure via skills
Section titled “T6 — Credential exposure via skills”Background. A skill, hook, or MCP config grants Claude access to a directory or file that contains credentials (~/.aws/credentials, ~/.ssh/id_rsa, browser keychains). Even if Claude doesn’t intend to read those files, a prompt injection or a buggy glob pattern could surface their contents.
Attacker. Same as T3 — anyone who can influence Claude’s prompts.
Impact. Credential theft. Often the credentials are higher-value than anything inside the user’s project.
Boundary crossed. Skill scope ↔ user’s secret storage.
Controls in place.
- The validator’s R8 rule blocks any
allowed-toolspattern that references.aws,.ssh,.azure,.gcloud, orCryptodirectories —CRITICALseverity, fails the build. - Standards pages explicitly call out these directories as forbidden.
- gitleaks catches secrets that were accidentally committed to the repo (a separate failure mode, same threat class).
Status: ✅ Implemented. R8 is hard-blocked in CI. Standards pages document the rule. gitleaks runs on every PR.
Residual risk. A user who manually edits their own ~/.claude/settings.local.json to grant access overrides the bundle. That’s a personal choice and not a catalog concern. CLAUDE.md rule 9 explicitly forbids using the dev-tooling settings file to ship product behavior.
T7 — Data exfiltration via WebFetch
Section titled “T7 — Data exfiltration via WebFetch”Background. A skill with broad WebFetch access posts the contents of files it read (or data from MCP responses) to an attacker-controlled URL — either via prompt injection or via a deliberately malicious skill.
Attacker. Malicious skill author, or a prompt injection acting through a legitimately-published skill that has broader WebFetch than it actually needs.
Impact. Exfiltration of project source, credentials embedded in source, or MCP response data.
Boundary crossed. Skill scope ↔ public internet.
Controls in place.
- The validator’s R7 rule blocks
WebFetch(domain:*)wildcard. Domains must be enumerated explicitly. - Bare
WebFetchproduces a warning and is only justified for genuinely open-ended skills (theresearchskill is the canonical exception). Reviewers push back on new bare-WebFetchintroductions. - CLAUDE.md rule 3 documents the principle.
Status: ⚠️ Partial. Domain enumeration prevents wildcards. It does not prevent a skill author from listing an attacker-controlled domain as one of the allowed targets — code review is the check there.
Residual risk. A skill author who lists a malicious domain that looks innocuous on review (docs-helper.example.org vs. the real docs.example.org). Audited via PR review of the allowed-tools block.
Threats this page does not model
Section titled “Threats this page does not model”Out of scope for this catalog, with the reason for each:
- Cowork-specific concerns (computer-use scope creep, computer-use audit gap). Cowork is a separate Anthropic product surface; its controls are deployment-time and live in RBA IT/Ops material, not in this catalog. Anthropic’s Compliance API and Audit Logs cover Claude Code but, as of this writing, do not cover Cowork — the mitigation is an enterprise-deployment matter.
- Endpoint compromise unrelated to Claude. If the user’s workstation is already compromised, every catalog-side control is bypassed at runtime.
- Anthropic-side infrastructure attacks. Out of scope for any single-tenant artifact; report directly to Anthropic.
- Insider threat at Anthropic. Same.
- Adversarial RBA employees with maintainer access. CODEOWNERS, branch protection, and PR review limit but do not eliminate this risk. A long-running insider threat is outside the catalog’s controls.
- npm supply-chain compromise of the catalog’s own dependencies. Dependabot reduces the window between a vuln being disclosed and an update being merged, but does not prevent a malicious package being introduced. Mitigation is review-by-default of dependency-update PRs.
How this page is maintained
Section titled “How this page is maintained”Threats are added when a new artifact type or a new platform integration introduces a class of risk we haven’t modeled. The validator’s lint rules and the standards pages are kept consistent with the controls described here — if a control moves from ⚠️ partial to ✅ implemented (or vice versa), this page reflects it on the next review.
Vulnerability reporting: SECURITY.md.