AG-SC-001/002/003 · supply-chain
Detects launch patterns where “what runs today” is decided by the package registry, not by you.
What it checks
Section titled “What it checks”Config (static), for servers launched via package runners (npx, pnpx, pnpm dlx, bunx, uvx, pipx):
- Unpinned package spec (
medium) —pkg,pkg@latest, or any non-exact version: every launch fetches whatever is latest (rug-pull / compromised-release exposure). Exact versions (pkg@1.2.3) and commit-pinned git specs pass. - Auto-confirm installs (
low) —-y/--yescombined with an unpinned spec installs new upstream code silently. - Unpinned docker images (
medium) —docker run image:latestor tagless images without a@sha256:digest. - Unpinned OpenCode plugins (
medium) — npm packages in thepluginarray ofopencode.jsonare auto-installed by Bun and executed at startup; specs without an exact version fetch whatever is latest. Git-URL plugin specs (pkg@git+https://…) without a commit pin (#<sha>) reportmediumtoo. Local plugin files (.opencode/plugins/,./…paths) are loaded from the repo and not flagged here. - Claude Code plugins from mutable marketplaces (
medium) —.claude/settings.jsoncan pre-enable plugins (enabledPlugins) from marketplaces declared inextraKnownMarketplaces; anyone who trusts the folder is prompted to install them, and plugins ship hooks, MCP servers, and skills. A git-based marketplace source without ashaor release-stylereffetches whatever the branch points at on every sync. Localdirectory/filesources and plugins that aren’t auto-enabled are not flagged. Copilot CLI repository settings (.github/copilot/settings.jsonandsettings.local.json, plus user-level~/.copilot/settings.json) support the sameextraKnownMarketplaces+enabledPluginskeys — a repository-level entry auto-installs the plugin for everyone who works in the repository — and get the same check. - Mutable plugin sources in marketplace catalogs (
medium) — a repo that hosts a marketplace (.claude-plugin/marketplace.jsonfor Claude Code,.github/plugin/marketplace.jsonfor Copilot CLI — same schema and source types per the official plugin reference) distributes each listed plugin from itssource; a git-based source (github,url,git-subdir) with noshaand no release-stylerefserves everyone who installs the plugin whatever the branch points at; annpmsource with no exactversion(absent or a range like^2.0.0) installs whatever the registry serves next; anarchive(zip) source with nosha256digest downloads unverified content on every install. npm-distributed plugins are also cross-checked against OSV.dev known-malware advisories and the AgentGate MCP advisory database (AG-SC-002/AG-SC-003), the same pipeline as runner-launched server packages. Relative-path sources (plugin code lives inside the marketplace repo itself) are not flagged. Marketplace entries can also define a plugin entirely inline (strict: false): entry-levelmcpServersare discovered and checked like any other MCP config (including advisory cross-checks), and entry-levelhookscommands go through the dangerous-command classification described under RCE vectors. - Known-malicious server package (
AG-SC-002) — the launched package — and every npm plugin an OpenCode config auto-installs — is checked against OSV.dev known-malware advisories (MAL-*). A package that is malware in every version iscritical; an advisory scoped to specific compromised releases is compared against the pinned version in the spec (unaffected =low, affected =critical, unpinned =high). Skipped with a warning when OSV.dev is unreachable. - MCP advisory database match (
AG-SC-003) — the launched package is also checked against the AgentGate MCP advisory database (MCPA-*), which covers vulnerabilities beyond malware (RCE, SSRF, path traversal, auth bypass in MCP servers). The database is bundled with the CLI, so this check works fully offline; when the network is available, the bundled copy is refreshed from the live advisory API so advisories published after your CLI release are still matched. A pinned version inside an advisory’s affected range carries the advisory’s severity; a version outside every range is not reported; an unpinned spec with a version-scoped advisory ismedium(“pin a fixed version”).
Why it matters
Section titled “Why it matters”The postmark-mcp backdoor (MCPA-2025-0002) shipped in a routine version bump; every npx postmark-mcp user got it automatically. Pinning turns “whatever upstream published last night” into an explicit, reviewable upgrade.
Fixing findings
Section titled “Fixing findings”- Pin exact versions:
npx -y postmark-mcp@1.0.15→ check the advisory database for known-bad versions first. - Pin docker images by digest:
image@sha256:…. - Pair version pinning with
agentgate lock: the version pin freezes the code you install, the lockfile freezes the tool surface you approve.