A vulnerability in the Cruft library's GitPython integration allows an attacker to execute arbitrary code by planting a malicious Git hook. The create_submodule function clones a submodule into the repository's .git directory before validating the path. Specifically, a path like ".git/hooks" is accepted initially, causing the submodule to be cloned directly into the live hooks directory. This results in an attacker-controlled executable hook file (e.g., post-checkout) being placed and executed on subsequent Git operations. Versions 3.1.x silently allow this, while 3.2.0 and later raise a ValueError after cloning, but do not remove the planted hook, so the risk remains. The vulnerability affects versions from 3.1.59 through 3.2.0 plus subsequent commits. A fix is available in version 2.16.0_17.
CVE-2026-100689 is a path traversal vulnerability in GitPython 3.1.61 and main branch affecting the submodule update process. The vulnerability arises because the 'path' field from .gitmodules is used without proper validation, allowing an attacker to specify a path outside the repository directory. This can lead to directory creation and population outside the intended repository location. The issue is mitigated in common workflows since real git rejects .gitmodules with '..' components in the working tree, but it can be triggered when updating submodules at non-HEAD commits. A fix is available in version 2.16.0_16.
GitPython versions prior to 3.1.60 contain a Regular Expression Denial of Service (ReDoS) vulnerability in the Actor.name_email_regex pattern used to parse commit author and committer fields. The vulnerable regex causes catastrophic backtracking when processing a commit with an author or committer string containing a long unterminated '<' character, leading to quadratic CPU time growth proportional to input length. This can cause significant CPU exhaustion and denial of service in any system using GitPython to read commit metadata from untrusted repositories.
GitPython version 3.1.59 contains a vulnerability (CVE-2026-87817) where the library incorrectly resolves the git directory path by testing candidate paths in an order that places the real .git directory last. This allows attacker-controlled repository content to impersonate the git directory, leading to arbitrary code execution when a victim performs a commit using GitPython's native index.commit() method. The vulnerability also allows reading files outside the repository and writing config files to attacker-chosen locations. The issue affects GitPython versions >=2.9.0 and <2.16.0_15 and has a CVSS score of 8.8 (high severity). A fix is available in version 2.16.0_15.
GitPython's TagReference.create() method improperly handles a positional 'reference' argument, allowing an attacker to bypass unsafe option guards and cause an arbitrary local file read. This occurs because the unsafe option check only inspects keyword arguments, ignoring positional arguments that can inject '--file=<path>' into the git tag command. The file contents are returned in the annotated tag message. This vulnerability affects GitPython versions up to 3.1.58 and is fixed in version 2.16.0_15.
GitPython versions from 2.9.0 up to 2.16.0_15 have a vulnerability where the clone_from() and clone() methods omit the --separate-git-dir option from their unsafe options denylist. This omission allows an attacker to specify an arbitrary path for the Git repository metadata directory, enabling creation of repository files and directories outside the intended clone destination. The flaw arises from a denylist parity gap between clone and init commands, despite documentation stating that --separate-git-dir should be blocked by default. This can lead to arbitrary directory creation controlled by the attacker within the filesystem permissions of the process running GitPython.
GitPython versions up to 3.1.58 have an incomplete denylist for unsafe git revision options in the Repo.blame() and Repo.blame_incremental() methods. This allows an attacker to use the --contents or -S options to cause arbitrary local file reads, exposing file contents in the blame output. The vulnerability arises because the denylist only blocks file-write options (--output/-o) but omits these read-capable options. A fix is available in version 2.16.0_15.
GitPython versions from 2.9.0 up to but not including 2.16.0_15 contain a vulnerability in the handling of multi-line git config values. When GitPython reads a multi-line quoted value from disk and later rewrites the config, it corrupts the value by improperly serializing embedded newlines. This causes dormant config values to be interpreted as new live directives, enabling injection of arbitrary configuration keys such as core.hooksPath. Since core.hooksPath controls the location of Git hooks, this can lead to arbitrary code execution during any hook-triggering git operation. A patch is available in version 2.16.0_15 that fixes this issue.
GitPython versions from 2.9.0 up to but not including 2.16.0_15 contain a vulnerability where the SubmoduleConfigParser used to parse the .gitmodules file follows [include] directives without restricting file paths. This allows an attacker controlling the .gitmodules file to cause the parser to read arbitrary local files. When such a file lacks git-config section headers, the resulting exception message leaks the first line of the file, leading to local file content disclosure. The issue arises because merge_includes is enabled by default in SubmoduleConfigParser, unlike other config parsers hardened against this risk. A fix is available in version 2.16.0_15.
GitPython versions from 2.9.0 up to but not including 2.16.0_14 contain a vulnerability where an attacker-controlled submodule name in a cloned repository's .gitmodules file can cause GitPython to create and initialize a Git repository outside the intended working directory. This occurs because GitPython does not validate the submodule name for path traversal sequences, allowing repository creation at arbitrary filesystem locations during submodule initialization. The vulnerability is fixed in version 2.16.0_14.
GitPython versions up to 3.1.57 contain a vulnerability in the config-name validator that allows injection of arbitrary git configuration directives via crafted option names. The validator fails to reject certain characters such as '=', '#', ';', '[', ']', and whitespace in option names, enabling attackers to forge config directives like core.sshCommand or core.hooksPath. This can lead to remote code execution on subsequent git operations if an attacker controls the option name passed to the config writer.
GitPython versions up to 3.1.57 contain a vulnerability where the unsafe git option guard can be bypassed by using the parameter split_single_char_options=False combined with a single-character keyword argument. This bypass allows arbitrary OS command execution via the git --upload-pack option, despite the default safety setting. The flaw is due to incomplete validation of joined short-option tokens, enabling command injection in methods like clone, fetch, and push.
GitPython's Repo.init method forwards keyword arguments directly to git init without checking for unsafe options. This allows an attacker who can control the template parameter to plant malicious git hooks that execute arbitrary code during subsequent git operations. The vulnerability affects GitPython versions up to 3.1.57 and requires the attacker to stage an executable hook directory at a known path. A fix is available in version 2.16.0_14 that adds unsafe option checks.
CVE-2026-76217 is a vulnerability in GitPython where the methods IndexFile.remove() and Head.checkout() forward arbitrary keyword arguments to git rm and git checkout commands without proper validation. When used with the --pathspec-from-file and --pathspec-file-nul options, this can cause Git to treat the entire contents of a specified file as a single pathspec, leading to an error message that includes the entire file content in the command's stderr output. This results in an arbitrary file read disclosure to the caller. The issue affects GitPython versions from 2.9.0 up to but not including 2.16.0_14 and has been fixed in version 2.16.0_14.
GitPython versions up to 3.1.57 contain a vulnerability in the IndexFile.from_tree, reset, and merge_tree methods where unguarded forwarding of positional treeish arguments to 'git read-tree' allows an attacker to overwrite arbitrary files with a valid git-index blob. This occurs because the methods do not guard against unsafe options like '--index-output', enabling an attacker to specify an arbitrary output path. The vulnerability can lead to arbitrary file overwrite or destruction with the privileges of the host process.
GitPython versions up to 3.1.53 contain a vulnerability in the check_unsafe_options guard that allows bypass via single-character keyword argument value token smuggling. This bypass enables arbitrary OS command execution through the --upload-pack git option in all guarded methods such as clone, fetch, and pull. The vulnerability arises because the guard only inspects option keys, not values, allowing crafted values to inject unsafe git options. A fix is available in version 2.16.0_12.
GitPython's Diffable.diff() method allows attacker-controlled arguments to be passed directly to git diff commands without proper validation, enabling arbitrary file overwrite via the git diff --output option. This can overwrite or corrupt files at the privilege level of the running process with attacker-chosen paths and diff content. The vulnerability affects versions up to 3.1.53 and has been fixed in version 2.16.0_12.
GitPython versions prior to 2.16.0_12 contain a vulnerability where environment variables embedded in URLs passed to Repo.create_remote() or Remote.add() are expanded and stored in the repository configuration. This can lead to secret environment variables being exfiltrated to attacker-controlled hosts during subsequent fetch or pull operations. The issue stems from an incomplete fix that only addressed Repo.clone_from() but left other URL-processing calls vulnerable. A patch is available in version 2.16.0_12.
GitPython's Commit.count() method improperly forwards unsafe options to git rev-list without validation, allowing an attacker to truncate arbitrary files to zero bytes. This occurs because the output argument is passed unchecked, leading to file truncation at the process privilege level. The vulnerability affects versions up to 3.1.53 and has a medium severity rating.
GitPython versions up to 3.1.53 have an incomplete denylist for unsafe git clone options that omits the --template option. This omission allows an attacker who can influence clone options and stage a malicious post-checkout hook in a directory to achieve arbitrary OS command execution during a git clone operation. The vulnerability requires the attacker to have write access to a directory used as a template containing executable hooks. A fix is available in version 2.16.0_12 that adds --template to the denylist.