GHSA-5fqc-mrg8-w798High· 8.6▾ TwilightDulwich: Symlink directory traversal in filter-branch index_filter via cross-commit state persistence
▾ Twilight zone — High severity, or a signal on a lesser flaw
impact 47.3 · likelihood 0 · exploitation 0
Need a working PoC? Pro members can cast a request and our team develops one — it lands right here.
Dulwich's filter_branch.py CommitFilter._apply_index_filter() is vulnerable to symlink directory traversal. When processing commit history, materialized tree entries (including symlinks) persist in the working directory between commits, allowing a symlink from an ancestor commit to redirect file writes from a descendant commit to arbitrary filesystem locations.
_apply_index_filter() at dulwich/filter_branch.py:212 calls build_index_from_tree(".", tmp_index_path, ...) which materializes all tree entries to the current working directory. The finally block (line 229-230) only cleans up the temporary index file (os.unlink(tmp_index_path)) — NOT the filesystem files written to CWD. When process_commit() processes parents recursively first (line 260), files materialized from ancestor commits persist and affect processing of descendant commits.
On dulwich 1.2.7, build_file_from_blob() has no symlink protection, and validate_path_element only validates name patterns, not filesystem state.
An attacker can craft a malicious repository where running filter_branch with an index filter writes attacker-controlled content to arbitrary filesystem locations via symlink traversal. This achieves RCE if the write targets .git/hooks/.
evil (mode 120000, symlink → /target_dir)evil/payload (mode 100644, attacker content)filter_branch with an index filterprocess_commit() processes ancestor first → materializes evil as symlink to /target_dir in CWDos.path.exists("./evil") → True (symlink exists). build_file_from_blob(blob, mode, "./evil/payload") → open("./evil/payload", "wb") follows intermediate symlink → writes to /target_dir/payloadClean the CWD between commit iterations in _apply_index_filter(), or verify that no intermediate path components are symlinks before writing files.
Reported by zx (Jace)
dulwich >= 0.23.1, <= 1.2.7Upgrade to a patched release:
dulwich 1.2.8Connected by shared product, vendor, weakness, or advisory.
GHSA-cm62-gvxx-vmxxHigh· 8.6Dulwich: Symlink directory traversal in stash pop allows arbitrary file write via intermediate directory symlinks
GHSA-8w8g-wq8h-fq33High· 8.6Dulwich: Symlink write-through in checkout(paths=[]) via raw os.open bypasses all symlink protections
GHSA-8mcx-5rqc-vhmfHigh· 8.8Dulwich: Arbitrary File Write (RCE) on Windows via Unvalidated Drive Letters in Tree Paths
CVE-2026-47712Low· 3.3Dulwich doesn't sanitize commit subjects in `porcelain.format_patch`
GHSA-35mr-4567-66vgMedium· 6.5Dulwich: Infinite Loop Denial of Service (DoS) in Packfile Object Resolution
CVE-2026-47734Medium· 5.7Dulwich has unbounded memory allocation in receive-pack from crafted thin packs