mirror of
https://github.com/cloudflare/vinext.git
synced 2026-05-09 08:25:34 +02:00
[PR #1056] [MERGED] fix: filter internal Next.js headers from inbound requests #1055
Labels
No labels
enhancement
enhancement
good first issue
help wanted
nextjs-tracking
nextjs-tracking
pull-request
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
starred/vinext#1055
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
📋 Pull Request Information
Original PR: https://github.com/cloudflare/vinext/pull/1056
Author: @NathanDrake2406
Created: 5/4/2026
Status: ✅ Merged
Merged: 5/5/2026
Merged by: @james-elicx
Base:
main← Head:fix/filter-internal-headers-security📝 Commits (8)
42adff7fix: filter internal Next.js headers from inbound requests31e22adfix: use safe Request rebuild instead of mutating headers directlyb8f0700fix: clone requests when filtering headers49aa54cfix: clone Requests safely across runtimes3b9e9b1fix: avoid type assertions in Request cf access980440bfix: move header filtering from handler body to entry boundaryc469a05fix: preserve x-vinext-mw-ctx when filtering internal headers in app-rsc-handler070d555fix: copy cf in both clone paths, add cloneRequestWithHeaders tests📊 Changes
7 files changed (+384 additions, -10 deletions)
View changed files
📝
packages/vinext/src/deploy.ts(+13 -1)📝
packages/vinext/src/index.ts(+14 -2)📝
packages/vinext/src/server/app-router-entry.ts(+13 -1)📝
packages/vinext/src/server/app-rsc-handler.ts(+22 -1)📝
packages/vinext/src/server/prod-server.ts(+14 -5)📝
packages/vinext/src/server/request-pipeline.ts(+101 -0)📝
tests/request-pipeline.test.ts(+207 -0)📄 Description
Summary
filterInternalHeaders()to strip internal Next.js headers from inbound requests at all entry points, matching Next.js behaviorx-nextjs-data,x-matched-path,x-now-route-matches,x-next-resume-state-length, andx-middleware-*headers to influence routing or impersonate internal stateProblem
Next.js calls
filterInternalHeaders()at the router-server entry point before any handler or middleware sees the request. This strips theINTERNAL_HEADERSlist from the request.vinext was not filtering any of these headers. All four headers reached middleware as user-controlled request headers.
Fix
Added
INTERNAL_HEADERSconstant andfilterInternalHeaders(headers: Headers)toserver/request-pipeline.ts, ported directly from Next.js. Wired into every request entry point:server/app-rsc-handler.tsserver/app-router-entry.tsserver/prod-server.ts(nodeToWebRequest + Pages path)index.tsdeploy.tsFiltering runs before middleware, config matching, and routing — no subsystem sees forged internal headers. The
x-middleware-*headers are stripped from requests but NOT from middleware responses — the middleware protocol (which readsx-middleware-*fromResponse.headers, notRequest.headers) continues to work correctly.Tests
Added 8 unit tests in
tests/request-pipeline.test.ts:INTERNAL_HEADERSx-middleware-rewrite+x-middleware-nextstrippedAll related tests pass (request-pipeline: 78, deploy: 210, app-router: 300, features: 267, pages-router: 200).
🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.