Rules / Hidden content and security
sec-mcp-launcher
MCP server runs an unpinned package or image, a downloaded script, or connects over plain http.
Source: Invariant Labs: MCP tool poisoning attacks (invariantlabs.ai), read 14 October 2026.
On GitHub: the rule doc and the tests.
All rules73
What it catches#
MCP server runs an unpinned package or image, a downloaded script, or connects over plain http.
An MCP server in .mcp.json, .cursor/mcp.json, .vscode/mcp.json or .gemini/settings.json started from an unpinned package (npx -y foo, npx foo@latest, uvx foo, pipx run foo), a container image with no tag or :latest, or a git source with no commit or tag. Also a server reached over plain http to a non-local host. Errors for a shell wrapper (sh -c "...") whose command downloads and runs code or decodes base64 and runs it, and for mcp-remote pinned below 0.1.16 (CVE-2025-6514). A package that matches one of the repository's own workspace folders, or the repository itself (its folder name, or the name in the root package.json or pyproject.toml), is skipped: running your own published server at its latest release is the point of that config. Needs --include config.
Why it matters#
npx, uvx or docker without an exact version or digest runs whatever was published last, after you approved an earlier one (the postmark-mcp backdoor shipped in version 1.0.16). mcp-remote before 0.1.16 has a command injection bug (CVE-2025-6514).
Bad example#
{
"mcpServers": {
"db": { "command": "npx", "args": ["-y", "@example/db-server"] }
}
}
npx -y fetches whatever version was published last and runs it on every start. A compromised or typosquatted publish runs on every developer's machine the next morning.
Good example#
{
"mcpServers": {
"db": { "command": "npx", "args": ["-y", "@example/db-server@1.4.2"] }
}
}
Better still, install the package in the repository (devDependencies, lockfile) and run it with node node_modules/@example/db-server/dist/cli.js.
How to fix#
Pin an exact version (package@1.2.3, package==1.2.3), an image digest or version tag, or a commit at the end of a git URL. Or vendor the server and start it from a path in the repository. Use https for remote servers. Replace a shell wrapper that downloads code with a direct command and arguments.
Suppress or configure#
sec-mcp-launcher is a security rule, so it cannot be suppressed with a comment in the file: a suppression comment is itself a hidden comment, and an attacker who can add a payload can add one next to it. A comment that tries gets a suppression-not-allowed warning.
Turn it off, or change its severity, in .asitisrc.json, which shows up in review:
{ "rules": { "sec-mcp-launcher": "off" } }
Or accept the findings you have today in a baseline, so only new ones fail the build:
asitis lint --format json --write-baseline > .asitis-baseline.json
asitis lint --baseline .asitis-baseline.json
Source#
Invariant Labs: MCP tool poisoning attacks, read on 14 October 2026.
Related guides
Run the rule
- In your browser, on one file
- In Claude Code, on the project
- In CI, on every pull request
This page is generated from the plugin's rule registry. Edit it on GitHub. False positive? Open an issue with the line it fired on.