{
  "affected": [
    {
      "ranges": [
        {
          "database_specific": {
            "extracted_events": [
              {
                "introduced": "0.24.0"
              },
              {
                "fixed": "1.2.5"
              }
            ],
            "source": [
              "AFFECTED_FIELD",
              "REFERENCES"
            ]
          },
          "events": [
            {
              "introduced": "031c690286ed5e6ddd199b4272587d590624b728"
            },
            {
              "fixed": "c2446e51b"
            },
            {
              "fixed": "073f4dfa9840af2da59887ed828b026b609faa6c"
            }
          ],
          "repo": "https://github.com/jelmer/dulwich",
          "type": "GIT"
        }
      ]
    }
  ],
  "aliases": [
    "GHSA-555p-6grf-mh7f"
  ],
  "database_specific": {
    "cna_assigner": "GitHub_M",
    "cwe_ids": [
      "CWE-22"
    ],
    "osv_generated_from": "https://github.com/CVEProject/cvelistV5/tree/main/cves/2026/47xxx/CVE-2026-47712.json"
  },
  "details": "Dulwich is a pure-Python implementation of the Git file formats and protocols. Starting in version 0.24.0 and prior to version 1.2.5, dulwich.porcelain.format_patch(outdir=...) derives each patch filename from the commit's subject line. Prior to this fix, get_summary 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. This is fixed in Dulwich 1.2.5. Users should upgrade to 1.2.5 or later. dulwich.patch.get_summary now mirrors git's format_sanitized_subject: 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 format_patch can no longer be steered out of outdir via the commit subject. Until upgrading, callers that pass untrusted commits to   porcelain.format_patch can use stdout=True and write the patch to a destination they control, rather than letting format_patch choose the filename; validate the chosen path before opening - e.g. compare os.path.realpath(returned_path) against  os.path.realpath(outdir) and reject any patch whose resolved path is not inside outdir; and/or pre-screen commits and refuse to format any whose subject's first line contains /, \\, .., or other characters that are not safe on the target filesystem.",
  "id": "CVE-2026-47712",
  "modified": "2026-08-07T11:31:12.661085076Z",
  "published": "2026-06-10T22:01:49.996Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/jelmer/dulwich/releases/tag/dulwich-1.2.5"
    },
    {
      "type": "ADVISORY",
      "url": "https://github.com/CVEProject/cvelistV5/tree/main/cves/2026/47xxx/CVE-2026-47712.json"
    },
    {
      "type": "ADVISORY",
      "url": "https://github.com/jelmer/dulwich/security/advisories/GHSA-555p-6grf-mh7f"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-47712"
    },
    {
      "type": "FIX",
      "url": "https://github.com/jelmer/dulwich/commit/c2446e51b"
    }
  ],
  "schema_version": "1.8.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:N/I:L/A:N",
      "type": "CVSS_V3"
    }
  ],
  "summary": "Dulwich doesn't sanitize commit subjects in `porcelain.format_patch`"
}