From 1018d818ba501f1fa6d365561d0c3f03b51b8c4a Mon Sep 17 00:00:00 2001 From: cliffhall Date: Fri, 4 Sep 2026 19:08:03 -0400 Subject: [PATCH] chore(deps): refresh fast-uri, qs and browserslist to clear npm audit Closes #2244 Closes #2225 All three outstanding advisories were stale lockfile resolutions, not upward-blocked pins: every fixed version already sits inside the range its declaring parent asks for, so refreshing the lock entry is the whole fix. fast-uri 3.1.5 -> 3.1.7 ajv@8.18.0 asks for ^3.0.1 (root) qs 6.15.3 -> 6.16.0 express@5.2.1 asks for ^6.14.0 (root) browserslist 4.28.2 -> 4.28.9 via @babel/core (clients/tui) No `overrides` entry is added, and no manifest changes. AGENTS.md's rule is that a transitive is pinned with `overrides` rather than with `npm audit fix` -- it does not call for a pin where none is needed. A permanent pin here would buy nothing and would later hold a package back: `fast-uri: ^3.1.6` forbids fast-uri 4.x for as long as it stands, including after ajv moves to it. The monthly refresh sweep and the daily alert sweep are what catch a regression. `npm audit` is clean in all five installs (root, web, cli, tui, launcher). Reachability, assessed rather than assumed: - fast-uri is the one that ships. ajv is a root runtime dependency, and Vite pre-bundles it into the published `clients/web/dist`, so the vulnerable code was inlined into the SPA rather than merely resolved at install time. Its input is attacker-influenced: `schemaUtils.ts` compiles the `outputSchema` a server under test supplies, and ajv resolves that schema's `$id`/`$ref` through fast-uri (`ajv/dist/runtime/uri.js`). Impact is bounded well below the advisory headlines, though: both SSRF advisories need a consumer that fetches the parsed URI, and ajv never performs a network request. The realistic worst case is the host-confusion pair mis-normalizing a crafted `$id`, giving a wrong or failed validation of one tool's output. - qs is installed in production, but nothing shipped runs it. express is a root devDependency, but that is not its only path: `npm ls express --omit=dev` shows it reaching a production install through @modelcontextprotocol/server-legacy@2.0.0 (a root runtime dependency, also via express-rate-limit) and through @modelcontextprotocol/ext-apps -> @modelcontextprotocol/sdk@1.30.0. So qs is present in every user install. What holds is that no shipped module ever instantiates it: nothing in `core/`, `clients/*/src` or `clients/web/server` calls `express()`, the web backend is Hono, and server-legacy is imported only from `test-servers/src`, which the root `files` list does not publish. Both advisories need express to parse an attacker-supplied query string, which requires a live express app. - browserslist is dev tooling. It arrives in the clients/tui install through eslint-plugin-react-hooks -> @babel/core, is reached only by lint, and is in no published bundle. The root install already resolved a patched 4.28.8 from the same plugin at the same version, which is what identified tui's copy as a stale lock rather than a constrained one. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01YahVxMTGpigLbZBh1JGPDr Signed-off-by: cliffhall --- clients/tui/package-lock.json | 46 +++++++++++++++++------------------ package-lock.json | 12 ++++----- 2 files changed, 29 insertions(+), 29 deletions(-) diff --git a/clients/tui/package-lock.json b/clients/tui/package-lock.json index c107e5fbd..9b4ebc834 100644 --- a/clients/tui/package-lock.json +++ b/clients/tui/package-lock.json @@ -1816,9 +1816,9 @@ } }, "node_modules/baseline-browser-mapping": { - "version": "2.10.38", - "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.38.tgz", - "integrity": "sha512-31/02mVB4yuQU6adKk5SlY6m+mxDwUq5KZkyYgnLrrKl7TEm1+3PyDtDBz2kOv/wxZz41GHsvV1A/u6RmiyBvw==", + "version": "2.11.21", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.11.21.tgz", + "integrity": "sha512-uh8vpY/1/YyFkunIDFH/12p7/7VdPKA1hejMVEbdkEaWnUz0Hesvx5EbiU6XxjyHZIOju+ZMbQJkRh+es3/spQ==", "dev": true, "license": "Apache-2.0", "bin": { @@ -1843,9 +1843,9 @@ } }, "node_modules/browserslist": { - "version": "4.28.2", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.2.tgz", - "integrity": "sha512-48xSriZYYg+8qXna9kwqjIVzuQxi+KYWp2+5nCYnYKPTr0LvD89Jqk2Or5ogxz0NUMfIjhh2lIUX/LyX9B4oIg==", + "version": "4.28.9", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.9.tgz", + "integrity": "sha512-EWazOblFYUvlGZcfGhPUPmYh3nikUxBVb+y9MJun5f3hBi812X+8MSQTujLBtgK3cf51fJWbWfOjyeO954d+Eg==", "dev": true, "funding": [ { @@ -1863,11 +1863,11 @@ ], "license": "MIT", "dependencies": { - "baseline-browser-mapping": "^2.10.12", - "caniuse-lite": "^1.0.30001782", - "electron-to-chromium": "^1.5.328", - "node-releases": "^2.0.36", - "update-browserslist-db": "^1.2.3" + "baseline-browser-mapping": "^2.11.20", + "caniuse-lite": "^1.0.30001810", + "electron-to-chromium": "^1.5.420", + "node-releases": "^2.0.54", + "update-browserslist-db": "^1.3.2" }, "bin": { "browserslist": "cli.js" @@ -1903,9 +1903,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001799", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001799.tgz", - "integrity": "sha512-hG1bReV+OUU+MOqK4t/ZWI0tZOyz3rqS9XuhOUz1cIcbwBKjOyJEJuw9ER5JuNyqxNk8u/JUVbGibBOL1yrjFw==", + "version": "1.0.30001810", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001810.tgz", + "integrity": "sha512-TITQPUkaz+aVk5GL6NhOdwk1aEaNTSDPsGFWrTuhKGtjTF70jL/Oht2W4c6rXUe5fu7Ie19VIahAXHIIiWWNeg==", "dev": true, "funding": [ { @@ -2099,9 +2099,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.5.376", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.376.tgz", - "integrity": "sha512-cUVA7/RvbFTEuw/i3obUwDTRIXojaxkResf+ibByPFxjc6XK3VNtcQXV0NSbAlJ0FMjcJGgftVVB4Qo184EXvA==", + "version": "1.5.422", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.422.tgz", + "integrity": "sha512-UvA/32XqrLDdZSn7Jllo1AYNcWji/G0d5M0GTViE7KoGBiMunw3a34Sb2KO4ZZyrSEhqsxFoVhWWJshdyfKqJA==", "dev": true, "license": "ISC" }, @@ -3366,9 +3366,9 @@ "peer": true }, "node_modules/node-releases": { - "version": "2.0.48", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.48.tgz", - "integrity": "sha512-1uz8041X6LoI6ZSdZacM9lVY28vuzDlSKitnpbSNK0RfKoIJkX29NBPVEFXhnuSuEOA9Ww0xnPJ+ILWbGAv8DA==", + "version": "2.0.54", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.54.tgz", + "integrity": "sha512-YHs7BmmcsdAI5Ozuf8JZo6PT0mv2GIWC9vMfvUC3dp65M8hn7Ux8CPL+2oBI7juNuj9d0ndhTcznq2ODBps9cQ==", "dev": true, "license": "MIT", "engines": { @@ -4151,9 +4151,9 @@ "license": "MIT" }, "node_modules/update-browserslist-db": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", - "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.3.2.tgz", + "integrity": "sha512-UQ+MSxlhRm1bzjhU+DcuXfjFO1FzNtqhK5+9Yvlp90ItDLk5vT932A0rFu619nf7RVS+Y/VeaUW1jaRDqZ8VJw==", "dev": true, "funding": [ { diff --git a/package-lock.json b/package-lock.json index bb0cd36ee..ba8b251eb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2856,9 +2856,9 @@ "license": "MIT" }, "node_modules/fast-uri": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.5.tgz", - "integrity": "sha512-gHwA1O9LDIcKunMKhObS/HimwtehO1nPUECKAu5TpKgaO19fcWEl4bliWe1jWxVFvIXztJjjQ4L8XQ1EU9f7Jw==", + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.7.tgz", + "integrity": "sha512-dOvZVzjdZdz7phd9v6jCbwxrBW3fK6n8Rc0CtdmM4bumzMnxywBYhuph6J819RRw/ku+rLbelwfMunktuzVVHg==", "funding": [ { "type": "github", @@ -4383,9 +4383,9 @@ } }, "node_modules/qs": { - "version": "6.15.3", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.3.tgz", - "integrity": "sha512-O9gl3zCl5h5blw1KGUzQKhA5oUXSl8rwUIM5o0S3nCXMliSvy5Dzx7/DJcI+SwgICv+IneSZwhBh1oSyEHA71A==", + "version": "6.16.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.16.0.tgz", + "integrity": "sha512-h6fhOIaRrID2CbEY2fqs+7t+UXZo+MLAnU5gRIq85uFtdiUPCdsApMlHhXogKVM4HM2DVbIjGNTTYH2OcmP1vA==", "license": "BSD-3-Clause", "dependencies": { "es-define-property": "^1.0.1",