Skip to content

Enhance path normalization to support Windows file paths in createHtt…#1527

Closed
guitavano wants to merge 1 commit intomainfrom
tavano/add-win-32
Closed

Enhance path normalization to support Windows file paths in createHtt…#1527
guitavano wants to merge 1 commit intomainfrom
tavano/add-win-32

Conversation

@guitavano
Copy link
Contributor

@guitavano guitavano commented Feb 10, 2026

Summary by cubic

Extend path normalization in createHttpClient to also check Windows-style paths (node:path/win32). This closes a gap in path traversal detection on Windows and keeps behavior consistent across platforms.

Written for commit 9b1ddcd. Summary will update on new commits.

Summary by CodeRabbit

  • Bug Fixes
    • Enhanced path validation to check both POSIX and Windows path formats for improved cross-platform file system compatibility.

@github-actions
Copy link
Contributor

Tagging Options

Should a new tag be published when this PR is merged?

  • 👍 for Patch 0.134.1 update
  • 🎉 for Minor 0.135.0 update
  • 🚀 for Major 1.0.0 update

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 10, 2026

📝 Walkthrough

Walkthrough

Security enhancement to path traversal guard in utils/http.ts that adds Windows path normalization checking. The existing POSIX normalization validation is expanded to also validate the Win32-normalized form of paths, preventing path traversal attacks via different path normalization schemes.

Changes

Cohort / File(s) Summary
Path Traversal Security Enhancement
utils/http.ts
Added Windows path normalization validation alongside existing POSIX normalization check. Imported normalize as normalizeWin32 from node:path/win32 and expanded the path traversal guard to reject paths where either POSIX or Win32 normalized forms differ from the compiled path.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

Poem

🐰 A rabbit hops through paths so neat,
Windows or POSIX, no sneaky beat!
Normalized thrice, we guard with care,
No traversal tricks will get us there! 🛡️

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Description check ⚠️ Warning The description lacks required sections from the template (Issue Link, Loom Video, Demonstration Link) and appears to be auto-generated by a tool rather than authored by the contributor. Add required template sections including Issue Link, Loom Video, and Demonstration Link. Replace or supplement auto-generated content with a proper contributor description.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: enhancing path normalization to support Windows file paths in the createHttpClient function.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch tavano/add-win-32

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 1 file

Prompt for AI agents (all issues)

Check if these issues are valid — if so, understand the root cause of each and fix them.


<file name="utils/http.ts">

<violation number="1" location="utils/http.ts:202">
P0: Critical bug: `path.win32.normalize()` converts `/` to `\`, so `normalizeWin32(compiled) !== compiled` is **always true** for any path containing a `/`. This breaks every multi-segment HTTP client request with a spurious path traversal error.

To detect Windows-style path traversal (e.g. `..\\..\\etc\\passwd`), check for backslashes in the compiled path instead:</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

if (normalize(compiled) !== compiled) {
if (
normalize(compiled) !== compiled ||
normalizeWin32(compiled) !== compiled
Copy link

@cubic-dev-ai cubic-dev-ai bot Feb 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P0: Critical bug: path.win32.normalize() converts / to \, so normalizeWin32(compiled) !== compiled is always true for any path containing a /. This breaks every multi-segment HTTP client request with a spurious path traversal error.

To detect Windows-style path traversal (e.g. ..\\..\\etc\\passwd), check for backslashes in the compiled path instead:

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At utils/http.ts, line 202:

<comment>Critical bug: `path.win32.normalize()` converts `/` to `\`, so `normalizeWin32(compiled) !== compiled` is **always true** for any path containing a `/`. This breaks every multi-segment HTTP client request with a spurious path traversal error.

To detect Windows-style path traversal (e.g. `..\\..\\etc\\passwd`), check for backslashes in the compiled path instead:</comment>

<file context>
@@ -196,7 +197,10 @@ export const createHttpClient = <T>(
-        if (normalize(compiled) !== compiled) {
+        if (
+          normalize(compiled) !== compiled ||
+          normalizeWin32(compiled) !== compiled
+        ) {
           throw new Error(
</file context>
Fix with Cubic

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@utils/http.ts`:
- Around line 200-203: The check using normalizeWin32(compiled) is
false-positive because compiled is built with forward slashes (join("/")) so
normalizeWin32 converts them to backslashes and will never equal compiled; fix
by replacing the normalizeWin32(compiled) equality check with an explicit
Win32-traversal/backslash presence check on the POSIX-normalized path (e.g.
reject if compiled contains "\\" or sequences like "..\\" or ".\\") and remove
the node:path/win32 import, or if you prefer to keep normalizeWin32, first
convert compiled's slashes to backslashes (compiled.replace(/\//g,'\\')) before
calling normalizeWin32 and comparing; update the logic around
normalize(compiled), normalizeWin32, and compiled accordingly.

Comment on lines +200 to +203
if (
normalize(compiled) !== compiled ||
normalizeWin32(compiled) !== compiled
) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Critical: normalizeWin32 converts /\, breaking all multi-segment paths.

compiled is built by .join("/") on line 198, so it always uses forward slashes (e.g. "api/v1/users/123"). normalizeWin32 converts all forward slashes to backslashes, so normalizeWin32("api/v1/users/123") returns "api\\v1\\users\\123", which will never equal compiled. This means every request with more than one path segment will throw a path-traversal error.

Instead, you should only check for the presence of Win32 traversal sequences (..\\, .\\, or lone backslashes) in the already POSIX-normalized path:

🐛 Proposed fix
-        if (
-          normalize(compiled) !== compiled ||
-          normalizeWin32(compiled) !== compiled
-        ) {
+        if (
+          normalize(compiled) !== compiled ||
+          compiled.includes("\\")
+        ) {

This keeps the existing POSIX normalization check and additionally rejects any backslash in the path, which prevents Win32-style traversal (e.g. ..\\..\\etc\\passwd) without false-positiving on normal forward-slash paths. The node:path/win32 import can then be removed.

Alternatively, if you want to keep using normalizeWin32, you must first convert compiled to use backslashes before comparing:

-        if (
-          normalize(compiled) !== compiled ||
-          normalizeWin32(compiled) !== compiled
-        ) {
+        const compiledWin32 = compiled.replaceAll("/", "\\");
+        if (
+          normalize(compiled) !== compiled ||
+          normalizeWin32(compiledWin32) !== compiledWin32
+        ) {
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if (
normalize(compiled) !== compiled ||
normalizeWin32(compiled) !== compiled
) {
if (
normalize(compiled) !== compiled ||
compiled.includes("\\")
) {
🤖 Prompt for AI Agents
In `@utils/http.ts` around lines 200 - 203, The check using
normalizeWin32(compiled) is false-positive because compiled is built with
forward slashes (join("/")) so normalizeWin32 converts them to backslashes and
will never equal compiled; fix by replacing the normalizeWin32(compiled)
equality check with an explicit Win32-traversal/backslash presence check on the
POSIX-normalized path (e.g. reject if compiled contains "\\" or sequences like
"..\\" or ".\\") and remove the node:path/win32 import, or if you prefer to keep
normalizeWin32, first convert compiled's slashes to backslashes
(compiled.replace(/\//g,'\\')) before calling normalizeWin32 and comparing;
update the logic around normalize(compiled), normalizeWin32, and compiled
accordingly.

@guitavano guitavano closed this Feb 10, 2026
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