[PR #87] [MERGED] fix: resolve CodeQL security alerts (ReDoS, incomplete sanitization) #297

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

📋 Pull Request Information

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

Base: mainHead: fix/codeql-security-alerts


📝 Commits (1)

  • 60f28d2 fix: resolve CodeQL security alerts (ReDoS, incomplete sanitization, bad code gen)

📊 Changes

9 files changed (+295 additions, -98 deletions)

View changed files

📝 packages/vinext/src/config/config-matchers.ts (+117 -35)
📝 packages/vinext/src/index.ts (+62 -42)
📝 packages/vinext/src/server/middleware-codegen.ts (+13 -7)
📝 packages/vinext/src/server/middleware.ts (+21 -12)
📝 tests/e2e/app-router/isr.spec.ts (+7 -1)
📝 tests/font-google.test.ts (+1 -0)
📝 tests/rsc-streaming.test.ts (+1 -0)
📝 tests/safe-json.test.ts (+4 -1)
📝 tests/shims.test.ts (+69 -0)

📄 Description

Summary

Resolves all 26 open CodeQL code scanning alerts from https://github.com/cloudflare/vinext/security/code-scanning.

Production code fixes (3 files)

Single-pass tokenizers replace chained .replace() — CodeQL flagged chained string replacements as incomplete sanitization since later passes could re-process earlier outputs. Refactored to single-pass regex tokenizer loops in:

  • matchConfigPattern() in both config-matchers.ts and index.ts (alerts #25-28, #30-33, #50)
  • matchMiddlewarePattern() inlined in the prod server entry template (same pattern as alert #29)
  • matchPattern() in middleware.ts (alert #29)

New escapeHeaderSource() helper — shared single-pass converter for Next.js header/rewrite/redirect source patterns, used by matchHeaders() and applyHeaders(). Correctly handles :param(constraint) patterns (improvement over old code which silently dropped constraints).

Additional fixes:

  • decodeURIComponent parity: index.ts catch-all matcher now decodes percent-encoded values, matching config-matchers.ts behavior
  • Redundant dot in middleware tokenizer char class: [^/:..]+[^/:.]+
  • lgtm suppression + safety comment for JSON.stringify code gen (alert #35)

Test file suppressions (5 files)

Added lgtm[js/redos], lgtm[js/bad-tag-filter], and lgtm[js/incomplete-sanitization] comments for confirmed false positives:

  • Deliberate pathological regex in ReDoS guard tests
  • Script tag counting for XSS protection verification
  • Quote escaping in font test assertions

New tests

9 unit tests for escapeHeaderSource covering literal paths, dot escaping, named params, glob star, plus/question escaping, constrained params, alternation groups, standalone groups, and multiple groups.

Verification

  • pnpm run typecheck — clean
  • pnpm run lint — clean
  • pnpm vitest run — 731 tests pass across affected suites

🔄 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/87 **Author:** [@dknecht](https://github.com/dknecht) **Created:** 2/26/2026 **Status:** ✅ Merged **Merged:** 2/26/2026 **Merged by:** [@southpolesteve](https://github.com/southpolesteve) **Base:** `main` ← **Head:** `fix/codeql-security-alerts` --- ### 📝 Commits (1) - [`60f28d2`](https://github.com/cloudflare/vinext/commit/60f28d232997328e8982dd1ae7efd112d9294edd) fix: resolve CodeQL security alerts (ReDoS, incomplete sanitization, bad code gen) ### 📊 Changes **9 files changed** (+295 additions, -98 deletions) <details> <summary>View changed files</summary> 📝 `packages/vinext/src/config/config-matchers.ts` (+117 -35) 📝 `packages/vinext/src/index.ts` (+62 -42) 📝 `packages/vinext/src/server/middleware-codegen.ts` (+13 -7) 📝 `packages/vinext/src/server/middleware.ts` (+21 -12) 📝 `tests/e2e/app-router/isr.spec.ts` (+7 -1) 📝 `tests/font-google.test.ts` (+1 -0) 📝 `tests/rsc-streaming.test.ts` (+1 -0) 📝 `tests/safe-json.test.ts` (+4 -1) 📝 `tests/shims.test.ts` (+69 -0) </details> ### 📄 Description ## Summary Resolves all 26 open CodeQL code scanning alerts from https://github.com/cloudflare/vinext/security/code-scanning. ### Production code fixes (3 files) **Single-pass tokenizers replace chained `.replace()`** — CodeQL flagged chained string replacements as incomplete sanitization since later passes could re-process earlier outputs. Refactored to single-pass regex tokenizer loops in: - `matchConfigPattern()` in both `config-matchers.ts` and `index.ts` (alerts #25-28, #30-33, #50) - `matchMiddlewarePattern()` inlined in the prod server entry template (same pattern as alert #29) - `matchPattern()` in `middleware.ts` (alert #29) **New `escapeHeaderSource()` helper** — shared single-pass converter for Next.js header/rewrite/redirect source patterns, used by `matchHeaders()` and `applyHeaders()`. Correctly handles `:param(constraint)` patterns (improvement over old code which silently dropped constraints). **Additional fixes:** - `decodeURIComponent` parity: `index.ts` catch-all matcher now decodes percent-encoded values, matching `config-matchers.ts` behavior - Redundant dot in middleware tokenizer char class: `[^/:..]+` → `[^/:.]+` - `lgtm` suppression + safety comment for `JSON.stringify` code gen (alert #35) ### Test file suppressions (5 files) Added `lgtm[js/redos]`, `lgtm[js/bad-tag-filter]`, and `lgtm[js/incomplete-sanitization]` comments for confirmed false positives: - Deliberate pathological regex in ReDoS guard tests - Script tag counting for XSS protection verification - Quote escaping in font test assertions ### New tests 9 unit tests for `escapeHeaderSource` covering literal paths, dot escaping, named params, glob star, plus/question escaping, constrained params, alternation groups, standalone groups, and multiple groups. ### Verification - `pnpm run typecheck` — clean - `pnpm run lint` — clean - `pnpm vitest run` — 731 tests pass across affected suites --- <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:02 +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#297
No description provided.