Skip to content

chore(deps): upgrade dependencies with known vulnerabilities - #2999

Open
dokterbob wants to merge 3 commits into
mainfrom
chore/dependency-security-updates
Open

chore(deps): upgrade dependencies with known vulnerabilities#2999
dokterbob wants to merge 3 commits into
mainfrom
chore/dependency-security-updates

Conversation

@dokterbob

@dokterbob dokterbob commented Jul 30, 2026

Copy link
Copy Markdown
Collaborator

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 chainlit
cannot resolve a known-vulnerable version. Upper bounds untouched; all four
support Python 3.10, so the 3.10-3.13 matrix is unaffected.

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

uv.lock refreshed with targeted --upgrade-package flags only, never a bare
--upgrade: 21 packages moved, 1 added.

Frontend

.npmrc sets shared-workspace-lockfile=false, so there are four independent
lockfiles, 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 a
manifest specifier. They are pinned with pnpm.overrides instead, the same
mechanism 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 (pickVersionOverride in pnpm's read-package-hook).

  1. 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. The edge
    was caught by the older ws@>=8.0.0 <8.17.1 entry and left at 8.18.0.
  2. 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 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.0
and rollup@>=3.0.0 <4.59.0 -> >=4.59.0 <5.0.0. 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. 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's browser field remaps to the native
WebSocket, so ws never enters libs/react-client/dist nor the frontend
bundle shipped inside the PyPI package; rollup is a build tool.

Still open

Root @babel/core stays at 7.29.0 despite its override. It is an
auto-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 name and is
unpublishable, and the advisory is low.

Worth flagging independently of this PR: pnpm install --frozen-lockfile
passed 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

Item Why
starlette -> 1.3.1 fastapi 0.123.5 pins starlette<0.51.0; the cap lifts only in fastapi 0.141.0, so this is an 18-minor fastapi upgrade
python-socketio -> 5.16.2 Held at 5.15.0, floor left at >=5.11.0, pending investigation of reported disconnect-handler warnings. Leaves the binary-attachment DoS open
semantic-kernel -> 1.39.4 Cannot resolve: 1.39.4 pins openai<2, the tests extra requires openai>=2.0.0,<3.0.0
langchain-core 1.5.x Widens on_llm_new_token to str | list[str | dict]; the narrower override in chainlit/langchain/callbacks.py fails mypy. Pinned to 1.3.3
vite 6, vitest 3, react-router 7 Majors across all three JS packages
vitest critical advisory Requires the Vitest UI server listening; @vitest/ui is an optional peer and is not installed
jsonpickle critical No patched version exists; arrives via botbuilder-core in the tests extra only, never in the shipped runtime tree
lockfile dedupe Large pure-churn diff, own PR

Verification

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-data and --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

dokterbob and others added 2 commits July 30, 2026 15:12
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
@dokterbob
dokterbob marked this pull request as ready for review July 30, 2026 14:27
@dosubot dosubot Bot added size:XS This PR changes 0-9 lines, ignoring generated files. dependencies Pull requests that update a dependency file labels Jul 30, 2026

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Comment thread package.json
"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"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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>

Comment thread frontend/package.json Outdated
Comment thread frontend/package.json Outdated
Comment thread frontend/package.json Outdated
Comment thread frontend/package.json
"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",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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>

Comment thread frontend/package.json
"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",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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>

Comment thread frontend/package.json
"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",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependencies Pull requests that update a dependency file review-me Ready for review! size:XS This PR changes 0-9 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant