Skip to content

Fix isPathWithinAllowedDirectories for UNC paths on Windows#3921

Open
Christian-Sidak wants to merge 1 commit intomodelcontextprotocol:mainfrom
Christian-Sidak:fix/unc-path-validation
Open

Fix isPathWithinAllowedDirectories for UNC paths on Windows#3921
Christian-Sidak wants to merge 1 commit intomodelcontextprotocol:mainfrom
Christian-Sidak:fix/unc-path-validation

Conversation

@Christian-Sidak
Copy link
Copy Markdown

Summary

Fixes #3756

On Windows, isPathWithinAllowedDirectories fails for UNC paths (e.g. \\192.168.1.1\share\) because path.normalize strips a leading backslash from UNC paths, and then path.resolve interprets the result as a drive-relative path (e.g. C:\server\share). This causes the allowed-directory check to always fail for network shares.

This PR introduces a normalizePossiblyUNCPath helper that detects UNC paths and preserves the \\ prefix through normalization, rather than passing them through path.resolve which corrupts them. Non-UNC paths continue to use the existing path.resolve(path.normalize(...)) logic.

Changes

  • Added isUNCPath() helper to detect UNC paths by their \\ prefix
  • Added normalizePossiblyUNCPath() that preserves the UNC prefix through path.normalize, restoring the stripped backslash when needed
  • Applied normalizePossiblyUNCPath() to both the input path and allowed directory normalization in isPathWithinAllowedDirectories

Test plan

  • All 53 existing tests pass (including the existing UNC path test case)
  • The existing UNC test at line 432 of path-validation.test.ts covers the core scenario: matching \\server\share\project against allowed directories, subdirectory access, and cross-server rejection
  • To reproduce the original bug: configure \\192.168.x.x\share\ as an allowed directory on Windows and attempt file access -- previously always denied, now correctly allowed

On Windows, path.normalize can strip a leading backslash from UNC paths
(\\server\share becomes \server\share). When path.resolve is then
called on this single-backslash path, it gets interpreted as drive-relative
(e.g. C:\server\share), causing the allowed-directory check to always
fail for UNC network paths.

This introduces normalizePossiblyUNCPath which detects UNC paths and
preserves the \\\\ prefix through normalization, rather than passing
them through path.resolve which corrupts them.

Fixes modelcontextprotocol#3756
Copy link
Copy Markdown
Member

@olaservo olaservo left a comment

Choose a reason for hiding this comment

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

Good approach — skipping path.resolve entirely for UNC paths is the right call since that's what causes the corruption. The normalizePossiblyUNCPath helper is clean and well-documented. Non-UNC paths are unaffected.

One request before we can merge: could you add test cases for UNC paths? PR #3920 has some good ones you could reference. They should be gated behind path.sep === '\' (like the existing UNC test at line 432) since UNC paths are meaningless on Linux. Something like:

  • UNC path within allowed UNC directory → true
  • UNC path outside allowed UNC directory → false
  • Exact UNC path match → true

This review was assisted by Claude Code.

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.

isPathWithinAllowedDirectories fails for UNC paths on Windows (network drives)

2 participants