Repository navigation
fix: move Node and Bun past the Brotli decoder advisory #357
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| --- | ||
| '@sei-js/create-sei': patch | ||
| --- | ||
|
|
||
| Require Bun 1.4.4 for generated applications, the first Bun release outside the Brotli decoder advisory `GHSA-9v8h-qqgm-4m35` (CVE-2026-111497). | ||
|
|
||
| Bun vendors Google's Brotli library for `node:zlib` and for decompressing `fetch` responses. The `1.3.14` the template pinned ships Brotli 1.1.0, and Bun 1.4.3 still ships 1.2.0, both inside the advisory's 1.0.3 through 1.2.0 range. Bun 1.4.4 ships Brotli 1.2.1, and there is no fixed 1.3.x release. | ||
|
|
||
| The template's `packageManager` moves from `bun@1.3.14` to `bun@1.4.4`, and the generated README and this package's README name 1.4.4 as the minimum. The release smoke now runs on Bun 1.4.4, so that is the version the template's overrides are validated with. | ||
|
|
||
| No published dependency or peer range changes. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| --- | ||
| '@sei-js/mcp-server': patch | ||
| --- | ||
|
|
||
| Raise the supported Node.js range to the releases that patch the Brotli decoder advisory `GHSA-9v8h-qqgm-4m35` (CVE-2026-111497). | ||
|
|
||
| **This drops support for Node.js 20, and for 22.x, 24.x, and 26.x releases before 22.23.4, 24.22.1, and 26.12.1.** npm only warns about the engine mismatch, but Yarn 1, and npm with `engine-strict` set, refuse to install this release on them. | ||
|
|
||
| Node.js bundles Google's Brotli library, and the decoder in Brotli 1.0.3 through 1.2.0 can be driven into an out-of-bounds write by a crafted compressed stream. Node fixed it in the [October 21, 2026 security releases](https://nodejs.org/en/blog/vulnerability/october-2026-security-releases): 22.23.4, 24.22.1, and 26.12.1. Node 20 is end-of-life and gets no fix. | ||
|
|
||
| The server reaches that decoder through `fetch`, which decompresses Brotli-encoded responses automatically: viem's HTTP transport for the configured RPC endpoints, and the docs client for `https://docs.sei.io/mcp`. Its own HTTP transports do not, because Express 4's body parser only inflates gzip and deflate request bodies and rejects `Content-Encoding: br` with a 415. | ||
|
|
||
| `engines.node` moves from `>=20.0.0` to `^22.23.4 || ^24.22.1 || >=26.12.1`, and the README's requirement matches. | ||
|
|
||
| No dependency or peer range changes. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1 +1 @@ | ||
| 24 | ||
| 24.22.1 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -46,5 +46,5 @@ | |
| "publint": "0.3.23", | ||
| "typescript": "^5.8.2" | ||
| }, | ||
| "packageManager": "bun@1.3.14" | ||
| "packageManager": "bun@1.4.4" | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -51,5 +51,5 @@ | |
| "uuid": "11.1.1", | ||
| "ws": "8.21.3" | ||
| }, | ||
| "packageManager": "bun@1.3.14" | ||
| "packageManager": "bun@1.4.4" | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -387,7 +387,12 @@ describe('StreamableHttpTransport', () => { | |
| }).catch(() => undefined); | ||
| await withTimeout(started, 'request startup'); | ||
|
|
||
| await expect(transport.stop()).rejects.toBeInstanceOf(AggregateError); | ||
| // Under Bun 1.4, `expect(...).rejects` never settles a stop() that has to close a live request. | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [nit] The workaround is sound: if |
||
| const stopError = await transport.stop().then( | ||
| () => undefined, | ||
| (error: unknown) => error | ||
| ); | ||
| expect(stopError).toBeInstanceOf(AggregateError); | ||
| expect(requestTransport.close).toHaveBeenCalledTimes(1); | ||
| expect(requestServer.close).toHaveBeenCalledTimes(1); | ||
| await expect(transport.stop()).resolves.toBeUndefined(); | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -631,10 +631,14 @@ | |
| filename: bundlePath, | ||
| timeout: 10_000 | ||
| }); | ||
| assert.deepEqual(context.__edgeCheck, { | ||
| aliases: true, | ||
| entrypoints: true | ||
| }); | ||
| // The result object belongs to the vm realm, and a strict deep comparison rejects its foreign prototype. | ||
| assert.deepEqual( | ||
| { ...(context.__edgeCheck as Record<string, unknown>) }, | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [nit] The shallow spread works here because both values are primitives. If There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [nit] Spreading into a main-realm object still catches missing or extra own keys, and an |
||
| { | ||
| aliases: true, | ||
| entrypoints: true | ||
| } | ||
| ); | ||
| }; | ||
|
|
||
| /** | ||
|
|
@@ -651,7 +655,7 @@ | |
| }; | ||
|
|
||
| const assertAuditClean = (report: AuditReport, label: string) => { | ||
| assert.equal(report.metadata?.vulnerabilities?.total, 0, `${label} audit was not clean: ${describeAuditFindings(report).join('; ')}`); | ||
|
Check failure on line 658 in scripts/check-sei-global-wallet.ts
|
||
| }; | ||
|
|
||
| const assertWithinWaiver = (reported: readonly string[], accepted: readonly string[], label: string) => { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nit] This workaround is fine, and if
stop()resolves,stopErrorisundefinedandtoBeInstanceOfstill fails, so the assertion stays meaningful. Consider linking an upstream Bun issue in the comment so the workaround can be reverted to.rejectsonce Bun fixes it.