cfgaudit

Rules / CFG128

CFG128 an MCP launcher references a confirmed malicious package artifact

Severity: error OWASP: LLM04:2026 – Supply Chain OWASP Agentic: ASI04:2026 – Agentic Supply Chain Vulnerabilities Agents: claude-code, cline, codex, continue, copilot, cursor, devin, devin-desktop, gemini-cli, goose, grok, junie, kimi-code, opencode, qwen-code, roo-code, vscode, zed

What cfgaudit checks

CFG128 compares exact npm package/version pairs launched by MCP server entries with a small reviewed, offline malicious-artifact IOC set. It shares the runner extraction used by CFG010, CFG059 and CFG126: npx, npm exec, pnpm dlx, yarn dlx, bunx, pnpx, package flags, Windows .cmd forms and cmd /c npx are covered.

This rule is deliberately separate from CFG126. A vulnerable package may have a fixed release; an artifact confirmed as malware remains evidence even after the registry unpublishes it, because it may remain in a package-manager cache or an image. The finding says that an IOC match requires incident-response review, not that cfgaudit proved execution or compromise.

Only exact pairs match. A different version, a tag/range, a substring, a lookalike, a security-holder package and the four SANDWORM_MODE packages Socket labelled sleeper packages (not malicious yet) do not. The scan makes no network request. It never repeats unrelated runner arguments, so a server URL carrying userinfo or query credentials cannot leak through the IOC finding.

Reviewed data and lifecycle

The versioned source is internal/maliciousioc/npm.json. Schema version 1 was last reviewed 2026-11-06, is owned by the cfgaudit maintainers, and is due for review by 2027-02-04. It contains 20 exact npm package-version indicators:

Every entry carries its source URL, campaign, reason/type, first and last review dates, and removal policy. An entry remains until its cited source retracts or corrects the identification; unpublishing alone is not removal, because cached copies remain the same artifact. A scheduled or release review updates last_reviewed and review_after, removes corrected entries, and adds only exact artifacts supported by a primary publisher statement or vendor threat research.

The deterministic update check is:

go run ./cmd/ioccheck -file internal/maliciousioc/npm.json
go test ./internal/maliciousioc ./rules ./cmd/cfgaudit

ioccheck rejects malformed metadata, unsorted/lowercase package identities, non-exact or duplicate package-version pairs, non-HTTPS sources and invalid review dates. It exits nonzero after review_after; the weekly Check advisories workflow runs it and opens an issue when that happens. Tests lock exact matching and the published seed count. Updating the JSON never adds a network dependency to a scan.

Trigger example

{
  "mcpServers": {
    "mail": {
      "command": "npx",
      "args": ["-y", "postmark-mcp@1.0.16"]
    }
  }
}

Remediation

Treat the exact match as an incident-response lead:

  1. Remove the MCP entry, installed artifact and cached copy; do not run it to test the finding.
  2. Determine whether the package executed on developer machines or CI, and inspect campaign-specific persistence. For SANDWORM_MODE, review global Git hook templates, repository hooks, workflows and unexpected MCP entries.
  3. Rotate credentials the artifact could have reached, including npm/GitHub/CI and service credentials; for postmark-mcp@1.0.16, review email logs and rotate credentials that may have appeared in sent email.
  4. Restore a legitimate integration only from its publisher's documented package and review its identity independently.

References

Documentation for cfgaudit 1.21.0. Source of this page · Rule implementation