Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions .changeset/fix-create-sei-next-sharp-advisories.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
'@sei-js/create-sei': patch
---

Bump the Next template's `next` and `sharp` pins to clear three newly published advisories.

The generated-app smoke audits every variant and fails on any high or critical finding. Three advisories landed against the pinned versions, so the check went red without any change to the template:

- `GHSA-p293-qw3h-jr36` — critical, unauthenticated RCE on Windows-hosted Next.js servers, `>=13.4.0 <15.5.24`.
- `GHSA-2xp9-vwfh-vxw4` — critical, unauthenticated RCE in the Image Optimization API when AVIF files are used, `>=10.0.0 <15.5.24`.
- `GHSA-rgj7-g3m4-5g8c` — high, heap overflow in Sharp's bundled libheif decoder, `<0.35.4`.

`next` moves `15.5.21` to `15.5.25` and the `sharp` override `0.35.3` to `0.35.4`, both inside their pinned minors.

Next also widened its own Sharp declaration to `^0.34.3 || ^0.35.4`, so the pinned override now sits inside the range Next supports. The image notes in the template README and `next.config.mjs` said the opposite and are corrected: images stay unoptimized to avoid requiring a native Sharp build, which is a template choice rather than a security tradeoff. The `sharp` override itself still is one, and both notes now say so — the `0.34.x` half of Next's range remains inside the advisory, making `0.35.4` the floor rather than a free upgrade.

The remaining `decode-uri-component` finding is moderate and does not block the smoke.
21 changes: 21 additions & 0 deletions .changeset/fix-global-wallet-sharp-override.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
---
'@sei-js/sei-global-wallet': patch
---

Override the newly advised `sharp` pin, and waive the one optional-AA advisory that no override can reach.

Two advisories published against the existing dependency graph, so the nightly consumer run went red without any change in this repository.

`GHSA-rgj7-g3m4-5g8c` covers `sharp` below `0.35.4`, and `@dynamic-labs/iconic` pins `sharp@0.35.0` exactly. That is the same shape as the existing Axios and UUID pins: the vulnerable copy is reachable from `@dynamic-labs/global-wallet-client`, overrides are root-only in both npm and Bun, and this package cannot propagate them to an application. A plain install reported nine high findings, one root advisory cascading up the Dynamic chain to `@sei-js/sei-global-wallet` itself. The [Required consumer overrides](https://github.com/sei-protocol/sei-js/blob/main/packages/sei-global-wallet/README.md#required-consumer-overrides) blocks now carry `"sharp": "0.35.4"`, a patch-level move inside the pinned minor. The advisory is a heap overflow in the bundled libheif decoder, so it needs untrusted HEIF input to trigger and `sharp` is a build-time dependency of the icon package that never reaches a browser bundle, but it is high severity with a compatible fix available, so it is corrected rather than waived.

`GHSA-528h-pc64-c93x` covers every `stream-json` up to `3.4.0`, which the Solana RPC client's `jayson` requires as CommonJS on the optional AA path. It cannot be overridden: `3.5.0` onward is ESM-only under a moved `src/` layout, so pointing `jayson` at a fixed version replaces the advisory with a `MODULE_NOT_FOUND` on its own require, and every CommonJS version is inside the advisory. It is now an accepted advisory for the full npm consumer, alongside the Bun waiver that already existed for advisories with no compatible fix. The finding is an `O(depth²)` slowdown in filters that no wallet path feeds, and the wallet-only npm consumer is still held to a strictly clean audit with no waiver, so a default install is unaffected.

Several verifier gaps this exposed are closed as well.

The npm audits ran without allowing a non-zero exit, so any finding surfaced as a raw spawn error carrying the whole audit JSON rather than the assertion naming the consumer; they now fail with the offending package and advisory URL. Allowing that exit means the body has to be validated, because `npm audit` fails the same way when it cannot reach the registry: an `ENOAUDIT` payload carries no counts, so an unvalidated report would read as zero findings and turn an audit that never ran into a pass on the gate this check exists to enforce. Every npm audit result is now rejected unless it carries a real vulnerability count.

The "overrides still required" report and the Bun "overrides are taking effect" assertion are now derived from the override block instead of a hardcoded `axios`/`uuid` list, so a newly overridden package cannot be left out and let a partial upstream fix ask for the whole waiver to be dropped. The README override blocks are asserted against the sets the consumers install, so the three hand-maintained copies cannot document an override that is never tested.

The audit and override-parsing helpers moved into `scripts/consumer-audit.ts` and `scripts/documented-overrides.ts` with unit tests, so these cases are pinned by `bun test --isolate scripts` rather than only by a full consumer run.

No published dependency or peer range changes.
6 changes: 4 additions & 2 deletions packages/create-sei/templates/next-template/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,13 @@ bun run build

## Image handling

Next.js image optimization is disabled because Next 15.5.21 declares only vulnerable Sharp 0.34.x releases. The manifest resolves secure Sharp 0.35.x for audit safety, while images are served unoptimized until Next.js supports that Sharp line.
Next.js image optimization is disabled so the generated app needs no native Sharp build. Turning it on is a template choice rather than a security tradeoff.

The manifest's `sharp` override is a separate matter and has to stay. The pinned Next 15 line declares Sharp `^0.34.3 || ^0.35.4`, and the `0.34.x` half of that range is still inside [GHSA-rgj7-g3m4-5g8c](https://github.com/advisories/GHSA-rgj7-g3m4-5g8c), so `0.35.4` is the advisory floor. Loosening or removing the override reintroduces a high audit finding whether or not optimization is enabled.

## Development bundler

`bun run dev` uses the Next 15 webpack default. Do not add `--turbopack`: Next 15.5.21 cannot express the required `false` alias for MetaMask SDK's mobile-only storage import in Turbopack without adding a synthetic replacement module. The production build and smoke use the validated webpack alias in `next.config.mjs`.
`bun run dev` uses the Next 15 webpack default. Do not add `--turbopack`: the pinned Next 15 line cannot express the required `false` alias for MetaMask SDK's mobile-only storage import in Turbopack without adding a synthetic replacement module. The production build and smoke use the validated webpack alias in `next.config.mjs`.

## Sei brand

Expand Down
7 changes: 5 additions & 2 deletions packages/create-sei/templates/next-template/next.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,11 @@ const nextConfig = {
ignoreDuringBuilds: true,
},
images: {
// Next 15.5.21 declares vulnerable Sharp 0.34.x. Keep the secure 0.35.x
// override for resolution, but do not rely on its unsupported optimizer API.
// Images stay unoptimized so the generated app needs no native Sharp
// build. Keep the manifest's Sharp override: Next declares
// `^0.34.3 || ^0.35.4`, and the 0.34.x half is still inside
// GHSA-rgj7-g3m4-5g8c, so 0.35.4 is the advisory floor. Loosening that
// pin reintroduces a high finding even though this flag is off.
unoptimized: true,
},
webpack: (config) => {
Expand Down
4 changes: 2 additions & 2 deletions packages/create-sei/templates/next-template/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
"@tailwindcss/postcss": "4.3.3",
"@tanstack/react-query": "5.85.3",
"ethers": "6.17.0",
"next": "15.5.21",
"next": "15.5.25",
"pino-pretty": "13.1.3",
"postcss": "8.5.26",
"react": "19.1.2",
Expand All @@ -46,7 +46,7 @@
"@metamask/sdk": "0.33.1",
"@metamask/sdk-communication-layer": "0.33.1",
"postcss": "8.5.26",
"sharp": "0.35.3",
"sharp": "0.35.4",
"use-sync-external-store": "1.6.0",
"uuid": "11.1.1",
"ws": "8.21.3"
Expand Down
22 changes: 15 additions & 7 deletions packages/sei-global-wallet/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
</div>

> [!WARNING]
> **Temporary consumer security waiver:** Dynamic Global Wallet Client transitively pins vulnerable `axios` and `uuid` as of 4.96.3, the current floor.
> **Temporary consumer security waiver:** Dynamic Global Wallet Client transitively pins vulnerable `axios`, `sharp`, and `uuid` as of 4.96.3, the current floor.
> Dependency overrides are root-only in both npm and Bun; this package cannot propagate them to your application. Add the overrides below before installing, and drop them once your install resolves a Dynamic release that corrects those pins.

## Required consumer overrides
Expand All @@ -26,6 +26,7 @@ Complete npm root overrides when the optional AA path is not enabled:
{
"overrides": {
"axios": "1.18.0",
"sharp": "0.35.4",
"uuid": "11.1.1",
"viem": {
"ws": "8.21.0"
Expand All @@ -39,14 +40,16 @@ Complete Bun root overrides. The block is the same with or without the optional
{
"overrides": {
"axios": "1.18.0",
"sharp": "0.35.4",
"uuid": "11.1.1"
}
}
```

The Axios and UUID overrides are temporary until Dynamic updates its exact transitive pins:
The Axios, Sharp, and UUID overrides are temporary until Dynamic updates its exact transitive pins:

- The high-severity Axios issue is in the Node HTTP adapter and requires a prerequisite prototype-pollution/interceptor pattern. Browser wallet paths do not use that adapter, which reduces exploitability but does not make the vulnerable install acceptable.
- The high-severity Sharp issue is the bundled libheif heap overflow reported as `GHSA-rgj7-g3m4-5g8c`, reached through `@dynamic-labs/iconic`'s exact `sharp@0.35.0` pin. It is only triggered by decoding untrusted HEIF input, which no wallet path does, and `sharp` is a build-time image dependency that never reaches a browser bundle. The override is a patch-level move within `0.35.x`, so it carries no API change.
- The UUID issue affects the v3, v5, and v6 buffer APIs. Dynamic's observed call sites use UUID v4, which reduces exploitability but does not clear the audit finding.

Applications using the optional `./zerodev` / Dynamic account-abstraction path must also replace the vulnerable exact `bn.js@4.11.6` copies used by `ethjs-unit` and `number-to-bn`. The complete npm root override block is:
Expand All @@ -60,6 +63,7 @@ Applications using the optional `./zerodev` / Dynamic account-abstraction path m
"number-to-bn": {
"bn.js": "4.12.5"
},
"sharp": "0.35.4",
"uuid": "11.1.1",
"viem": {
"ws": "8.21.0"
Expand All @@ -70,17 +74,21 @@ Applications using the optional `./zerodev` / Dynamic account-abstraction path m

Bun 1.3.14 does not support nested overrides. Do **not** globally override `bn.js` or `ws`: Solana/borsh require bn5 while Jayson requires ws7. Bun's complete root override block is therefore the same with or without the optional AA path.

For npm, scoped `bn.js@4.12.5` stays on the legacy dependencies' expected major while Solana resolves `bn.js@5.2.5`. Scoped `ws@8.21.0` patches Viem's ws8 subtree while Jayson resolves `ws@7.5.13` from its `^7.5.10` range. The result is audit-clean.
For npm, scoped `bn.js@4.12.5` stays on the legacy dependencies' expected major while Solana resolves `bn.js@5.2.5`. Scoped `ws@8.21.0` patches Viem's ws8 subtree while Jayson resolves `ws@7.5.13` from its `^7.5.10` range. With the overrides above, a wallet-only npm install audits clean; the optional AA path carries the one `stream-json` advisory described below, on npm and Bun alike.

The verifier builds its browser consumer against `viem@2.45.3`, because the previously tested 2.55.19 pulls Ox Tempo's `node:worker_threads` path into Vite resolution while 2.45.3 predates it. That is a property of the verifier's own bundle, not a constraint on applications: the published `viem` peer range stays `^2.7.12`. If your bundler externalizes `node:worker_threads` on a newer Viem, configure it in your application rather than downgrading.

For Bun, scoped overrides are unavailable. The selected waiver therefore accepts exactly these unresolved optional-AA advisories while preserving compatible majors:
One advisory on the optional AA path has no fix any override can reach, on either package manager:

- `GHSA-528h-pc64-c93x` on `stream-json@1.9.1` — moderate, CVSS 6.2. Reached through the Solana RPC client's `jayson`, which requires `stream-json` as CommonJS. The advisory covers every version up to `3.4.0`, and `3.5.0` onward is ESM-only under a moved `src/` layout, so overriding it to a fixed version replaces the advisory with a `MODULE_NOT_FOUND` on `jayson`'s own require. The finding is an `O(depth²)` slowdown in the `pick`/`ignore`/`filter`/`replace` filters, reachable only by feeding crafted deeply nested JSON through them, which no wallet path does.

For Bun, scoped overrides are unavailable, so the waiver also accepts these advisories that npm resolves with the scoped blocks above, while preserving compatible majors:

- `GHSA-378v-28hj-76wf` on `bn.js@4.11.6` — moderate, CVSS 5.3.
- `GHSA-58qx-3vcg-4xpx` on Viem's `ws@8.18.3` — moderate, CVSS 4.4.
- `GHSA-96hv-2xvq-fx4p` on Viem's `ws@8.18.3` — high, CVSS 7.5.

Jayson remains on `ws@7.5.13`; globally forcing ws8 would violate that major contract. The verifier fails on any advisory outside this set, and reports rather than fails when one of them stops being reported, so an upstream fix or a withdrawn advisory never turns an unrelated pull request red.
Jayson remains on `ws@7.5.13`; globally forcing ws8 would violate that major contract. The verifier fails on any advisory outside each waiver, and reports rather than fails when one of them stops being reported, so an upstream fix or a withdrawn advisory never turns an unrelated pull request red. The wallet-only npm consumer is held to a strictly clean audit with no waiver at all, so nothing here excuses a finding that a default install would hand an application.

## Quick start

Expand Down Expand Up @@ -159,6 +167,6 @@ The pinned source includes its terminal newline and has SHA-256 `e288cd08b510afb

## Release verification

The dedicated `Sei Global Wallet Consumer Smoke` workflow runs on wallet-related paths for pull requests and for pushes to `main` (so the publishing commit is gated too), daily on a schedule to catch registry and advisory drift, and on demand with `workflow_dispatch`. It executes `bun run test:sei-global-wallet-release`, including an audit-clean scoped npm consumer, a waiver-aware Bun consumer, declarations that resolve with no optional peer installed, native and bundled edge-like SSR, real local ZeroDev provider operations in esbuild/Vite, dependency graphs, and package contents. Regular package tests remain deterministic and do not perform clean consumer installs.
The dedicated `Sei Global Wallet Consumer Smoke` workflow runs on wallet-related paths for pull requests and for pushes to `main` (so the publishing commit is gated too), daily on a schedule to catch registry and advisory drift, and on demand with `workflow_dispatch`. It executes `bun run test:sei-global-wallet-release`, including an audit-clean wallet-only npm consumer, waiver-aware full npm and Bun consumers, the override blocks documented above matching the sets it installs, declarations that resolve with no optional peer installed, native and bundled edge-like SSR, real local ZeroDev provider operations in esbuild/Vite, dependency graphs, and package contents. Regular package tests remain deterministic and do not perform clean consumer installs.

`SEI_GLOBAL_WALLET_FAST_CHECK=1` shortens the local loop by skipping the two clean npm consumers and the entire Bun consumer path, so a green run under that flag covers neither the audit waiver nor Bun. Release verification must run without it, which is what CI does.
`SEI_GLOBAL_WALLET_FAST_CHECK=1` shortens the local loop by skipping the two clean npm consumers and the entire Bun consumer path, so a green run under that flag covers neither the strictly clean wallet-only audit nor the Bun waiver. Release verification must run without it, which is what CI does.
Loading
Loading