fix(transfer): reject Windows drive prefixes from untrusted senders + audit#3496
Merged
Conversation
… audit
On Windows, `Path::has_root()` returns false for drive-relative paths
such as `C:foo`, but `dest_dir.join("C:foo")` discards `dest_dir`
(Path::join semantics for prefixed inputs), letting a malicious sender
escape the destination tree. The receiver's sanitize_file_list now
rejects any path whose first component is `Component::Prefix(_)` on
Windows. Adds two unit tests for the trusted/untrusted paths.
Also catalogs Windows path-handling hazards beyond the wire-encoding
work (drive prefixes, UNC, `\\?\`, canonicalize round-trips, reparse
points, long paths, reserved names) in `docs/audits/windows-path-edge-cases.md`.
3 tasks
oferchen
added a commit
that referenced
this pull request
May 5, 2026
… audit (#3496) On Windows, `Path::has_root()` returns false for drive-relative paths such as `C:foo`, but `dest_dir.join("C:foo")` discards `dest_dir` (Path::join semantics for prefixed inputs), letting a malicious sender escape the destination tree. The receiver's sanitize_file_list now rejects any path whose first component is `Component::Prefix(_)` on Windows. Adds two unit tests for the trusted/untrusted paths. Also catalogs Windows path-handling hazards beyond the wire-encoding work (drive prefixes, UNC, `\\?\`, canonicalize round-trips, reparse points, long paths, reserved names) in `docs/audits/windows-path-edge-cases.md`.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
windows-path-normalization.mdandwindows-path.mdaudits: drive-relative paths, UNC,\\?\round-trips,Path::canonicalizesemantics, reparse points / junctions, long paths, and reserved names. Each hazard is mapped to current oc-rsync code and test coverage in a new audit atdocs/audits/windows-path-edge-cases.md.Path::has_root()returns false for drive-relative paths such asC:foo, butdest_dir.join("C:foo")discardsdest_direntirely (Path::joinsemantics). An untrusted sender could therefore emit a wire path with a drive letter, UNC prefix, or\\?\extended prefix to escape the destination tree. The receiver'ssanitize_file_listnow rejects any path whose first component isComponent::Prefix(_)on Windows.crates/transfer/src/receiver/tests.rscovering both the trusted and untrusted code paths.The fix is
#[cfg(windows)]-gated, lives in a single function, and does not touch wire protocol or shared logic. Behaviour on Linux and macOS is unchanged.No matching tracking issue was found in
gh issue listfor "windows path", "path normalization", or "windows in:title path".Test plan
#[cfg(windows)]testswindows_drive_relative_path_rejected_when_untrustedandwindows_drive_relative_path_allowed_when_trusted.#[cfg(windows)].