Skip to content

fix(security): validate supplemental interception selectors - #2976

Merged
james-elicx merged 4 commits into
mainfrom
codex/verify-interception-cache-identity
Aug 18, 2026
Merged

fix(security): validate supplemental interception selectors#2976
james-elicx merged 4 commits into
mainfrom
codex/verify-interception-cache-identity

Conversation

@james-elicx

@james-elicx james-elicx commented Aug 18, 2026

Copy link
Copy Markdown
Member

Summary

  • reject unknown X-Vinext-Interception-Id values before middleware, redirects, or other cacheable early responses
  • require graph-owned IDs to match the exact requested target and source context before page dispatch
  • canonicalize ID-bearing requests to an ID-inclusive _rsc URL before cacheable redirects
  • include verified IDs in origin ISR read, regeneration, and write keys so valid supplemental refreshes remain cacheable
  • force only rejected selector responses to no-store; preserve cache policy for valid selector responses
  • express invalid-selector cache policy through the configured CDN adapter without provider header coupling in vinext core
  • preserve context-only interception compatibility and valid supplemental refreshes from fix(router): refresh retained parallel routes #2880

Security impact

Previously arbitrary interception:* values could add an unbounded cache dimension, early responders could escape exact verification, rollout hashes could collapse different selectors onto one URL key, and origin ISR keys did not include the selector. Unknown or mismatched selectors are now rejected, while graph-owned selectors are isolated by both the canonical URL hash and origin ISR key.

Next.js / Cloudflare reference

Next.js gates generated interception rewrites with Next-Url, emits it in Vary for interception responses, and validates the header-derived _rsc URL hash because CDNs may ignore Vary. X-Vinext-Interception-Id is vinext-specific because supplemental refreshes fan out retained branches; vinext applies the same URL-key principle and additionally validates the ID against its generated route graph.

Validation

  • focused handler, cache-busting, route-matching, page-dispatch, ISR, cache, render, adapter, and codegen suites — 581 passed
  • App Router E2E interception coverage — 37 passed, 1 existing skip
  • full vp check
  • vp run vinext#build
  • independent cumulative review and re-review — no findings

@james-elicx

Copy link
Copy Markdown
Member Author

/bigbonk review for issues

@james-elicx james-elicx changed the title fix(security): verify interception cache identities fix(security): validate supplemental interception selectors Aug 18, 2026
@ask-bonk

ask-bonk Bot commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

github run

@ask-bonk

ask-bonk Bot commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

@james-elicx Bonk workflow failed. Check the logs for details.

View workflow run · To retry, trigger Bonk again.

@pkg-pr-new

pkg-pr-new Bot commented Aug 18, 2026

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/@vinext/cloudflare@2976
npm i https://pkg.pr.new/create-vinext-app@2976
npm i https://pkg.pr.new/@vinext/types@2976
npm i https://pkg.pr.new/vinext@2976

commit: caaa3a4

@github-actions

Copy link
Copy Markdown
Contributor
Example Preview Production Original
app-router-cloudflare preview production
pages-router-cloudflare preview production
app-router-playground preview production original
realworld-api-rest preview production
nextra-docs-template preview production
benchmarks preview production
hackernews preview production original
workers-cache preview production
web preview production

@github-actions

github-actions Bot commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

Performance benchmarks

Compared caaa3a4 against base fbf77b1 using alternating same-runner rounds. Next.js was unchanged and skipped.

0 improved · 0 regressed · 6 within ±1.5%

Scenario Framework Baseline Current Change
Client bundle size (gzip) vinext 140.3 KB 140.3 KB ⚫ +0.0%
Client entry size (gzip) vinext 127.7 KB 127.7 KB ⚫ +0.0%
Dev server cold start vinext 3.18 s 3.14 s ⚫ -1.2%
Production build time vinext 3.53 s 3.57 s ⚫ +1.1%
RSC entry closure size (gzip) vinext 115.2 KB 115.4 KB ⚫ +0.2%
Server bundle size (gzip) vinext 196.2 KB 196.6 KB ⚫ +0.2%

View detailed results and traces

🟢 improvement · 🔴 regression · ⚫ change below 1.5% · paired base/head

@james-elicx

Copy link
Copy Markdown
Member Author

/bigbonk review for issues

@ask-bonk

ask-bonk Bot commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

github run

@james-elicx

Copy link
Copy Markdown
Member Author

/bigbonk review for issues

@ask-bonk

ask-bonk Bot commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

github run

@james-elicx

Copy link
Copy Markdown
Member Author

/bigbonk review for issues

@ask-bonk

ask-bonk Bot commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

github run

@james-elicx

Copy link
Copy Markdown
Member Author

/bigbonk review for issues

@ask-bonk

ask-bonk Bot commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

github run

@james-elicx
james-elicx merged commit 5eb21da into main Aug 18, 2026
70 checks passed
@james-elicx
james-elicx deleted the codex/verify-interception-cache-identity branch August 18, 2026 09:48
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.

1 participant