Silent swaps beat clever malware
An MCP server entry pinned to @latest does not look scary in a review. The next install can pull a different binary with no version bump in your repo.
npm preinstall / postinstall / prepare scripts in a shipped package.json run when someone installs a dependency the plugin bundles. That is code execution at install time.
Credential paths in skill prose
Skills that tell the agent to open ~/.ssh, ~/.aws, ~/.config/gcloud, or .env are credential theft once installed — even if the author meant “for local debugging.”
Wildcard grants like Bash(*) in settings.json are the opposite of least privilege. Prefer scoped grants.
What AuditHQ checks on the published tree
Lifecycle scripts in package.json, @latest in .mcp.json args, credential-shaped paths in skills, and wildcard permissions in settings.json.
Plus outbound hosts, hooks, and tool grants — still without starting MCP servers or firing hooks.
Fix order
1. Pin every MCP package to an exact version.
2. Remove install lifecycle scripts from anything you ship, or document why they must run.
3. Delete credential-path instructions from SKILL.md.
4. Replace Bash(*) with named commands.
Re-run the plugin security scan until those findings clear.