CVE-2026-59176
Functype: MCP set_functype_version Package Alias RCE via Unsanitized pnpm install + Dynamic Import
Functype is a family of TypeScript functional programming libraries. Prior to 1.4.4, the set_functype_version MCP tool in functype-mcp-server accepts an unconstrained version string using only z.string() validation in packages/mcp-server/src/index.ts and interpolates it into functype@<version> for pnpm add. Package-alias syntaxes such as file:, npm:, URLs, or paths can cause an arbitrary local or remote package to be installed as functype. Immediately afterward, initDocsData(true) in packages/mcp-server/src/lib/docs/data.ts resolves functype/cli and dynamically imports the newly installed module, executing attacker-controlled JavaScript with the MCP server process's privileges. Any MCP client able to send a tools/call request invoking the tool can exploit the flaw; the tool is enabled by default without authentication in stdio mode. A connected AI assistant susceptible to indirect prompt injection can also be induced to invoke it from a malicious document or web page. In non-default TRANSPORT_TYPE=httpStream deployments, a network-accessible attacker does not require local access. Successful execution can read process secrets, modify files, or terminate the server. This issue is fixed in version 1.4.4.
Attack profile
How easy it is to exploit
- Attack vector
- Local
- Complexity
- Low
- Privileges needed
- None
- User interaction
- Required
What an attacker can affect
- Confidentiality
- High
- Integrity
- High
- Availability
- High
Exploit likelihood
What each source reports
CVE List Score used 7.8
Functype: MCP set_functype_version Package Alias RCE via Unsanitized pnpm install + Dynamic Import
Functype is a family of TypeScript functional programming libraries. Prior to 1.4.4, the set_functype_version MCP tool in functype-mcp-server accepts an unconstrained version string using only z.string() validation in packages/mcp-server/src/index.ts and interpolates it into functype@<version> for pnpm add. Package-alias syntaxes such as file:, npm:, URLs, or paths can cause an arbitrary local or remote package to be installed as functype. Immediately afterward, initDocsData(true) in packages/mcp-server/src/lib/docs/data.ts resolves functype/cli and dynamically imports the newly installed module, executing attacker-controlled JavaScript with the MCP server process's privileges. Any MCP client able to send a tools/call request invoking the tool can exploit the flaw; the tool is enabled by default without authentication in stdio mode. A connected AI assistant susceptible to indirect prompt injection can also be induced to invoke it from a malicious document or web page. In non-default TRANSPORT_TYPE=httpStream deployments, a network-accessible attacker does not require local access. Successful execution can read process secrets, modify files, or terminate the server. This issue is fixed in version 1.4.4.
- Record
CVE-2026-59176- CVSS 3.1
- 7.8 High
CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H - Weakness
- CWE-829
- Updated
- 2026-11-03
EUVDEUVD-2026-112078 7.8
Functype is a family of TypeScript functional programming libraries. Prior to 1.4.4, the set_functype_version MCP tool in functype-mcp-server accepts an unconstrained version string using only z.string() validation in packages/mcp-server/src/index.ts and interpolates it into functype@<version> for pnpm add. Package-alias syntaxes such as file:, npm:, URLs, or paths can cause an arbitrary local or remote package to be installed as functype. Immediately afterward, initDocsData(true) in packages/mcp-server/src/lib/docs/data.ts resolves functype/cli and dynamically imports the newly installed module, executing attacker-controlled JavaScript with the MCP server process's privileges. Any MCP client able to send a tools/call request invoking the tool can exploit the flaw; the tool is enabled by default without authentication in stdio mode. A connected AI assistant susceptible to indirect prompt injection can also be induced to invoke it from a malicious document or web page. In non-default TRANSPORT_TYPE=httpStream deployments, a network-accessible attacker does not require local access. Successful execution can read process secrets, modify files, or terminate the server. This issue is fixed in version 1.4.4.
- Record
EUVD-2026-112078- CVSS 3.1
- 7.8 High
CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H - Updated
- 2026-11-03
GitHub AdvisoriesGHSA-wcjj-9m6g-2fr2 7.8
functype-mcp-server: MCP `set_functype_version` Package Alias RCE via Unsanitized pnpm install + Dynamic Import
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@<version>), 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):
// 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:
// 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:
// 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:
index.ts:115— MCP toolset_functype_versionregistered, no auth required.index.ts:119-121—versionaccepted as rawz.string()(source).index.ts:123—functype@${args.version}constructed without sanitization.index.ts:125—execFileSync("pnpm", ["add", spec], ...)installs attacker-controlled package (sink: arbitrary install).index.ts:134—initDocsData(true)called immediately.data.ts:29-30—require.resolve("functype/cli")+ dynamicimport()executes attacker module (sink: RCE).
PoC
Step 1 — Prepare the attacker-controlled evil package:
mkdir -p /tmp/evil
cat > /tmp/evil/package.json <<'EOF'
{"name":"evil-functype","version":"1.0.0","type":"module","exports":{"./cli":"./cli.js"}}
EOF
cat > /tmp/evil/cli.js <<'EOF'
import { writeFileSync } from "node:fs";
writeFileSync("/pwned.txt", "RCE: mcp import-time code execution via set_functype_version\n");
export const TYPES = {};
export const INTERFACES = {};
export const CATEGORIES = {};
export const FULL_INTERFACES = {};
export const VERSION = "1.0.0";
EOF
Step 2 — Clone and build the victim monorepo at the affected version:
TMP="$(mktemp -d)"
git clone https://github.com/jordanburke/functype.git "$TMP/functype"
cd "$TMP/functype"
git checkout v1.4.3
corepack enable
pnpm install…
- Record
GHSA-wcjj-9m6g-2fr2- CVSS 3.1
- 7.8 High
CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H - Weakness
- CWE-829
- Updated
- 2026-11-02
NVD 7.8
Functype is a family of TypeScript functional programming libraries. Prior to 1.4.4, the set_functype_version MCP tool in functype-mcp-server accepts an unconstrained version string using only z.string() validation in packages/mcp-server/src/index.ts and interpolates it into functype@<version> for pnpm add. Package-alias syntaxes such as file:, npm:, URLs, or paths can cause an arbitrary local or remote package to be installed as functype. Immediately afterward, initDocsData(true) in packages/mcp-server/src/lib/docs/data.ts resolves functype/cli and dynamically imports the newly installed module, executing attacker-controlled JavaScript with the MCP server process's privileges. Any MCP client able to send a tools/call request invoking the tool can exploit the flaw; the tool is enabled by default without authentication in stdio mode. A connected AI assistant susceptible to indirect prompt injection can also be induced to invoke it from a malicious document or web page. In non-default TRANSPORT_TYPE=httpStream deployments, a network-accessible attacker does not require local access. Successful execution can read process secrets, modify files, or terminate the server. This issue is fixed in version 1.4.4.
- Record
CVE-2026-59176- CVSS 3.1
- 7.8 High
CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H - Weakness
- CWE-829
- Updated
- 2026-11-03
OSV 7.8
Functype: MCP set_functype_version Package Alias RCE via Unsanitized pnpm install + Dynamic Import
Functype is a family of TypeScript functional programming libraries. Prior to 1.4.4, the set_functype_version MCP tool in functype-mcp-server accepts an unconstrained version string using only z.string() validation in packages/mcp-server/src/index.ts and interpolates it into functype@<version> for pnpm add. Package-alias syntaxes such as file:, npm:, URLs, or paths can cause an arbitrary local or remote package to be installed as functype. Immediately afterward, initDocsData(true) in packages/mcp-server/src/lib/docs/data.ts resolves functype/cli and dynamically imports the newly installed module, executing attacker-controlled JavaScript with the MCP server process's privileges. Any MCP client able to send a tools/call request invoking the tool can exploit the flaw; the tool is enabled by default without authentication in stdio mode. A connected AI assistant susceptible to indirect prompt injection can also be induced to invoke it from a malicious document or web page. In non-default TRANSPORT_TYPE=httpStream deployments, a network-accessible attacker does not require local access. Successful execution can read process secrets, modify files, or terminate the server. This issue is fixed in version 1.4.4.
- Record
CVE-2026-59176- CVSS 3.1
- 7.8 High
CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H - Weakness
- CWE-829
- Updated
- 2026-11-07
OSVGHSA-wcjj-9m6g-2fr2 7.8
functype-mcp-server: MCP `set_functype_version` Package Alias RCE via Unsanitized pnpm install + Dynamic Import
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@<version>), 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):
// 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:
// 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:
// 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:
index.ts:115— MCP toolset_functype_versionregistered, no auth required.index.ts:119-121—versionaccepted as rawz.string()(source).index.ts:123—functype@${args.version}constructed without sanitization.index.ts:125—execFileSync("pnpm", ["add", spec], ...)installs attacker-controlled package (sink: arbitrary install).index.ts:134—initDocsData(true)called immediately.data.ts:29-30—require.resolve("functype/cli")+ dynamicimport()executes attacker module (sink: RCE).
PoC
Step 1 — Prepare the attacker-controlled evil package:
mkdir -p /tmp/evil
cat > /tmp/evil/package.json <<'EOF'
{"name":"evil-functype","version":"1.0.0","type":"module","exports":{"./cli":"./cli.js"}}
EOF
cat > /tmp/evil/cli.js <<'EOF'
import { writeFileSync } from "node:fs";
writeFileSync("/pwned.txt", "RCE: mcp import-time code execution via set_functype_version\n");
export const TYPES = {};
export const INTERFACES = {};
export const CATEGORIES = {};
export const FULL_INTERFACES = {};
export const VERSION = "1.0.0";
EOF
Step 2 — Clone and build the victim monorepo at the affected version:
TMP="$(mktemp -d)"
git clone https://github.com/jordanburke/functype.git "$TMP/functype"
cd "$TMP/functype"
git checkout v1.4.3
corepack enable
pnpm install…
- Record
GHSA-wcjj-9m6g-2fr2- CVSS 3.1
- 7.8 High
CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H - Weakness
- CWE-829
- Updated
- 2026-11-02
Affected products
Affected packages
| Package | Affected | Fixed |
|---|---|---|
functype-mcp-servernpm | through 1.4.3 | 1.4.4 |
functype-mcp-servernpm | before 1.4.4 | 1.4.4 |
History
| Recorded | Changed | Sources |
|---|---|---|
| facts | EUVD, NVD | |
| references | CVE List | |
| first indexed | CVE List, EUVD, GitHub Advisories, NVD, OSV |
Dates are when Every CVE recorded each change. Upstream dates may differ.
In short
CVE-2026-59176 is a high vulnerability (CVSS 7.8) in Jordanburke Functype, published September 9, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.21%, the 11th percentile. Fixed in functype-mcp-server 1.4.4.
References
github.com/jordanburke/functype/security/advisories/GHSA-wcjj-9m6g-2fr2
github.com/jordanburke/functype/commit/c0d58ad9c2a7d15c6117bd3adbbd75de37317dcf
github.com/jordanburke/functype/releases/tag/v1.4.4
nvd.nist.gov/vuln/detail/CVE-2026-59176
github.com/advisories/GHSA-wcjj-9m6g-2fr2
github.com/CVEProject/cvelistV5/tree/main/cves/2026/59xxx/CVE-2026-59176.json
github.com/jordanburke/functype
Left out here: the rest of 2 source descriptions. The JSON record has them.