Skip to content

fix(deps): raise the Next peer floor above the middleware-bypass advisories - #113

Merged
msalvatti merged 4 commits into
mainfrom
sec/next-peer-floor
Aug 2, 2026
Merged

fix(deps): raise the Next peer floor above the middleware-bypass advisories#113
msalvatti merged 4 commits into
mainfrom
sec/next-peer-floor

Conversation

@msalvatti

Copy link
Copy Markdown
Member

peerDependencies.next was ^16.2.10 — the exact version carrying eight open advisories fixed in 16.2.11, three of them high.

One is the reason this is not routine dependency hygiene:

Next.js: Middleware / Proxy bypass in App Router applications — crafted requests targeting apps built with Turbopack and a single config.i18n.locales entry can bypass middleware/proxy based authentication.

Workaround: enforce authorization in the page's server-side data path instead of relying solely on middleware.

The ./nextjs surface of this package is that middleware. A peer range admitting the vulnerable version hands the bypass to anyone who installs this and lets the resolver pick.

^16.2.11 is still a range — every later 16.x satisfies it — so nothing is pinned and nobody on a newer Next is held back. The dev dependency and both example apps move with it, so what CI builds is a version the peer range actually permits.

Verified against 16.2.12: npm ci, build:wasm, build, tsc --noEmit, lint, typedoc --emit none, the Vitest suite, and the nextjs example's production build — the last one compiles the middleware, which is the surface the advisory concerns.

The same floor is being raised in nest-auth (bymaxone/nest-auth#55), which ships the equivalent proxy.

Not included: postcss, sharp, esbuild and brace-expansion are build-time transitives pinned by their parents. None ship in the published dist/, and forcing them through an overrides block would mask a real incompatibility for no consumer-facing gain — they are Dependabot's to carry now that #112 has landed the grouping.

…sories

`peerDependencies.next` was `^16.2.10`, so a consumer could satisfy it with the
exact version carrying eight open advisories fixed in 16.2.11. Three are high,
and one of them is a middleware/proxy authentication bypass in App Router:
crafted requests against an app built with Turbopack and a single
`config.i18n.locales` entry skip middleware-based auth entirely.

That one is not a generic dependency issue for this package. The `./nextjs`
surface IS middleware — the proxy is the authorization boundary a consumer
installs it for — and the advisory's own workaround says not to rely on
middleware alone. A peer range that admits the vulnerable version hands that
bypass to anyone who installs this library and takes the resolver's default.

The floor is a range, not a pin: `^16.2.11` accepts every later 16.x, so nobody
already on a newer Next is affected or held back. The dev dependency and the two
example apps move with it so what is built and tested is a version the peer
range permits.

Verified against 16.2.12: install, wasm, bundle, `tsc`, lint, TypeDoc, the
Vitest suite, and the `nextjs` example's production build — which compiles the
middleware, the surface the advisory is about.

The remaining alerts on this repo (`postcss`, `sharp`, `esbuild`,
`brace-expansion`) are build-time transitives pinned by their parents; none ship
in the published `dist/`, and they are Dependabot's to carry rather than
something to force with an `overrides` block.
Copilot AI review requested due to automatic review settings August 2, 2026 13:54
@socket-security

socket-security Bot commented Aug 2, 2026

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Updatednpm/​next@​16.2.9 ⏵ 16.2.1264100 +4090 +19970
Addednpm/​react@​19.2.81001008497100
Addednpm/​react-dom@​19.2.81001009298100

View full report

Copilot AI 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.

Pull request overview

Raises the package’s Next.js peer/dev dependency floor to avoid admitting vulnerable Next versions (notably the middleware/proxy bypass advisories) and keeps the tested install set aligned with the declared peer range.

Changes:

  • Bump peerDependencies.next (and dev next) from ^16.2.10 to ^16.2.11 in @bymax-one/rust-auth.
  • Update lockfiles to resolve the newer Next toolchain (now resolving to next@16.2.12).
  • Raise Next dependency floors in the smoke-npm and nextjs examples to match the new peer floor.

Reviewed changes

Copilot reviewed 3 out of 6 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
packages/rust-auth/package.json Raises Next peer/dev floor to ^16.2.11.
packages/rust-auth/package-lock.json Updates resolved Next-related packages to the newer versions.
examples/smoke-npm/package.json Raises example’s Next dependency floor to ^16.2.11.
examples/smoke-npm/package-lock.json Updates resolved Next-related packages for the example install set.
examples/nextjs/package.json Raises example’s Next dependency floor to ^16.2.11.
examples/nextjs/package-lock.json Updates resolved Next-related packages for the example install set.
Files not reviewed (3)
  • examples/nextjs/package-lock.json: Generated file
  • examples/smoke-npm/package-lock.json: Generated file
  • packages/rust-auth/package-lock.json: Generated file

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread packages/rust-auth/package.json
Comment thread packages/rust-auth/package.json Outdated
…e peer range

Takes the react half of the grouped bump #114 opened, and leaves out the part
that would cost consumers something. Dependabot raises the peer range alongside
the dev dependency, which would have moved `peerDependencies.react` from
`^19.0.0` to `^19.2.8` — every consumer on an earlier 19.x forced to upgrade for
no reason. A peer range states what the library SUPPORTS, not what it was last
tested against, and nothing here stops working on react 19.0.

`next` is the opposite case and keeps its raised floor: there the range is what
decides whether a consumer can end up on a version carrying the middleware
bypass.

Verified under react 19.2.8 and next 16.2.12: install, bundle, `tsc`, lint, the
Vitest suite, and the `react-vite` example's production build.

Copilot AI 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.

Pull request overview

Copilot reviewed 3 out of 6 changed files in this pull request and generated no new comments.

Files not reviewed (3)
  • examples/nextjs/package-lock.json: Generated file
  • examples/smoke-npm/package-lock.json: Generated file
  • packages/rust-auth/package-lock.json: Generated file
Suppressed comments (2)

examples/nextjs/package-lock.json:43

  • In this example app's lockfile, the linked ../../packages/rust-auth package snapshot lists react/react-dom devDependency ranges as ^19.0.0, but packages/rust-auth/package.json now declares ^19.2.8. This mismatch can cause noisy lockfile churn on the next install; update the lockfile snapshot to match the source package.json (or regenerate the lockfile).
    examples/smoke-npm/package-lock.json:43
  • In this example app's lockfile, the linked ../../packages/rust-auth package snapshot lists react/react-dom devDependency ranges as ^19.0.0, but packages/rust-auth/package.json now declares ^19.2.8. This mismatch can cause noisy lockfile churn on the next install; update the lockfile snapshot to match the source package.json (or regenerate the lockfile).

… package by path

Next 16.2.11 gave `NextURL` a `[Internal]` property keyed by a unique symbol.
TypeScript treats a unique symbol as distinct per declaration file, so two
INSTALLS of Next — even at the identical version — stopped being assignable to
one another:

    Property '[Internal]' is missing in type
      examples/nextjs/node_modules/next/.../NextURL
    but required in type
      packages/rust-auth/node_modules/next/.../NextURL

The examples consume the package as `file:../../packages/rust-auth`, so the
package's own dev dependency on Next sits beside the example's, and the built
`.d.ts` resolves `NextRequest` from a different copy than the route handler
does. `next build` then rejects a handler this package exported.

A consumer never sees this: Next is a peer dependency, so a registry install
leaves exactly one copy and both sides resolve to it. The duplicate is an
artifact of the local-path harness, and mapping `next` to the example's own copy
is what makes the example's tree resemble the tree a consumer actually gets —
which is the only tree the example is evidence about.

Found because the peer floor moved to 16.2.11; the same trap is waiting for any
future Next bump, and it is now closed in both examples that consume the package
this way.

An earlier local run of this build passed and should not have: `.next` had a
cached type-check and the failure only appears after `rm -rf .next`. Verified
here from a clean state.
Copilot AI review requested due to automatic review settings August 2, 2026 14:08

Copilot AI 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.

Pull request overview

Copilot reviewed 5 out of 8 changed files in this pull request and generated 3 comments.

Files not reviewed (3)
  • examples/nextjs/package-lock.json: Generated file
  • examples/smoke-npm/package-lock.json: Generated file
  • packages/rust-auth/package-lock.json: Generated file

Comment thread packages/rust-auth/package-lock.json
Comment thread examples/nextjs/package-lock.json
Comment thread examples/smoke-npm/package-lock.json
`engines.node` said `>=18.0.0` while `peerDependencies.next` requires Node
20.9.0 or newer. The package therefore promised a floor at which its own
declared peer set cannot be installed — a contributor or a consumer reading
`engines` would be told Node 18 works, and find out otherwise from a resolver
error. Node 18 has been end-of-life since April 2025; CI has been on 24
throughout.

`examples/react-vite/package-lock.json` also still embedded the pre-bump peer
range for the linked package (`next: ^16.2.10`), because it was installed with
`npm ci` — which reads the lockfile rather than rewriting it — after the peer
range moved. The other two example lockfiles had been regenerated and were
already current.

Verified from a clean state after both: install, bundle, `tsc`, the Vitest
suite, and the `react-vite` and `nextjs` production builds.
Copilot AI review requested due to automatic review settings August 2, 2026 14:13

Copilot AI 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.

Pull request overview

Copilot reviewed 5 out of 9 changed files in this pull request and generated no new comments.

Files not reviewed (4)
  • examples/nextjs/package-lock.json: Generated file
  • examples/react-vite/package-lock.json: Generated file
  • examples/smoke-npm/package-lock.json: Generated file
  • packages/rust-auth/package-lock.json: Generated file
Suppressed comments (6)

examples/smoke-npm/package-lock.json:52

  • This example lockfile’s link entry for ../../packages/rust-auth still records engines.node as >=18.0.0, but packages/rust-auth/package.json now requires >=20.9.0. Regenerate the lockfile (or update this entry) so the recorded engine matches the linked package’s current package.json.
    examples/nextjs/package-lock.json:52
  • This example lockfile’s link entry for ../../packages/rust-auth still records engines.node as >=18.0.0, but packages/rust-auth/package.json now requires >=20.9.0. Regenerate the lockfile (or update this entry) so the recorded engine matches the linked package’s current package.json.
    packages/rust-auth/package-lock.json:36
  • packages/rust-auth/package.json raises the Node engine to >=20.9.0, but this lockfile still records the package's engines.node as >=18.0.0 in the root packages[""] entry. This makes the lock metadata inconsistent with the package being installed and can cause confusion/drift when validating runtime requirements. Update the lockfile entry (or regenerate the lockfile) so the engine floor matches package.json.
    examples/react-vite/package-lock.json:52
  • This example lockfile’s link entry for ../../packages/rust-auth still records engines.node as >=18.0.0, but packages/rust-auth/package.json now requires >=20.9.0. Regenerate the lockfile (or update this entry) so the recorded engine matches the linked package’s current package.json.
    examples/nextjs/package-lock.json:43
  • In the ../../packages/rust-auth link entry, the recorded devDependencies for react/react-dom are still ^19.0.0, but packages/rust-auth/package.json now has ^19.2.8. This indicates the lockfile wasn’t fully regenerated after the dependency bump and leaves stale metadata in the lock.

This issue also appears on line 50 of the same file.
examples/smoke-npm/package-lock.json:43

  • In the ../../packages/rust-auth link entry, the recorded devDependencies for react/react-dom are still ^19.0.0, but packages/rust-auth/package.json now has ^19.2.8. This indicates the lockfile wasn’t fully regenerated after the dependency bump and leaves stale metadata in the lock.

This issue also appears on line 50 of the same file.

@msalvatti
msalvatti merged commit 3219525 into main Aug 2, 2026
23 checks passed
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