[PR #174] [MERGED] fix: block dangerous URI schemes in Link and Form components #369

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

📋 Pull Request Information

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

Base: mainHead: fix/block-dangerous-uri-schemes-in-link-form


📝 Commits (1)

  • 1194ab0 fix: block dangerous URI schemes in Link and Form components

📊 Changes

3 files changed (+61 additions, -0 deletions)

View changed files

📝 packages/vinext/src/shims/form.tsx (+31 -0)
📝 packages/vinext/src/shims/link.tsx (+13 -0)
packages/vinext/src/shims/url-safety.ts (+17 -0)

📄 Description

Summary

Validates URL schemes in the Link and Form component shims to match how Next.js handles these cases. Blocks javascript:, data:, and vbscript: URI schemes that should never appear in navigation targets.

Changes

New: url-safety.ts -- shared isDangerousScheme() utility with a single regex that handles evasion vectors (mixed case, leading whitespace, zero-width characters, whitespace before colon).

Link component (link.tsx)

  • Checks resolved href against isDangerousScheme() before rendering
  • Dangerous hrefs render an inert <a> without href (preserves className, id, aria-* for styling)
  • Warns in dev mode via console.warn

Form component (form.tsx)

  • New isSafeAction() validates string action URLs
  • Blocks dangerous URI schemes, protocol-relative URLs (//evil.com), and cross-origin absolute URLs
  • Unsafe forms render without action attribute (submits to current page)
  • Warns in dev mode

Based on the work by @kochrac in #142. This PR takes a different approach (validating at the component level rather than escaping in code generation) since the generated entries are Vite virtual modules, not inline HTML.

Supersedes #142


🔄 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/174 **Author:** [@southpolesteve](https://github.com/southpolesteve) **Created:** 2/27/2026 **Status:** ✅ Merged **Merged:** 2/27/2026 **Merged by:** [@southpolesteve](https://github.com/southpolesteve) **Base:** `main` ← **Head:** `fix/block-dangerous-uri-schemes-in-link-form` --- ### 📝 Commits (1) - [`1194ab0`](https://github.com/cloudflare/vinext/commit/1194ab06c7ecd2e28a8a5a073f63018d1acafb55) fix: block dangerous URI schemes in Link and Form components ### 📊 Changes **3 files changed** (+61 additions, -0 deletions) <details> <summary>View changed files</summary> 📝 `packages/vinext/src/shims/form.tsx` (+31 -0) 📝 `packages/vinext/src/shims/link.tsx` (+13 -0) ➕ `packages/vinext/src/shims/url-safety.ts` (+17 -0) </details> ### 📄 Description ## Summary Validates URL schemes in the `Link` and `Form` component shims to match how Next.js handles these cases. Blocks `javascript:`, `data:`, and `vbscript:` URI schemes that should never appear in navigation targets. ## Changes **New: `url-safety.ts`** -- shared `isDangerousScheme()` utility with a single regex that handles evasion vectors (mixed case, leading whitespace, zero-width characters, whitespace before colon). **Link component** (`link.tsx`) - Checks resolved href against `isDangerousScheme()` before rendering - Dangerous hrefs render an inert `<a>` without `href` (preserves className, id, aria-* for styling) - Warns in dev mode via `console.warn` **Form component** (`form.tsx`) - New `isSafeAction()` validates string action URLs - Blocks dangerous URI schemes, protocol-relative URLs (`//evil.com`), and cross-origin absolute URLs - Unsafe forms render without `action` attribute (submits to current page) - Warns in dev mode Based on the work by @kochrac in #142. This PR takes a different approach (validating at the component level rather than escaping in code generation) since the generated entries are Vite virtual modules, not inline HTML. Supersedes #142 --- <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:27 +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#369
No description provided.