From 185d4468f359bb28108379a1caa2ed25119cddc4 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Wed, 7 Oct 2026 08:59:53 +0000 Subject: [PATCH] fix(security): pin MCP SDK 1.32.1 and proxy-addr 2.0.8 Weekly npm audit --omit=dev fails on main: @modelcontextprotocol/sdk 1.30.0 is inside GHSA-6qxp-vccf-f47h (<1.31.0), and express still resolves proxy-addr 2.0.7 (GHSA-jqcg-44mw-7w3h). Bump the direct SDK dependency and override proxy-addr to ^2.0.8 so the production audit is clean. Fixes #43 Fixes #48 --- CHANGELOG.md | 7 +++++++ package-lock.json | 22 +++++++++++++--------- package.json | 7 ++++--- packages/efficiency-agent/package.json | 2 +- tests/security-audit-script.test.ts | 15 +++++++++++++++ 5 files changed, 40 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a45e46c6..8794e0cd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,13 @@ All notable changes to this project are documented in this file. ## [Unreleased] +### Fixed — production `npm audit --omit=dev` (GHSA-6qxp-vccf-f47h, GHSA-jqcg-44mw-7w3h) + +- Direct `@modelcontextprotocol/sdk` (root and `packages/efficiency-agent`) moved from `^1.30.0` to `^1.32.1`. The advisory range was `<1.31.0` (OAuth client could send credentials to an authorization server chosen by the MCP server). +- `overrides.proxy-addr` is `^2.0.8`. express still declares `^2.0.7`, which resolved to the vulnerable `2.0.7` (IPv4-mapped IPv6 trust spoofing). + +## [Unreleased] + ### Fixed — 第 0 步性能与健壮性(迁移 Rust 前的架构债清偿,复审登记项全闭环) - **file 传输读路径共享缓存(P2-8)**:`GraphifyFileClient.peekStore()` 静态共享读入口(走进程内 `graphifyFileStoreCache`,stat 校验+delta 已应用,不开句柄不写);`graphStoreNeedsIndexing` 与 `readFileGraphStore`/`resolveGraphStoreAfterIndex` 不再各自 readFileSync+JSON.parse 整个 9.5MB store——每 preview 省 2 次全量读+解析。消费方 mutation 全审计(全只读),peek 结果仍做浅拷贝防御未来调用方。 diff --git a/package-lock.json b/package-lock.json index ed7705af..1ec73b22 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,7 +13,7 @@ "packages/*" ], "dependencies": { - "@modelcontextprotocol/sdk": "^1.30.0", + "@modelcontextprotocol/sdk": "^1.32.1", "ajv": "^8.17.1", "ajv-formats": "^3.0.1", "gpt-tokenizer": "^3.4.0", @@ -1438,9 +1438,9 @@ } }, "node_modules/@modelcontextprotocol/sdk": { - "version": "1.30.0", - "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.30.0.tgz", - "integrity": "sha512-xKd8OIzlqNzcqcNumGAa6g+PW2kjD5vrpcKOnfldAUPP3j7lnqMPwlTXQm8gF+UwH72z0lqaRbjr9hqGz0eITA==", + "version": "1.32.1", + "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.32.1.tgz", + "integrity": "sha512-2DdE+SJDtzLEEWzY1ZjY7Q+VcPhcV1KisD3zI4u0XZyktsjHum1mwbMI+JaulUBi2OZk+KJAi2uPXzxichPkdw==", "license": "MIT", "dependencies": { "@hono/node-server": "^1.19.9 || ^2.0.5", @@ -4425,7 +4425,7 @@ } }, "node_modules/ipaddr.js": { - "version": "1.9.4", + "version": "1.9.1", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", "license": "MIT", @@ -5585,9 +5585,9 @@ } }, "node_modules/proxy-addr": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", - "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.8.tgz", + "integrity": "sha512-5nnx0yGyVUcY6t9RnWcARWtwT9F1D8O9rt08htPvnd49W1IgZtmLkhu9WfMzQj1cFxjHIO6connUNVW5k7AVyQ==", "license": "MIT", "dependencies": { "forwarded": "0.2.0", @@ -5595,6 +5595,10 @@ }, "engines": { "node": ">= 0.10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/pump": { @@ -6992,7 +6996,7 @@ "name": "@roarpeng/graphflow-efficiency-agent", "version": "0.1.0", "dependencies": { - "@modelcontextprotocol/sdk": "^1.30.0" + "@modelcontextprotocol/sdk": "^1.32.1" }, "bin": { "eff-agent": "dist/bin/eff-agent.js" diff --git a/package.json b/package.json index 571d1885..f81e3d33 100644 --- a/package.json +++ b/package.json @@ -166,7 +166,7 @@ "vitest": "^3.2.6" }, "dependencies": { - "@modelcontextprotocol/sdk": "^1.30.0", + "@modelcontextprotocol/sdk": "^1.32.1", "ajv": "^8.17.1", "ajv-formats": "^3.0.1", "gpt-tokenizer": "^3.4.0", @@ -185,9 +185,10 @@ "body-parser": "^2.3.0", "fast-uri": "^3.1.7", "ip-address": "^10.7.2", - "qs": "^6.16.0" + "qs": "^6.16.0", + "proxy-addr": "^2.0.8" }, - "overridesComment": "Pinned past advisories in transitive deps. Six were non-breaking and lifted npm audit to zero: hono (cross-request data disclosure / ReDoS / SSRF-adjacent parser issues), @hono/node-server (Windows path traversal via encoded backslash), body-parser (DoS when an invalid limit silently disables size enforcement), fast-uri (host confusion and SSRF), ip-address (SSRF via octet and IPv6 misclassification), qs (array-limit bypass, DoS). The only remaining route was @huggingface/transformers 3.x -> 4.3.0, which pulls sharp 0.35.5 and clears the libvips/libheif CVEs; verified against the exact API surface used in src/learning/embeddings.ts (pipeline, env.cacheDir, env.remoteHost).", + "overridesComment": "Pinned past advisories in transitive deps. Six were non-breaking and lifted an earlier npm audit to zero: hono (cross-request data disclosure / ReDoS / SSRF-adjacent parser issues), @hono/node-server (Windows path traversal via encoded backslash), body-parser (DoS when an invalid limit silently disables size enforcement), fast-uri (host confusion and SSRF), ip-address (SSRF via octet and IPv6 misclassification), qs (array-limit bypass, DoS). @huggingface/transformers 4.3.0 pulls sharp 0.35.5 and clears the libvips/libheif CVEs; verified against the exact API surface used in src/learning/embeddings.ts (pipeline, env.cacheDir, env.remoteHost). proxy-addr ^2.0.8 clears GHSA-jqcg-44mw-7w3h (IPv4-mapped IPv6 trust spoofing) inside express, which still accepts ^2.0.7. @modelcontextprotocol/sdk is a direct dependency pinned to ^1.32.1 (advisory range was <1.31.0, GHSA-6qxp-vccf-f47h).", "disclosure": { "cloud": true, "network": [ diff --git a/packages/efficiency-agent/package.json b/packages/efficiency-agent/package.json index d9d69b3c..6bf234e5 100644 --- a/packages/efficiency-agent/package.json +++ b/packages/efficiency-agent/package.json @@ -25,7 +25,7 @@ "sbom": "node scripts/supply-chain.mjs" }, "dependencies": { - "@modelcontextprotocol/sdk": "^1.30.0" + "@modelcontextprotocol/sdk": "^1.32.1" }, "devDependencies": { "@types/node": "^25.9.1", diff --git a/tests/security-audit-script.test.ts b/tests/security-audit-script.test.ts index 58440e0d..33e51d33 100644 --- a/tests/security-audit-script.test.ts +++ b/tests/security-audit-script.test.ts @@ -13,6 +13,21 @@ describe("security-audit script", () => { } }); + it("pins the production advisories that npm audit --omit=dev currently reports", () => { + const pkg = JSON.parse(readFileSync(join(process.cwd(), "package.json"), "utf8")) as { + dependencies: Record; + overrides: Record; + }; + const agent = JSON.parse( + readFileSync(join(process.cwd(), "packages/efficiency-agent/package.json"), "utf8") + ) as { dependencies: Record }; + // GHSA-6qxp-vccf-f47h: @modelcontextprotocol/sdk <1.31.0 + expect(pkg.dependencies["@modelcontextprotocol/sdk"]).toBe("^1.32.1"); + expect(agent.dependencies["@modelcontextprotocol/sdk"]).toBe("^1.32.1"); + // GHSA-jqcg-44mw-7w3h: proxy-addr <2.0.8, still allowed by express's ^2.0.7 + expect(pkg.overrides["proxy-addr"]).toBe("^2.0.8"); + }); + it("imports join from node:path so the scheduled audit can start", () => { const src = readFileSync(join(process.cwd(), "scripts/security-audit.cjs"), "utf8"); expect(src).toMatch(/require\(["']node:path["']\)/);