[SECURITY] Marketplace auto-sync silently installs new plugins without user consent — supply chain risk

Resolved 💬 4 comments Opened Mar 22, 2026 by greogory Closed Apr 19, 2026

Summary

Claude Code's official marketplace (claude-plugins-official) auto-syncs on every startup, and new plugins added upstream by Anthropic are silently loaded into the user's environment without any notification, consent prompt, or opt-in mechanism. This creates a supply chain attack surface that bypasses the user's ability to audit what runs in their environment.

The Concrete Problem

On 2026-03-20, Anthropic merged PR #755 into claude-plugins-official, adding the math-olympiad plugin. On my next Claude Code startup, the marketplace repo was auto-synced, and math-olympiad appeared as an installed, active plugin — without any notification, consent dialog, or changelog.

I discovered this only by manually auditing my plugin directory days later. I had not installed it, had no use for it, and was unaware it existed until I happened to run a full inventory.

Why This Matters

Plugins in Claude Code are not inert metadata. They include:

  • Skills and commands that shape Claude's behavior and decision-making
  • Hooks (PreToolUse, PostToolUse, Stop, UserPromptSubmit) that execute code in response to tool calls and user input
  • Agents that run autonomously with access to the user's filesystem, shell, and network

A plugin with a malicious or compromised hook could silently exfiltrate data, modify files, or alter Claude's behavior in ways that are invisible to the user. The current auto-sync model means that a single compromised commit to claude-plugins-official would propagate to every Claude Code installation on next startup, with no user-visible indication that anything changed.

This is not a hypothetical concern about Anthropic's internal review processes. It's a structural observation: the architecture has no consent gate between "code is merged upstream" and "code runs in the user's environment." Even organizations with excellent review practices benefit from defense in depth — and the user's explicit consent is one of those layers.

Current Behavior

  1. On startup, Claude Code clones/pulls anthropics/claude-plugins-official
  2. All plugins in the repo's plugins/ directory are loaded automatically
  3. enabledPlugins in settings only controls external plugins, not marketplace-bundled ones (per #29734)
  4. known_marketplaces.json is overwritten on startup
  5. groveConfigCache is reset on startup
  6. There is no notification that new plugins have been added since last launch
  7. There is no documented way to prevent this behavior (the env var CLAUDE_CODE_DISABLE_OFFICIAL_MARKETPLACE_AUTOINSTALL exists but is undocumented)

Proposed Behavior

At minimum:

  1. Notification on new plugins: When a marketplace sync introduces plugins that weren't present in the previous sync, display a clear notification listing what was added
  2. Opt-in activation: New plugins from marketplace syncs should be downloaded but not loaded until the user explicitly enables them
  3. Document the opt-out: If CLAUDE_CODE_DISABLE_OFFICIAL_MARKETPLACE_AUTOINSTALL is the intended escape hatch, document it prominently

Ideally:

  1. Plugin manifest pinning: Allow users to pin their marketplace to a specific commit SHA, updating only when they choose to
  2. Diff visibility: Show what changed in the marketplace repo since the user's last sync, similar to how package managers show changelogs on update

Related Issues

  • #29734 — No way to opt out of bundled marketplace plugins
  • #9537 — Plugin marketplace removal doesn't clean up settings.json, causing reinstall
  • #10265 — Feature request for controlling automatic marketplace updates

Those issues frame this as a user-control concern. This issue frames the same behavior as a security architecture gap: the absence of a consent gate in the plugin delivery pipeline.

Environment

  • Claude Code 2.1.81
  • Linux (CachyOS)
  • claude-plugins-official synced automatically on startup

View original on GitHub ↗

This issue has 4 comments on GitHub. Read the full discussion on GitHub ↗