# Dulwich has an arbitrary file write via NTFS-hostile tree entries on Windows

Dulwich's NTFS path validator accepted backslash, colon and git~N tree entries, letting a malicious repo write files into .git/hooks on Windows and achieve RCE.

- Payout: Research
- Severity: high
- Program: Dulwich
- Found by: ctoth
- Disclosed: 2026-05-28
- CVE: CVE-2026-42305
- Write-up quality: 7/10
- Original: https://github.com/advisories/GHSA-897w-fcg9-f6xj
- Library page: https://bugbountylibrary.com/r/ghsa%3AGHSA-897w-fcg9-f6xj
- Tags: area:oss domain:oss impact:integrity impact:rce kind:research platform:ghsa sev:high tech:windows technique:incomplete-fix technique:parser-differential technique:source-review vuln:path-traversal vuln:rce

**Target:** Git client path validation (validate_path_element_ntfs) on Windows
**Root cause:** validate_path_element_ntfs only rejected literal git~1 and did not reject \, :, or other git~<digits> 8.3 aliases; additionally core.protectNTFS/protectHFS were read under wrong option names and protectNTFS defaulted true only on Windows.
**Steps:**
1. Craft a Git tree entry whose filename contains Windows structural syntax, e.g. `.git\hooks\pre-commit.exe`
2. Clone/fetch/checkout the malicious repo with Dulwich on Windows (CLI, porcelain.clone, or downstream tool)
3. Dulwich materializes the single entry as nested dirs `.git/hooks/pre-commit.exe`
4. Next `git commit` by victim executes the planted hook
5. Alternates: `.git::$INDEX_ALLOCATION` (ADS write into .git) or `git~2`/`GIT~1` 8.3 aliases to bypass .git check; `..\outside.txt` to escape work tree
**How found:** Reporter compared Dulwich's NTFS validator against Git upstream's is_ntfs_dotgit/verify_path and noticed only literal git~1 was blocked while other 8.3 aliases and Windows structural bytes passed; also found config keys read under wrong names so protectNTFS was silently ignored.
**Exploitation:** Attacker publishes a repo with a tree entry named `.git\hooks\pre-commit.exe`; victim clones on Windows with Dulwich, file lands in .git/hooks, and Git for Windows runs it on next commit, executing attacker code in victim context.
**Escalation:** File write into .git/hooks escalates to arbitrary code execution; `..\` variant escapes the work tree entirely.
**Insight:** When auditing cross-platform archive/checkout code, diff the validator against the canonical upstream (Git's is_ntfs_dotgit) and enumerate the full alias space (git~1..git~N, case variants) plus OS-structural bytes rather than the single known-bad string; also verify security config keys are actually read under their documented names.

