Skip to content

fix: clear the zod, MCP SDK, and body-parser advisory drift - #359

Merged
alexander-sei merged 4 commits into
mainfrom
fix/zod-advisory-widening
Oct 23, 2026
Merged

alexander-sei merged 4 commits into
mainfrom
fix/zod-advisory-widening

Conversation

@alexander-sei

Copy link
Copy Markdown
Collaborator

Re-running the release smokes against today's advisory data shows that the green checks on #358 are stale. Two advisories reached npm's audit data after those checks ran:

  • GHSA-mrhx-c7xc-m3w5 (high, Zod array validation below 4.6.6) was updated on October 23 at 18:26 UTC and now reports the zod@4.0.5 that Dynamic pins and the zod@3.22.4 that Reown pins. On the Version Packages #358 head, bun run test:sei-global-wallet-release fails because the wallet-only npm consumer, which must audit clean, reports zod. Every create-sei app also reports a new high; that smoke stays green only because registry-mode audits are report-only.
  • GHSA-27r3-jxmh-p828 (high, published October 23 at 20:53 UTC) covers body-parser below 1.20.9, which both mcp-server HTTP transports parse requests with.

mcp-server also declared floors (@modelcontextprotocol/sdk ^1.23.0, zod ^4.0.5) that let an in-place upgrade keep releases inside the SDK advisories published October 6–20. A fresh install was already clean.

Changes

One commit per fix, so each can be reviewed or dropped on its own.

  • sei-global-wallet: add "zod": "4.6.7" to the verifier's baseSafeOverrides and all three README override blocks. The README notes that the override is global, so npm applications with their own Zod 3 dependency (such as Reown under wagmi) should scope it to @dynamic-labs-sdk/client and @dynamic-labs/wallet-book. New patch changeset.
  • create-sei: the pending 2.0.2 note now lists the Reown zod finding next to decode-uri-component instead of calling the latter the only one left. No override reaches it: Reown 1.8.24 still pins zod@3.22.4, and Zod has no fixed 3.x.
  • mcp-server floors: @modelcontextprotocol/sdk ^1.32.0 and zod ^4.6.6. A root zod: 4.6.7 override keeps the workspace on one copy, which mcp-zod-lock requires while Dynamic pins 4.0.5. bun.lock moves only the SDK (1.30.0 → 1.32.2) and zod (4.0.5 → 4.6.7). The SDK range test now pins the advisory floor.
  • mcp-server compressed bodies: both HTTP transports pass express.json({ inflate: false }), the advisory's documented workaround, so an encoded request body gets a 415 whichever body-parser an existing lockfile holds. Express 4 accepts body-parser ~1.20.5, so no floor could do this. It is a behavior change for a client that compresses request bodies; the SDK's client transports do not. The pending Brotli note's sentence about Express inflating gzip and deflate is updated to match.

Verification

  • bun run test:sei-global-wallet-release (full run) fails on the Version Packages #358 head with zod (GHSA-mrhx-c7xc-m3w5) and passes on this branch. The wallet-only npm consumer audits clean, the full npm consumer reports only the three waived stream-json advisories, and the Bun AA consumer stays within its waiver with zod no longer reported.
  • bun run check, bun run build, bun run test (626 mcp-server tests, 48 script tests, and the other package suites), and bun run lint:pack:all pass on Bun 1.4.4 and Node 26.12.1.
  • The two new transport tests send a gzip frame with trailing bytes and expect a 415 and a live /health. Both fail against the previous express.json(), which answers 400.
  • I could not reproduce the advisory's process crash on Node 26.12.1 with gzip or deflate payloads; the old code answered 400 or 200 and stayed up. The inflate: false change rests on the advisory's description and workaround, not a local reproduction.
  • A fresh npm install of mcp-server's new ranges audits clean. For an app that also installs @reown/appkit-wallet, the scoped npm zod override resolves Dynamic to 4.6.7 while Reown keeps 3.22.4, as the README describes.

The release plan is unchanged: create-sei 2.0.2, mcp-server 1.0.2, and sei-global-wallet 2.0.2, all patch.

alexander-sei and others added 4 commits October 24, 2026 00:48
…c-m3w5

GHSA-mrhx-c7xc-m3w5 (high) covers Zod's array validation below 4.6.6.
Since its October 23 update it reports the zod@4.0.5 that
@dynamic-labs-sdk/client and @dynamic-labs/wallet-book pin exactly, so
the wallet-only npm consumer, which must audit clean, failed. The newest
@dynamic-labs-sdk/client (1.45.0) still pins 4.0.5.

The verifier's override set and all three README blocks gain
"zod": "4.6.7", a minor-level move inside Zod 4. Nothing else in the
wallet graph, including the AA path, needs Zod 3, so it is safe as a
global Bun override. The README tells npm applications with their own
Zod 3 dependency, such as Reown under wagmi, to scope it instead.

Co-authored-by: Cursor <cursoragent@cursor.com>
Generated apps now also report GHSA-mrhx-c7xc-m3w5 (high) through the
zod@3.22.4 that @reown/appkit-wallet pins under wagmi's WalletConnect
connector. Reown's newest release still pins it and Zod has no fixed
3.x, so the template cannot override it without moving Reown onto Zod 4.
The note claiming decode-uri-component was the only remaining finding
now lists both.

Co-authored-by: Cursor <cursoragent@cursor.com>
Fresh installs already resolved fixed releases, but ^1.23.0 and ^4.0.5
let an existing lockfile keep @modelcontextprotocol/sdk below 1.32.0,
where GHSA-46jr-4wx8-v453 lets one HTTP request exhaust server memory,
and zod below 4.6.6. The floors move to ^1.32.0 and ^4.6.6.

A root zod override keeps the workspace on one copy, since Dynamic still
pins 4.0.5 and mcp-zod-lock requires the SDK to share mcp-server's zod.
bun.lock moves only the SDK to 1.32.2 and zod to 4.6.7. The SDK range
test now pins the advisory floor.

Co-authored-by: Cursor <cursoragent@cursor.com>
GHSA-27r3-jxmh-p828 (high, published October 23) covers body-parser
below 1.20.9: a compressed body followed by trailing bytes can raise an
uncaught exception that terminates the process, before routing. Express 4
accepts body-parser ~1.20.5, so no floor here can move an existing
lockfile off a vulnerable copy.

Both transports now pass inflate: false, the advisory's workaround, so an
encoded body gets a 415 before any decompression stream exists. The SDK's
client transports send uncompressed JSON. The Brotli note for this
release said Express inflates gzip and deflate, which is no longer true.

Co-authored-by: Cursor <cursoragent@cursor.com>
@cursor

cursor Bot commented Oct 23, 2026 •

Copy link
Copy Markdown

PR Summary

Medium Risk
MCP HTTP transports now reject compressed request bodies (415), and global Zod 4 overrides can affect apps that still depend on Zod 3 unless scoped on npm.

Overview
Addresses stale release smokes after new Zod (GHSA-mrhx-c7xc-m3w5) and body-parser (GHSA-27r3-jxmh-p828) advisories landed in npm audit data.

@sei-js/sei-global-wallet documents and applies a root "zod": "4.6.7" override (README blocks, release verifier baseSafeOverrides) so wallet-only npm installs audit clean despite Dynamic pinning zod@4.0.5; npm apps with their own Zod 3 deps can scope the override to Dynamic packages.

@sei-js/mcp-server raises dependency floors to @modelcontextprotocol/sdk ^1.32.0 and zod ^4.6.6, adds a workspace zod: 4.6.7 override in package.json / bun.lock, and hardens both HTTP transports with express.json({ inflate: false }) so encoded request bodies get 415 before vulnerable body-parser decompression (workaround when lockfiles still hold old body-parser). New transport tests assert gzip+trailing-bytes → 415 with /health still up; mcp-zod-lock now enforces the SDK 1.32 advisory floor.

@sei-js/create-sei changeset text only: generated apps still report Reown’s unpatchable Zod 3 finding alongside decode-uri-component.

Reviewed by Cursor Bugbot for commit 793cc0a. Bugbot is set up for automated code reviews on this repo. Configure here.

@codecov-commenter

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 96.53%. Comparing base (a61b860) to head (793cc0a).

Additional details and impacted files
@@           Coverage Diff           @@
##             main     #359   +/-   ##
=======================================
  Coverage   96.53%   96.53%           
=======================================
  Files          81       81           
  Lines        5563     5563           
=======================================
  Hits         5370     5370           
  Misses        193      193           
Flag Coverage Δ
mcp-server 95.15% <100.00%> (ø)
precompiles 99.85% <ø> (ø)
registry 100.00% <ø> (ø)
sei-global-wallet 100.00% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@seidroid seidroid Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

This is a tightly scoped advisory fix with patch changesets for each affected package. It raises the MCP SDK and zod floors, adds a root zod override, documents a consumer zod override, and turns off request-body inflation on both mcp-server HTTP transports, with tests that check for a 415. I found no correctness or security regressions; the wallet stdio-only guard and SSE session binding are untouched. The only notes are non-blocking.

Findings: 0 blocking | 5 non-blocking | 1 posted inline

Blockers

  • None at the file/PR level.

Non-blocking

  • The Cursor review pass produced no output (cursor-review.md was empty). Codex reported no material issues, and I agree.
  • Bun consumers who also install @reown/appkit-wallet have no scoped option. The README says Bun cannot scope overrides, so they are left with two choices: force Reown onto Zod 4, which it does not declare support for, or keep the zod finding. Consider saying so explicitly in the Bun block, rather than only in the npm-scoping sentence, so Bun users of wagmi/WalletConnect see the trade-off.
  • The inflate: false mitigation rests on the advisory's documented workaround, not on a local reproduction of the crash (the PR says so openly). The new tests confirm the 415 and that /health still responds, which is what this change can control. A short note in the mcp-server README about rejecting compressed request bodies could save HTTP-transport users some debugging, since this is a behavior change.
  • The root zod: 4.6.7 override is safe today because the lockfile previously held a single zod@4.0.5 with no Zod 3 copy in the workspace. If a workspace package ever adds a Zod 3 dependency, this override will silently move it to Zod 4. mcp-zod-lock partly guards this, so it is worth keeping in mind when the override is removed.
  • 1 suggestion(s)/nit(s) flagged inline on specific lines.

this.app = express();
this.app.use(express.json());
// No compressed request bodies: body-parser's decoder can crash the process (GHSA-27r3-jxmh-p828).
this.app.use(express.json({ inflate: false }));

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[nit] Looks correct: body-parser 1.x answers 415 for any non-identity Content-Encoding when inflate is false, before it creates a decompression stream. Requests whose content type isn't JSON skip express.json and reach the SDK transport, which reads the raw body without inflating it, so they get no decompression path either. Consider linking the advisory ID in the README or changelog alongside this comment so the behavior change is easy to find.

@alexander-sei
alexander-sei merged commit 8da8c09 into main Oct 23, 2026
15 checks passed
@seidroid seidroid Bot mentioned this pull request Oct 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants