GitHub Advisoryadvisory · npm
GHSA-wcjj-9m6g-2fr2 functype-mcp-server: MCP `set_functype_version` Package Alias RCE via Unsanitized pnpm install + Dynamic Import
HIGH
Official page ↗
- Aliases
- CVE-2026-59176
- Ecosystem
- npm
- Packages
- functype-mcp-server
- Severity
- High
- CVSS vector
- CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H
- Weaknesses
- CWE-829
- Reviewed
- 2026-09-09
Affected packages
• npm functype-mcp-server: < 1.4.4 → fixed in 1.4.4
Description
MCP `set_functype_version` Package Alias RCE via Unsanitized pnpm install + Dynamic Import
Summary
The `set_functype_version` MCP tool in `functype-mcp-server` accepts an unconstrained `version` string, interpolates it directly into an npm package specifier (`functype@`), and installs it via `pnpm add` without any validation. Because npm/pnpm package specifiers support `file:`, `npm:`, and other alias syntaxes, an attacker who can send an MCP `tools/call` request to this tool can cause the server to install an arbitrary local or remote package as `functype`. Immediately after installation, the server calls `initDocsData(true)`, which dynamically imports `functype/cli` from the newly installed location, executing attacker-controlled JavaScript in the MCP server process. This results in full Remote Code Execution (RCE) with the privileges of the server process — full confidentiality, integrity, and availability impact (CVSS 7.8 High).
Details
The vulnerable code is in `packages/mcp-server/src/index.ts`. The `set_functype_version` tool is registered at line 115 and is enabled by default (no authentication required in stdio mode).
Source (user input accepted without validation):
```ts
// packages/mcp-server/src/index.ts:119-121
parameters: z.object({
version: z.string().describe('The functype version to install (e.g., "0.46.0", "latest", "^0.45.0")'),
}),
```
Only `z.string()` validation is applied — no semver format check, no allowlist for dist-tags, and no rejection of `file:`, `npm:`, URL, or path alias syntaxes.
Sink 1 — arbitrary package installation:
```ts
// packages/mcp-server/src/index.ts:122-125
execute: async (args) => {
const spec = `functype@${args.version}`
try {
execFileSync("pnpm", ["add", spec], { cwd: PROJECT_ROOT, stdio: "pipe", timeout: 60_000 })
```
`args.version` is interpolated into the package specifier string and passed directly to `pnpm add`. Supplying `file:/path/to/evil` causes pnpm to install an attacker-controlled directory as the `functype` package alias.
Sink 2 — dynamic import executes installed package code:
```ts
// packages/mcp-server/src/lib/docs/data.ts:23-30
if (force) {
const resolvedPath = require.resolve("functype/cli")
cli = await import(`${pathToFileURL(resolvedPath).href}?t=${Date.now()}`)
}
```
`initDocsData(true)` is called immediately after installation (line 134 in `index.ts`). It resolves `functype/cli` from the node_modules that now points to the attacker's package and dynamically imports it, executing any module-level code in the attacker's `cli.js` at import time.
Data flow summary:
1. `index.ts:115` — MCP tool `set_functype_version` registered, no auth required.
2. `index.ts:119-121` — `version` accepted as raw `z.string()` (source).
3. `index.ts:123` — `functype@${args.version}` constructed without sanitization.
4. `index.ts:125` — `execFileSync("pnpm", ["add", spec], ...)` installs attacker-controlled package (sink: arbitrary install).
5. `index.ts:134` — `initDocsData(true)` called immediately.
6. `data.ts:29-30` — `require.resolve("functype/cli")` + dynamic `import()` executes attacker module (sink: RCE).
PoC
Step 1 — Prepare the attacker-controlled evil package:
```bash
mkdir -p /tmp/evil
cat > /tmp/evil/package.json /tmp/evil/cli.js exploit.mjs {
+ const trimmed = version.trim()
+ return trimmed === version && SAFE_FUNCTYPE_VERSION.test(trimmed) && !/[/:\\@]/.test(trimmed)
+}
execute: async (args) => {
• const spec = `functype@${args.version}`
+ if (!isSafeFunctypeVersion(args.version)) {
+ return "Invalid functype version. Use a semver version, range prefix (^ or ~), or a known dist-tag."
+ }
+ const spec = `functype@${args.version}`
try {
• execFileSync("pnpm", ["add", spec], { cwd: PROJECT_ROOT, stdio: "pipe", timeout: 60_000 })
+ execFileSync("pnpm", ["add", "--ignore-scripts", spec], { cwd: PROJECT_ROOT, stdio: "pipe", timeout: 60_000 })
```
Impact
This is a Remote Code Execution (RCE) vulnerability. Any MCP client that can invoke the `set_functype_version` tool — which requires no authentication and is enabled by default in the stdio MCP server — can execute arbitrary JavaScript in the MCP server process.
Who is impacted:
• Developers and teams running `functype-mcp-server` (version 1.4.3) in their local or CI environments as an AI coding assistant integration.
• Users whose AI assistant (LLM agent) is connected to this MCP server and is susceptible to indirect prompt injection: a malicious document or web page read by the AI could trigger a `set_functype_version` call with a `file:` or `npm:` alias payload.
• In non-default `TRANSPORT_TYPE=httpStream` deployments, network-accessible attackers can exploit this without local access.
The full impact at exploitation is confidentiality, integrity, and availability — an attacker can read secrets from the process environment, modify files, or crash the server.
Reproduction artifacts
`Dockerfile`
```dockerfile
Dockerfile for VULN-001: MCP set_functype_version Package Alias RCE
Build context: reports/npmAI_684_jordanburke__functype/
COPY repo/ -> /workspace/functype/ (victim monorepo)
COPY vuln-001/ -> supporting PoC files
Build: docker build -t vuln001-functype-rce -f vuln-001/Dockerfile .
Run: docker run --rm vuln001-functype-rce
Expected exit 0 with "[poc] EXPLOIT SUCCEEDED" in output.
FROM node:24-slim
Install pnpm matching the repo's packageManager field ([email protected]).
RUN npm install -g [email protected] --quiet
── Victim workspace ──────────────────────────────────────────────────────────
WORKDIR /worksp…
Related
Alias · CVE (1)
- CVE-2026-59176 Functype is a family of TypeScript functional programming libraries. vulnerability
Weakness · CWE (1)
- CWE-829 Inclusion of Functionality from Untrusted Control Sphere weakness
References
- https://github.com/jordanburke/functype/security/advisories/GHSA-wcjj-9m6g-2fr2 web
- https://nvd.nist.gov/vuln/detail/CVE-2026-59176 advisory
- https://github.com/jordanburke/functype/commit/c0d58ad9c2a7d15c6117bd3adbbd75de37317dcf web
- https://github.com/jordanburke/functype package
- https://github.com/jordanburke/functype/releases/tag/v1.4.4 web