[WIP] Fix GitPython section-name injection vulnerability - #24
Merged
Merged
Conversation
Arun Iyer (aruniyer)
marked this pull request as ready for review
August 6, 2026 08:23
Copilot stopped work on behalf of
Arun Iyer (aruniyer) due to an error
August 6, 2026 08:23
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
create_submodule,submodule_update,Submodule.add) are used anywhere in the codebaseimport gitworks and resolves cleanly withpip installReachability Assessment
The advisory (GHSA-3rp5-jjmw-4wv2) describes a git-config section-name injection vulnerability that is exploitable specifically through GitPython's submodule APIs:
Repo.create_submodule(name=...)andRepo.clone_from(...)+repo.submodule_update(init=True), where an attacker-controlled submodule name is written unescaped into.git/config.I searched the entire repository for GitPython usage and found only two files that import
git(theGitPythonpackage):project_utils/csharp_setup_utils.py— usesgit.Repo.clone_from(...)(fixed, trusted URL) andgit.Repo.init(...).repoclassbench/dataset/python_setup_utils/git_related_utils.pyNeither file calls
create_submodule,submodule_update,Submodule.add, or any other submodule-related API, and no.gitmodules-processing logic exists in the codebase. There is no repository code path that constructs a submodule from user-controlled or untrusted names.Conclusion: the vulnerable code path is not reachable in this codebase (high confidence, since the advisory names specific APIs —
create_submodule/submodule_update/Submodule.add— and a full-repo search confirms none of them are called). The version bump to the patched release (3.1.53) is applied to resolve the Dependabot alert and satisfy vulnerability scanners rather than to address an active exploitation risk in this repository.No other code changes were required since the affected functionality is unused.
Original prompt
This section details the Dependabot vulnerability alert you should resolve
<alert_title>GitPython: git-config section-name injection enables arbitrary config directives (core.sshCommand RCE)</alert_title>
<alert_description>### Summary
In GitPython
<= 3.1.52, the config writer neutralizes only CR, LF, and NUL in configuration names, but writes section names into the[...]header with no other escaping. A section/subsection name that contains] [ "closes the intended header and opens a second same-line section, injecting an arbitrary config directive — with no newline required. Because a submodule name is attacker-controlled data (it comes from a repository's.gitmodules, or from an application that lets a user name a submodule) and is written verbatim into the parent repository's trusted.git/config, an attacker can setcore.sshCommand(oralias.*,core.pager,core.fsmonitor) and achieve remote code execution on the victim's next git operation. Likely CWE-74 (Injection).This is a distinct variant of the injection addressed by GHSA-mv93-w799-cj2w / GHSA-v87r-6q3f-2j67: those fixed newline injection into config values/names (patched in 3.1.50); the
[r\n\x00]guard added for them does not stop a same-line section break inside a name.Details
The only guard applied to section/option names before writing is
_assure_config_name_safe, which uses a regex that matches solely CR/LF/NUL:git/config.py:75,897-899(GitPython 3.1.52):The name is then serialized into the header with no escaping of
],[,", space,=or#:git/config.py:693:For submodules the name is wrapped as
submodule "<name>"(git/objects/submodule/util.py:39,return f'submodule "{name}"'), which supplies the balancing quote. A submodule named:therefore serializes to the header
[submodule "x"] [core] sshCommand=CMD #"]. git parses everything after the first]on that line as a fresh section, yieldingcore.sshCommand=CMD(the trailing#"]is an inline comment). No CR/LF/NUL appears, so_assure_config_name_safenever fires.The attacker-controlled name reaches this sink through documented public entry points that write it into the parent repository's
.git/config:Repo.create_submodule(name=<untrusted>, ...)→Submodule.add→git/objects/submodule/base.py:619writer.set_value(sm_section(name), "url", url)— a single call, no hostile remote required.Repo.clone_from(<hostile url>)+repo.submodule_update(init=True)→git/objects/submodule/base.py:855writer.set_value(sm_section(self.name), "url", self.url), whereself.nameis read unvalidated from the cloned repo's.gitmodules.Asymmetry: the sibling class is blocked — a newline in a config value, e.g.
set_value("core", "editor", "x\n\tsshCommand=CMD"), raisesValueError. The section-name bracket payload is not caught by the same guard.PoC
Single self-contained script, run against the pinned release in an ephemeral environment. Non-destructive: the injected value is an inert marker, verified parse-only with
git config --get; no ssh/fetch/push is run and nothing is executed.