CVE-2026-47712 Overview
CVE-2026-47712 is a path traversal vulnerability [CWE-22] in Dulwich, a pure-Python implementation of Git file formats and protocols. The flaw exists in dulwich.porcelain.format_patch when an outdir argument is supplied. The get_summary helper used to derive patch filenames only replaced spaces with dashes, leaving path separators (/, \), parent-directory components (..), and other filename-hostile characters intact. A crafted commit subject passes those characters directly into os.path.join(outdir, f"{i:04d}-{summary}.patch"), allowing the generated patch file to be written outside the requested output directory. The issue affects Dulwich versions 0.24.0 through 1.2.4 and is fixed in 1.2.5.
Critical Impact
A malicious commit subject can steer format_patch to write patch files outside the caller's chosen output directory, enabling local file write in unintended locations.
Affected Products
- Dulwich >= 0.24.0 and < 1.2.5
- Python applications that call dulwich.porcelain.format_patch with an outdir argument on untrusted commits
- Downstream tooling that consumes patches generated by Dulwich from third-party repositories
Discovery Timeline
- 2026-06-10 - CVE-2026-47712 published to NVD
- 2026-06-10 - Last updated in NVD database
Technical Details for CVE-2026-47712
Vulnerability Analysis
The vulnerability is a classic path traversal [CWE-22] driven by insufficient sanitization of attacker-controlled input used to construct a filename. dulwich.porcelain.format_patch produces one .patch file per commit, naming each output after the commit's subject line. Because the subject is fully attacker-controlled by anyone who can author a commit, embedding ../ segments or absolute-path fragments redirects the write to an arbitrary location reachable by the calling process. Exploitation requires the target to invoke format_patch on the malicious commit and write to a local destination, which scopes impact to integrity of files reachable by the caller's privileges.
Root Cause
Before the fix, get_summary only normalized whitespace and preserved characters that are unsafe in filenames. The returned string was concatenated into the output path via os.path.join, which treats absolute paths and parent-directory traversal segments according to OS semantics. As a result, a subject such as x/../../x collapses path components and escapes outdir.
Attack Vector
An attacker authors a commit whose subject line contains path separators or .. segments, then convinces a victim to run dulwich.porcelain.format_patch(outdir=...) over that commit. The patch file is written to the traversed path, potentially overwriting files or planting content under directories the caller did not intend to touch.
# Security patch in dulwich/patch.py (Dulwich 1.2.5)
# Source: https://github.com/jelmer/dulwich/commit/c2446e51b
def _sanitize_subject_for_filename(text: str, max_length: int = 52) -> str:
"""Sanitize a string for safe use as part of a filename.
Matches git's ``format_sanitized_subject`` behavior:
- Only ``[A-Za-z0-9._]`` are kept; other characters become ``-``
(collapsed across runs).
- Consecutive ``.`` are collapsed to a single ``.``.
- The result is truncated to ``max_length`` characters.
- Trailing ``.`` and ``-`` are stripped.
"""
result: list[str] = []
# 2 = initial, 1 = saw a non-title char, 0 = saw a title char
space = 2
i = 0
text_len = len(text)
while i < text_len:
c = text[i]
if ("A" <= c <= "Z") or ("a" <= c <= "z") or ("0" <= c <= "9") or c in "._":
if space == 1:
result.append("-")
Source: GitHub Commit c2446e51b
Detection Methods for CVE-2026-47712
Indicators of Compromise
- Unexpected .patch files written outside the directory passed as outdir to dulwich.porcelain.format_patch.
- Commits in fetched repositories whose subject's first line contains /, \, .., or : characters.
- Process telemetry showing Python interpreters writing files to paths that resolve outside the working tree of a Dulwich-driven workflow.
Detection Strategies
- Audit application code for calls to dulwich.porcelain.format_patch and verify the installed Dulwich version is >= 1.2.5.
- Add logging around format_patch invocations to capture the returned path and the original outdir, and alert when os.path.realpath(returned_path) is not a child of os.path.realpath(outdir).
- Static analysis to flag use of commit subject strings as components of filesystem paths without sanitization.
Monitoring Recommendations
- Monitor build and CI systems that consume third-party Git history for file writes outside expected artifact directories.
- Track installed Python dependency versions in software inventory and flag any pinned Dulwich release below 1.2.5.
- Review patch generation jobs for anomalous output filenames containing path separators or parent-directory segments.
How to Mitigate CVE-2026-47712
Immediate Actions Required
- Upgrade Dulwich to version 1.2.5 or later in all environments that import the library.
- Inventory automation that calls dulwich.porcelain.format_patch with untrusted commits and pause those jobs until upgraded.
- Validate the resolved path of any patch file produced by older Dulwich versions against the intended outdir before opening or processing it.
Patch Information
The fix lands in Dulwich 1.2.5. dulwich.patch.get_summary now mirrors git's format_sanitized_subject: only [A-Za-z0-9._] are retained, runs of other characters collapse to a single -, consecutive . collapse to a single ., trailing ./- are stripped, and the result is length-limited. See the GitHub Security Advisory GHSA-555p-6grf-mh7f and the Dulwich 1.2.5 Release Notes for details.
Workarounds
- Call porcelain.format_patch with stdout=True and write the patch to a destination the caller controls instead of letting Dulwich choose the filename.
- Validate the chosen path before opening by comparing os.path.realpath(returned_path) against os.path.realpath(outdir) and rejecting any patch whose resolved path is not inside outdir.
- Pre-screen commits and refuse to format any whose subject's first line contains /, \, .., or other characters unsafe on the target filesystem.
# Upgrade Dulwich to the patched release
pip install --upgrade 'dulwich>=1.2.5'
# Verify the installed version
python -c "import dulwich; print(dulwich.__version__)"
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

