T08 · Insecure Dependencies
- Location
python/agent-sdk/patterns.md:162- Finding
Unpinned MCP Packages Are Downloaded and Executed Through npx
- Content
View full analysis
Vulnerability Details
File Locations:
python/agent-sdk/README.md:132python/agent-sdk/patterns.md:139python/agent-sdk/patterns.md:162-164typescript/agent-sdk/README.md:78typescript/agent-sdk/patterns.md:93
Vulnerability Type: Runtime execution of mutable, unpinned third-party dependencies
Risk Level: MediumVulnerable Code
python/agent-sdk/README.md:132:python "playwright": {"command": "npx", "args": ["@playwright/mcp@latest"]}python/agent-sdk/patterns.md:139:python "playwright": {"command": "npx", "args": ["@playwright/mcp@latest"]}python/agent-sdk/patterns.md:162-164:python "command": "npx", "args": ["-y", "@modelcontextprotocol/server-postgres"], "env": {"DATABASE_URL": os.environ["DATABASE_URL"]}typescript/agent-sdk/README.md:78:typescript playwright: { command: "npx", args: ["@playwright/mcp@latest"] },typescript/agent-sdk/patterns.md:93:typescript playwright: { command: "npx", args: ["@playwright/mcp@latest"] },Technical Analysis
The examples instruct users to start MCP servers through
npx. If the requested package is not already installed,npxretrieves it from the package registry and executes it locally.The Playwright examples explicitly use the mutable
@latesttag. The PostgreSQL example omits a version entirely and uses-y, suppressing interactive confirmation. Consequently, the code executed when a user follows these examples is not fixed to the package contents reviewed with this Skill.This creates a supply-chain trust boundary: a compromised registry account, malicious package release, or compromised upstream maintainer could replace the effective runtime payload without requiring any modification to the Skill. The PostgreSQL MCP process is particularly sensitive because it is explicitly given
DATABASE_URL, which may contain a database hostname, usernam ...[truncated 2250 chars]- Remediation
View remediation
Remediation Suggestions
-
Replace mutable and unversioned dependencies with exact, reviewed versions:
python "playwright": { "command": "npx", "args": ["--no-install", "@playwright/mcp@X.Y.Z"] }python "postgres": { "command": "npx", "args": ["--no-install", "@modelcontextprotocol/server-postgres@X.Y.Z"], "env": {"DATABASE_URL": os.environ["DATABASE_URL"]} } -
Install MCP packages as project dependencies before execution and commit the applicable lockfile. Use locked, integrity-verified installation commands such as
npm ci. -
Prefer invoking a package from the project's verified local dependency tree rather than allowing
npxto download missing code at runtime. -
Remove
@latest, add exact versions to all examples, and avoidnpx -ywhere confirmation provides a meaningful security boundary. -
Document that MCP servers are locally executed third-party programs rather than passive API definitions.
-
Run MCP servers in a restricted environment with:
- A dedicated operating-system account or container.
- Access only to the necessary working directory.
- Restricted outbound network access.
- A minimal environment-variable allowlist.
- Resource and execution-time limits.
-
For PostgreSQL integration, use a dedicated database account limited to the required database, schema, tables, and operations. Prefer read-only credentials for analytical queries and rotate the credential if package compromise is suspected.
-
Review package provenance, release signatures, maintainers, and published integrity metadata before updating pinned versions. Test updates in an isolated environment before deployment.
-
