[PR #203] [MERGED] fix: throw on missing middleware/proxy exports instead of failing open #384

Closed
opened 2026-05-06 12:39:32 +02:00 by BreizhHardware · 0 comments

📋 Pull Request Information

Original PR: https://github.com/cloudflare/vinext/pull/203
Author: @southpolesteve
Created: 2/28/2026
Status: Merged
Merged: 2/28/2026
Merged by: @southpolesteve

Base: mainHead: fix/middleware-export-validation


📝 Commits (4)

  • 50e54eb fix: throw on missing middleware/proxy exports instead of failing open
  • bb62ff5 fix: update export precedence test to match Next.js behavior (named > default)
  • df1c06b fix: use ?? instead of || in generated middleware export resolution for consistency
  • c0b47fd fix: update app-router test to match new export validation behavior

📊 Changes

7 files changed (+247 additions, -22 deletions)

View changed files

📝 AGENTS.md (+28 -4)
📝 packages/vinext/src/index.ts (+10 -3)
📝 packages/vinext/src/server/app-dev-server.ts (+14 -3)
📝 packages/vinext/src/server/middleware.ts (+49 -6)
📝 tests/app-router.test.ts (+5 -4)
📝 tests/pages-router.test.ts (+2 -2)
📝 tests/shims.test.ts (+139 -0)

📄 Description

Summary

Middleware and proxy files that don't export the expected function (e.g. misspelled export, wrong named export, no exports at all) were silently skipped, letting requests through unprotected. This is a security-relevant bug: if someone typos export function prooxy() in their auth middleware, requests bypass it entirely with no warning.

Next.js throws a ProxyMissingExportError in this scenario. This PR matches that behavior.

Changes

  • server/middleware.ts: Added isProxyFile() and resolveMiddlewareHandler() that validates exports based on file type, then throws if no valid export is found
  • index.ts (Pages Router prod): Updated generated code to check correct exports per file type and throw on mismatch (also fixes the missing proxy export check from #188)
  • server/app-dev-server.ts (App Router): Same validation in the generated RSC entry
  • tests/shims.test.ts: 14 new tests covering all valid/invalid export combinations for both proxy.ts and middleware.ts files
  • AGENTS.md: Added "Searching the Next.js Test Suite" as a required workflow step to prevent this class of bug in the future

Validation rules (matching Next.js)

File Accepted exports Rejects
proxy.ts proxy, default middleware, any other name, no export
middleware.ts middleware, default proxy, any other name, no export

Ported from Next.js

Tests ported from test/e2e/app-dir/proxy-missing-export/proxy-missing-export.test.ts.


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/cloudflare/vinext/pull/203 **Author:** [@southpolesteve](https://github.com/southpolesteve) **Created:** 2/28/2026 **Status:** ✅ Merged **Merged:** 2/28/2026 **Merged by:** [@southpolesteve](https://github.com/southpolesteve) **Base:** `main` ← **Head:** `fix/middleware-export-validation` --- ### 📝 Commits (4) - [`50e54eb`](https://github.com/cloudflare/vinext/commit/50e54ebcb5ff453f6bb988c892946ffcd0c61735) fix: throw on missing middleware/proxy exports instead of failing open - [`bb62ff5`](https://github.com/cloudflare/vinext/commit/bb62ff5e51b9e683f06a45918cdfb181337111e3) fix: update export precedence test to match Next.js behavior (named > default) - [`df1c06b`](https://github.com/cloudflare/vinext/commit/df1c06b6bc2421f1c171bc7155c7e77919041fba) fix: use ?? instead of || in generated middleware export resolution for consistency - [`c0b47fd`](https://github.com/cloudflare/vinext/commit/c0b47fdbe3ab038469b0ae2c80d9a3d49ce58ae2) fix: update app-router test to match new export validation behavior ### 📊 Changes **7 files changed** (+247 additions, -22 deletions) <details> <summary>View changed files</summary> 📝 `AGENTS.md` (+28 -4) 📝 `packages/vinext/src/index.ts` (+10 -3) 📝 `packages/vinext/src/server/app-dev-server.ts` (+14 -3) 📝 `packages/vinext/src/server/middleware.ts` (+49 -6) 📝 `tests/app-router.test.ts` (+5 -4) 📝 `tests/pages-router.test.ts` (+2 -2) 📝 `tests/shims.test.ts` (+139 -0) </details> ### 📄 Description ## Summary Middleware and proxy files that don't export the expected function (e.g. misspelled export, wrong named export, no exports at all) were silently skipped, letting requests through unprotected. This is a security-relevant bug: if someone typos `export function prooxy()` in their auth middleware, requests bypass it entirely with no warning. Next.js throws a `ProxyMissingExportError` in this scenario. This PR matches that behavior. ## Changes - **`server/middleware.ts`**: Added `isProxyFile()` and `resolveMiddlewareHandler()` that validates exports based on file type, then throws if no valid export is found - **`index.ts`** (Pages Router prod): Updated generated code to check correct exports per file type and throw on mismatch (also fixes the missing `proxy` export check from #188) - **`server/app-dev-server.ts`** (App Router): Same validation in the generated RSC entry - **`tests/shims.test.ts`**: 14 new tests covering all valid/invalid export combinations for both proxy.ts and middleware.ts files - **`AGENTS.md`**: Added "Searching the Next.js Test Suite" as a required workflow step to prevent this class of bug in the future ## Validation rules (matching Next.js) | File | Accepted exports | Rejects | |------|-----------------|---------| | `proxy.ts` | `proxy`, `default` | `middleware`, any other name, no export | | `middleware.ts` | `middleware`, `default` | `proxy`, any other name, no export | ## Ported from Next.js Tests ported from [`test/e2e/app-dir/proxy-missing-export/proxy-missing-export.test.ts`](https://github.com/vercel/next.js/blob/canary/test/e2e/app-dir/proxy-missing-export/proxy-missing-export.test.ts). --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
BreizhHardware 2026-05-06 12:39:32 +02:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/vinext#384
No description provided.