chore(deps): upgrade dependencies with known vulnerabilities - #2999
chore(deps): upgrade dependencies with known vulnerabilities#2999dokterbob wants to merge 3 commits into
Conversation
Raise floors on four direct runtime dependencies so that `pip install chainlit` cannot resolve a known-vulnerable version: mcp >=1.11.0 -> >=1.28.1 (3x high) pyjwt >=2.8.0 -> >=2.13.0 (2x high) python-multipart >=0.0.18 -> >=0.0.30 (3x high) pydantic-settings >=2.10.1 -> >=2.14.2 (1x medium) All four support Python 3.10, so the 3.10-3.13 CI matrix is unaffected. Upper bounds are untouched. Refresh uv.lock via targeted --upgrade-package flags only (no bare --upgrade): 21 packages moved, 1 added. langchain-core is pinned to 1.3.3. 1.5.x widens on_llm_new_token to `str | list[str | dict]`, which trips mypy's Liskov check against the narrower `token: str` override in chainlit/langchain/callbacks.py. Widening that signature is a behaviour change and belongs in its own PR. Deliberately excluded: - python-socketio / python-engineio held at 5.15.0 / 4.12.3 and the floor left at >=5.11.0, pending investigation of reported disconnect-handler warnings. Leaves one high advisory (binary attachment DoS) open, and preserves the ability to pin below 5.12.0. - starlette held at >=0.47.2: fastapi 0.123.5 pins starlette<0.51.0, so reaching 1.3.1 is really an 18-minor fastapi upgrade. - semantic-kernel cannot move: 1.39.4 pins openai<2 while the tests extra requires openai>=2.0.0,<3.0.0. Advisory stays open. Verified: pytest 801 passed; type_check, lint and format --check clean under both `--extra tests --extra custom-data` and `--all-extras --dev`. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BAURDqzAzmDL8LDC7Zs2RK
…ides Add pnpm.overrides entries for transitive packages with known advisories. These cannot be reached with `pnpm update <name>`, which only moves packages carrying a manifest specifier, so overrides are the same mechanism already used by the existing entries in these files. Closes, across the four independent lockfiles: handlebars 4.7.8 -> 4.7.9 CRITICAL, AST type-confusion postcss 8.4.x -> 8.5.25 2x high ws 8.18.0 -> 8.21.1 high rollup 4.24.0 -> 4.62.3 high minimatch 9.0.5 -> 9.0.9 high glob 10.4.5 -> 10.5.0 high picomatch 2.3.1 -> 2.3.2 high brace-expansion -> 2.1.4 / 5.0.9 high immutable -> 3.8.3 / 4.3.9 2x high socket.io-parser 4.2.4 -> 4.2.7 high js-yaml 4.1.0 -> 4.3.0 high form-data 4.0.0 -> 4.0.6 high flatted 3.3.2 -> 3.4.4 high lodash/undici/qs/tmp/yaml/@babel/core/mdast-util-to-hast: medium+low Direct dependency specifiers move within their existing ^ ranges: react-router-dom 6.30.4 (terminal v6, clears @remix-run/router), storybook 8.6.18, postcss 8.5.25, immutable 4.3.9, lodash 4.18.1. All override ranges are two-sided so they cannot drift across a major. No major crossed: vite 5.4.14, vitest 0.34.x, react-router 6.30.4, storybook 8.6.18, undici 6.28.0. Existing override entries are preserved unchanged; only new entries are appended. Known incomplete, being addressed separately: - libs/react-client resolves both ws 8.18.0 and 8.21.1; the 8.18.0 edge comes from engine.io-client's `~8.11.0`, which is caught by the older `ws@>=8.0.0 <8.17.1` override before the new one can apply. - libs/react-client likewise retains rollup 4.24.0 alongside 4.62.3, via tsup's exact pin. - root @babel/core stays at 7.29.0 despite the override; consumers' peer ranges were rewritten but the resolution was not. Note `pnpm install --frozen-lockfile` passes in all four directories even with those gaps present -- it verifies lockfile/manifest agreement, not semver consistency of the resolved graph. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BAURDqzAzmDL8LDC7Zs2RK
There was a problem hiding this comment.
4 issues found across 10 files
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="frontend/package.json">
<violation number="1" location="frontend/package.json:125">
P2: This selector upgrades every `glob` dependency below 10.5.0 to the 10.x line, including transitive consumers that may still require glob 7.x or 8.x; it is not limited to the vulnerable 10.x range. The same broad major-crossing override is repeated in the other package manifests, and analogous selectors do this for `minimatch`, `js-yaml`, `form-data`, and `yaml`. That contradicts the stated no-major-upgrades goal and can break older consumers through API or engine incompatibilities. Major lines should be constrained separately or the override should be scoped to the dependency edge that needs the security fix.</violation>
<violation number="2" location="frontend/package.json:129">
P2: form-data override range is too broad: `form-data@<4.0.6` matches v2 and v3 as well as v4. Overriding form-data v2/v3 to >=4.0.6 forces a major-version upgrade that can break consumers expecting the v2/v3 API. Scope it to `form-data@>=4.0.0 <4.0.6` to stay within v4.</violation>
<violation number="3" location="frontend/package.json:130">
P2: yaml override range is too broad: `yaml@<2.8.3` matches v1.x, which would force a v1→v2 major upgrade with breaking API changes. Scope it to `yaml@>=2.0.0 <2.8.3` to stay within v2.</violation>
</file>
<file name="package.json">
<violation number="1" location="package.json:54">
P1: The root `@babel/core` resolution is explicitly known not to be affected by this override, so the root dependency graph can still contain a version below 7.29.6. This leaves one of the targeted vulnerability fixes incomplete while the lockfile remains installable. The root/direct Babel dependency or the specific unresolved edge should be upgraded, then the root lockfile should be verified for the fixed floor.</violation>
</file>
Tip: cubic can generate docs of your entire codebase and keep them up to date. Try it here.
Re-trigger cubic
| "qs@<6.14.2": ">=6.14.2 <7.0.0", | ||
| "tmp@<0.2.6": ">=0.2.6 <0.3.0", | ||
| "yaml@<2.8.3": ">=2.8.3 <3.0.0", | ||
| "@babel/core@<7.29.6": ">=7.29.6 <8.0.0" |
There was a problem hiding this comment.
P1: The root @babel/core resolution is explicitly known not to be affected by this override, so the root dependency graph can still contain a version below 7.29.6. This leaves one of the targeted vulnerability fixes incomplete while the lockfile remains installable. The root/direct Babel dependency or the specific unresolved edge should be upgraded, then the root lockfile should be verified for the fixed floor.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At package.json, line 54:
<comment>The root `@babel/core` resolution is explicitly known not to be affected by this override, so the root dependency graph can still contain a version below 7.29.6. This leaves one of the targeted vulnerability fixes incomplete while the lockfile remains installable. The root/direct Babel dependency or the specific unresolved edge should be upgraded, then the root lockfile should be verified for the fixed floor.</comment>
<file context>
@@ -40,7 +40,18 @@
+ "qs@<6.14.2": ">=6.14.2 <7.0.0",
+ "tmp@<0.2.6": ">=0.2.6 <0.3.0",
+ "yaml@<2.8.3": ">=2.8.3 <3.0.0",
+ "@babel/core@<7.29.6": ">=7.29.6 <8.0.0"
}
},
</file context>
| "immutable@>=3.0.0 <3.8.3": ">=3.8.3 <4.0.0", | ||
| "js-yaml@<4.3.0": ">=4.3.0 <5.0.0", | ||
| "form-data@<4.0.6": ">=4.0.6 <5.0.0", | ||
| "yaml@<2.8.3": ">=2.8.3 <3.0.0", |
There was a problem hiding this comment.
P2: yaml override range is too broad: yaml@<2.8.3 matches v1.x, which would force a v1→v2 major upgrade with breaking API changes. Scope it to yaml@>=2.0.0 <2.8.3 to stay within v2.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At frontend/package.json, line 130:
<comment>yaml override range is too broad: `yaml@<2.8.3` matches v1.x, which would force a v1→v2 major upgrade with breaking API changes. Scope it to `yaml@>=2.0.0 <2.8.3` to stay within v2.</comment>
<file context>
@@ -117,7 +117,19 @@
+ "immutable@>=3.0.0 <3.8.3": ">=3.8.3 <4.0.0",
+ "js-yaml@<4.3.0": ">=4.3.0 <5.0.0",
+ "form-data@<4.0.6": ">=4.0.6 <5.0.0",
+ "yaml@<2.8.3": ">=2.8.3 <3.0.0",
+ "mdast-util-to-hast@<13.2.1": ">=13.2.1 <14.0.0",
+ "@babel/core@<7.29.6": ">=7.29.6 <8.0.0"
</file context>
| "picomatch@<2.3.2": ">=2.3.2 <3.0.0", | ||
| "immutable@>=3.0.0 <3.8.3": ">=3.8.3 <4.0.0", | ||
| "js-yaml@<4.3.0": ">=4.3.0 <5.0.0", | ||
| "form-data@<4.0.6": ">=4.0.6 <5.0.0", |
There was a problem hiding this comment.
P2: form-data override range is too broad: form-data@<4.0.6 matches v2 and v3 as well as v4. Overriding form-data v2/v3 to >=4.0.6 forces a major-version upgrade that can break consumers expecting the v2/v3 API. Scope it to form-data@>=4.0.0 <4.0.6 to stay within v4.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At frontend/package.json, line 129:
<comment>form-data override range is too broad: `form-data@<4.0.6` matches v2 and v3 as well as v4. Overriding form-data v2/v3 to >=4.0.6 forces a major-version upgrade that can break consumers expecting the v2/v3 API. Scope it to `form-data@>=4.0.0 <4.0.6` to stay within v4.</comment>
<file context>
@@ -117,7 +117,19 @@
+ "picomatch@<2.3.2": ">=2.3.2 <3.0.0",
+ "immutable@>=3.0.0 <3.8.3": ">=3.8.3 <4.0.0",
+ "js-yaml@<4.3.0": ">=4.3.0 <5.0.0",
+ "form-data@<4.0.6": ">=4.0.6 <5.0.0",
+ "yaml@<2.8.3": ">=2.8.3 <3.0.0",
+ "mdast-util-to-hast@<13.2.1": ">=13.2.1 <14.0.0",
</file context>
| "ws@>=8.17.1 <8.21.0": ">=8.21.0 <9.0.0", | ||
| "rollup@>=4.0.0 <4.59.0": ">=4.59.0 <5.0.0", | ||
| "minimatch@<9.0.7": ">=9.0.7 <10.0.0", | ||
| "glob@<10.5.0": ">=10.5.0 <11.0.0", |
There was a problem hiding this comment.
P2: This selector upgrades every glob dependency below 10.5.0 to the 10.x line, including transitive consumers that may still require glob 7.x or 8.x; it is not limited to the vulnerable 10.x range. The same broad major-crossing override is repeated in the other package manifests, and analogous selectors do this for minimatch, js-yaml, form-data, and yaml. That contradicts the stated no-major-upgrades goal and can break older consumers through API or engine incompatibilities. Major lines should be constrained separately or the override should be scoped to the dependency edge that needs the security fix.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At frontend/package.json, line 125:
<comment>This selector upgrades every `glob` dependency below 10.5.0 to the 10.x line, including transitive consumers that may still require glob 7.x or 8.x; it is not limited to the vulnerable 10.x range. The same broad major-crossing override is repeated in the other package manifests, and analogous selectors do this for `minimatch`, `js-yaml`, `form-data`, and `yaml`. That contradicts the stated no-major-upgrades goal and can break older consumers through API or engine incompatibilities. Major lines should be constrained separately or the override should be scoped to the dependency edge that needs the security fix.</comment>
<file context>
@@ -117,7 +117,19 @@
+ "ws@>=8.17.1 <8.21.0": ">=8.21.0 <9.0.0",
+ "rollup@>=4.0.0 <4.59.0": ">=4.59.0 <5.0.0",
+ "minimatch@<9.0.7": ">=9.0.7 <10.0.0",
+ "glob@<10.5.0": ">=10.5.0 <11.0.0",
+ "picomatch@<2.3.2": ">=2.3.2 <3.0.0",
+ "immutable@>=3.0.0 <3.8.3": ">=3.8.3 <4.0.0",
</file context>
Three override edges declared in the previous commit never applied. pnpm matches an override selector against the *dependent's declared range*, not against the resolved version, and applies exactly one override per edge with no cascading (see `pickVersionOverride` in pnpm's read-package-hook). ws: engine.io-client declares `ws: ~8.11.0`, which is disjoint from the `ws@>=8.17.1 <8.21.0` selector, so that pin could never match this edge. It was instead caught by the older `ws@>=8.0.0 <8.17.1` entry and left at 8.18.0. Replaced both with a single `ws@>=8.0.0 <8.21.0` -> `>=8.21.0 <9.0.0`, which intersects engine.io-client's `~8.11.0` and jsdom's `^8.13.0` alike. rollup: tsup declares `rollup: ^3.2.5`, which only ever intersected the pre-existing `rollup@>=3.0.0 <3.29.5` -> `>=3.29.5` entry. That target has no upper bound, so a 3.x consumer was free to drift up into a vulnerable 4.x -- which is how 4.24.0 (CVE-2026-27606, arbitrary file write via path traversal) entered the tree in the first place. Bounding it as `rollup@>=3.0.0 <4.59.0` -> `>=4.59.0 <5.0.0` closes the window while keeping the >=3.0.0 floor so no 1.x/2.x consumer is ever retargeted. Result: libs/react-client now resolves a single ws 8.21.1 and a single rollup 4.62.3; the duplicate 4.24.0 and its 16 platform binaries are gone. Root @babel/core stays at 7.29.0 and is deliberately not addressed here. It is an auto-installed peer rather than a declared edge, so it needs an explicit root devDependency rather than an override; it is CI-only tooling (cypress-split), the root package is unpublishable, and the advisory is low. None of the three was ever end-user exposure: all were verified absent from the built artifacts. engine.io-client's `browser` field remaps to the native WebSocket, so `ws` never enters libs/react-client/dist or the frontend bundle shipped in the PyPI package; rollup is a build tool. Verified: frozen-lockfile install clean in all four directories, builds green, lint, type-check, 32/32 frontend unit tests. No major crossed. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BAURDqzAzmDL8LDC7Zs2RK
Clears the reachable portion of the Dependabot backlog without any manifest
major upgrades. Three commits, separately revertable.
Backend
Raises floors on four direct runtime dependencies, so
pip install chainlitcannot resolve a known-vulnerable version. Upper bounds untouched; all four
support Python 3.10, so the 3.10-3.13 matrix is unaffected.
uv.lockrefreshed with targeted--upgrade-packageflags only, never a bare--upgrade: 21 packages moved, 1 added.Frontend
.npmrcsetsshared-workspace-lockfile=false, so there are four independentlockfiles, each updated. The CVE'd packages here are almost all transitive, and
pnpm update <name>is a no-op for those -- it only moves packages carrying amanifest specifier. They are pinned with
pnpm.overridesinstead, the samemechanism as the existing entries in these files.
Headline: handlebars 4.7.8 -> 4.7.9 (critical, AST type-confusion JS
injection). Plus postcss 8.5.25, ws 8.21.1, rollup 4.62.3, minimatch 9.0.9,
glob 10.5.0, picomatch 2.3.2, brace-expansion 2.1.4/5.0.9, immutable 3.8.3 and
4.3.9, socket.io-parser 4.2.7, js-yaml 4.3.0, form-data 4.0.6, flatted 3.4.4,
and a tail of medium/low.
New override ranges are two-sided so they cannot drift across a major. No major
crossed: vite 5.4.14, vitest 0.34.x, react-router 6.30.4, storybook 8.6.18,
undici 6.28.0.
Two pre-existing override bugs, fixed in the third commit
Worth review attention -- the first pass declared overrides that silently did
not apply, and finding out why turned up a latent bug that predates this PR.
pnpm matches an override selector against the dependent's declared range,
not against the resolved version, and applies exactly one override per edge
with no cascading (
pickVersionOverridein pnpm's read-package-hook).engine.io-clientdeclaresws: ~8.11.0, which is disjoint from thews@>=8.17.1 <8.21.0selector -- so that pin could never match. The edgewas caught by the older
ws@>=8.0.0 <8.17.1entry and left at 8.18.0.tsupdeclaresrollup: ^3.2.5, which only ever intersected thepre-existing
rollup@>=3.0.0 <3.29.5->>=3.29.5entry. That target hasno upper bound, so a 3.x consumer was free to drift up into a vulnerable
4.x -- which is how rollup 4.24.0 (CVE-2026-27606, arbitrary file write via
path traversal) entered the tree in the first place, independently of this
PR.
Both are now single bounded entries:
ws@>=8.0.0 <8.21.0->>=8.21.0 <9.0.0and
rollup@>=3.0.0 <4.59.0->>=4.59.0 <5.0.0.libs/react-clientnowresolves a single ws 8.21.1 and a single rollup 4.62.3; the duplicate 4.24.0
and its 16 platform binaries are gone. Every other override entry is preserved
byte-for-byte.
Neither was ever end-user exposure -- both were verified absent from the built
artifacts.
engine.io-client'sbrowserfield remaps to the nativeWebSocket, sowsnever enterslibs/react-client/distnor the frontendbundle shipped inside the PyPI package; rollup is a build tool.
Still open
Root
@babel/corestays at 7.29.0 despite its override. It is anauto-installed peer rather than a declared edge, so the fix is an explicit root
devDependency, not an override -- deliberately left for separate work. It is
CI-only tooling (cypress-split), the root package has no
nameand isunpublishable, and the advisory is low.
Worth flagging independently of this PR:
pnpm install --frozen-lockfilepassed in all four directories while all three gaps above were present. It
verifies lockfile/manifest agreement, not semver consistency of the resolved
graph -- so this class of gap is invisible to CI.
Deliberately out of scope
starlette-> 1.3.1fastapi0.123.5 pinsstarlette<0.51.0; the cap lifts only in fastapi 0.141.0, so this is an 18-minor fastapi upgradepython-socketio-> 5.16.2>=5.11.0, pending investigation of reported disconnect-handler warnings. Leaves the binary-attachment DoS opensemantic-kernel-> 1.39.4openai<2, the tests extra requiresopenai>=2.0.0,<3.0.0langchain-core1.5.xon_llm_new_tokentostr | list[str | dict]; the narrower override inchainlit/langchain/callbacks.pyfails mypy. Pinned to 1.3.3vite6,vitest3,react-router7vitestcritical advisory@vitest/uiis an optional peer and is not installedjsonpicklecriticalbotbuilder-corein the tests extra only, never in the shipped runtime treeVerification
CI on the first two commits was green across the board: python 3.10/3.11/3.12/
3.13, backend and frontend lint/format/type-check, and E2E on ubuntu x5 and
windows x5. The third commit is pushed and awaiting the same.
Locally: pytest 801 passed; backend type-check, lint and format --check clean
under both
--extra tests --extra custom-dataand--all-extras --dev;frozen-lockfile install clean in all four directories; builds green; 32/32
frontend unit tests.
🤖 Generated with Claude Code
https://claude.ai/code/session_01BAURDqzAzmDL8LDC7Zs2RK