dulwich.porcelain.formatpatch(outdir=...) derives each patch filename from the commit's subject line. Prior to this fix, getsummary only replaced spaces with dashes - path separators (/, ), parent-directory components (..), and other filename-hostile characters (e.g. :) were preserved verbatim and passed straight into os.path.join(outdir, f"{i:04d}-{summary}.patch").
A malicious commit subject could therefore direct the generated patch file outside the requested outdir. Reduced examples:
Related issues from the same root cause:
Anyone calling porcelain.format_patch (or the dulwich format-patch CLI) against untrusted commits - for example, a service that runs format-patch over user-supplied repositories or pull requests - could have patch files written to attacker-chosen locations within the process's write permissions.
Fixed in Dulwich 1.2.5. Users should upgrade.
dulwich.patch.getsummary now mirrors git's formatsanitizedsubject: only [A-Za-z0-9._] are kept, runs of other characters collapse to a single -, consecutive . collapse to a single ., trailing ./- are stripped, and the result is length-limited. This makes the returned string safe to embed as a filename component, so formatpatch can no longer be steered out of outdir via the commit subject.
Until upgrading, callers that pass untrusted commits to porcelain.format_patch can:
{
"github_reviewed_at": "2026-06-08T23:04:48Z",
"nvd_published_at": "2026-06-10T23:16:48Z",
"github_reviewed": true,
"cwe_ids": [
"CWE-22"
],
"severity": "LOW"
}