GHSA-jm78-9fvv-mhgrHigh· 8.8▾ TwilightGitPython: git-config OPTION-name injection via =/#/whitespace bypasses name validator, enabling forged core.sshCommand/hooksPath (RCE)
▾ Twilight zone — High severity, or a signal on a lesser flaw
impact 48.4 · likelihood 0 · exploitation 0
Need a working PoC? Pro members can cast a request and our team develops one — it lands right here.
GitPython's config-name validator only neutralizes CR/LF/NUL for the "option" label; it does not reject =, #, ;, [, ], or whitespace in an option name. write_section writes the option name verbatim into the config file, so an option name such as sshCommand = touch <cmd> # is written as \tsshCommand = touch <cmd> # = <value>, which git parses as core.sshCommand = touch <cmd> (the trailing # comments out the intended value). This forges arbitrary config directives (core.sshCommand, core.hooksPath, alias.*) → RCE on the next git operation. This is a distinct field (option name, not section name) and distinct character class (=/#/space, not newline/bracket) from GHSA-3rp5-jjmw-4wv2 (section-name bracket injection) and GHSA-mv93-w799-cj2w / GHSA-v87r-6q3f-2j67 (newline injection).
_assure_config_name_safe(name, label) (git/config.py:897) applies the bracket/quote state machine ONLY when label == "section"; for the "option" label it falls through with just the UNSAFE_CONFIG_CHARS_RE = [\r\n\x00] regex. write_section then writes the option name verbatim into "\t%s = %s\n" (config.py:702).
Arbitrary git-config directive injection → remote code execution via core.sshCommand (fires on any ssh git operation, no staged file needed) or core.hooksPath (with a staged hook). Requires the embedding application to forward a caller-influenced OPTION NAME into the config writer (name-control model, the same name-control model accepted by the related published advisories GHSA-3rp5-jjmw-4wv2 and GHSA-mv93-w799-cj2w). Default configuration.
with repo.config_writer() as cw:
cw.set_value("core", "sshCommand = touch /tmp/RCE #", "x")
# git config --get core.sshCommand -> touch /tmp/RCE
set_value("core", "sshCommand = touch /tmp/RCE #", "x")._assure_config_name_safe(option, "option") @ config.py. Guard: regex matches only [\r\n\x00]; bracket/quote state machine is gated on label=="section". Bypass proof: =,#,space pass → no ValueError.write_section writes "\tsshCommand = touch /tmp/RCE # = x\n" (config.py:702).core.sshCommand=touch /tmp/RCE → arbitrary code execution on next git op.Independently reproduced (gate harness): set_value('core','sshCommand = touch <RCE> #','x') → no ValueError; file line sshCommand = touch <RCE> # = x; git config --get core.sshCommand → touch <RCE> (rc=0). Also verified core.hooksPath via both GitConfigParser and repo.config_writer(). Fix-commit read: bracket/quote checks are inside if label == "section"; the "option" label is not covered.
GitPython <= 3.1.57 (validator present verbatim on the latest release tag).
Apply the section-name safety checks (reject =, #, ;, [, ], whitespace) to the "option" label as well, or validate the fully-rendered config line after substitution.
Reported by zx (Jace) — GitHub: @manus-use
GitPython <= 3.1.57Upgrade to a patched release:
GitPython 3.1.58Connected by shared product, vendor, weakness, or advisory.
GHSA-4gmw-gg2m-w46pHigh· 8.1GitPython: Unguarded git read-tree option forwarding in IndexFile.from_tree/reset/merge_tree enables arbitrary file overwrite
GHSA-9rj7-rf2p-w77rHigh· 7.5GitPython: Unguarded git option forwarding in Repo.init enables arbitrary command execution via --template clone hooks
GHSA-wvpp-8hx9-p66jHigh· 8.8GitPython: Unsafe git option guard bypass via split_single_char_options=False short-option token smuggling enables command execution
CVE-2026-76217Medium· 6.5GitPython: Arbitrary file read via --pathspec-from-file in IndexFile.remove() and Head.checkout()
GHSA-hh9p-6wh2-4mfcMedium· 6.5GitPython: Arbitrary file read via --pathspec-from-file in IndexFile.remove() and Head.checkout()
CVE-2026-87818Medium· 6.5GitPython 3.1.59 fails to restrict the --no-index option in the high-level diff API, allowing attackers to read arbitrary filesystem paths as repository operands