Skip to content

feat(rules): flag unpinned MCP package launches (MCPCFG-003) - #274

Merged
ivanpaghubasan merged 3 commits into
mainfrom
feat/mcpcfg-003-unpinned-mcp-launch
Oct 26, 2026
Merged

ivanpaghubasan merged 3 commits into
mainfrom
feat/mcpcfg-003-unpinned-mcp-launch

Conversation

@ivanpaghubasan

Copy link
Copy Markdown
Collaborator

Summary

Adds MCPCFG-003: a committed MCP client config starts a server with a package
runner (npx, bunx, pnpm dlx, uvx, uv tool run, pipx run, docker run) on a package
or image that is not pinned to an exact version or digest.

  • New predicate repo_mcp_config_launches_unpinned_package, backed by
    ProjectConfigFacts.UnpinnedMCPLaunch and classifyMCPPin.
  • Reuses the server entries MCPCFG-002 already parses (.mcp.json, .cursor/mcp.json,
    .vscode/mcp.json, claude_desktop_config.json, .gemini/settings.json, Codex config.toml).
  • Disjoint from MCPCFG-002: a command inside the repo is left to MCPCFG-002.
  • Second commit: MCPCFG-002 explanation text now points to MCPCFG-003 for
    unpinned packages (text only; id, severity and match unchanged).

Schema version

28 is provisional. CSDK-115 (#273) holds 27. Whichever PR merges later merges
main in and renumbers schema_version.go, the fixture manifest and the rules
manifest, then reruns go test ./... and scripts/check-rules-sync.sh.

Merge order

Engine, then rules, then rulebook. The rules PR must not merge before the
rationale-doc PR is ready.

Tests

  • go build, go vet, go test ./... pass.
  • RULES_REPO=../trustabl-rules scripts/check-rules-sync.sh: fixture in sync.
  • Corpus scan before and after on all 24 corpus dirs: the 193 existing findings
    are unchanged; the only new finding is MCPCFG-003 on the new fixture.
  • Unit, policy and scanner tests, including a disjointness test against MCPCFG-002.

Maintainer notes

  • Not judged: git, URL, local-path and $VAR specs; runners started through a
    shell; a flag before the subcommand; remote URL servers.
  • A value flag that is not in the flag lists is read as boolean, so its value can
    be taken as the package spec (possible false positive). Not stated in the rule text.
  • Unverified: pipx value flags other than --spec, positional pkg==x for uvx
    (credited as pinned, so the failure direction is silent), pnpm dlx behaviour
    with no version, -c semantics for bunx and pnpm.
  • --exclude-newer is not credited as a pin.
  • Existing behaviour: isRepoRelativePath treats .cmd as a script extension, so a
    bare npx.cmd command is claimed by MCPCFG-002.
  • Evidence named by the source report, not verified and not used in the rule or
    docs: "0 of 8 concealment techniques force re-approval under rug pull
    (2607.05744)" and the postmark-mcp BCC backdoor in 1.0.16.
  • The rulebook doc for MCPCFG-002 has CVE claims and frequency words. Left alone here.

…ned-mcp-launch

# Conflicts:
#	CHANGELOG.md
#	CLAUDE.md
#	COVERAGE.md
#	internal/rules/schema_version.go
#	testdata/corpus/PROVENANCE.md
#	testdata/rules-fixture/manifest.yaml
@ivanpaghubasan
ivanpaghubasan merged commit 96a781a into main Oct 26, 2026
6 of 7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants