/

CVE-2026-67323

Severity:

HIGH RISK

(8.4)

Command Injection (CWE-77) in GitPython Git Helpers

CVE-2026-67323

Analyzed

Vulnerability type

Category:

Command Injection

CWE:

CWE-77

Impact:

Arbitrary Command Execution and File Truncation

Severity:

HIGH RISK

(8.4)

CVSS version:

3.1

Catch this CVE while code is being written

Detect vulnerable code directly in pull requests, so CVEs are fixed before merge.

Summary

GitPython before 3.1.51 fails to sanitize dangerous Git CLI options passed into Repo.archive(), git.ls_remote(), Repo.iter_commits(), and Repo.blame().

When applications forward attacker-controlled arguments to these helpers, an attacker can inject commands via options like --exec/--upload-pack or cause Git to overwrite arbitrary files using leading-dash revisions.

Affected context

This vulnerability appears in Python applications that embed GitPython as a wrapper around the Git command-line client.

It is most relevant when user-supplied or otherwise untrusted values are passed directly into Repo.archive(), git.ls_remote(), Repo.iter_commits(), or Repo.blame() as keyword arguments or revision parameters.

The risk materializes in environments where these arguments are not validated or normalized, and the underlying Git invocation is allowed to respect dangerous options such as --exec, --upload-pack, or arbitrary leading-dash arguments.

Exploit preconditions

  • Attack surface: Application features that expose Git operations (e.g., archive creation, remote listing, history browsing, or blame views).
  • Required access: Ability to influence or control arguments passed into GitPython methods, typically via HTTP parameters, form fields, API payloads, or plugin interfaces.
  • Trigger point: Calling Repo.archive(), git.ls_remote(), Repo.iter_commits(), or Repo.blame() with unvalidated keyword options or revision strings beginning with -.
  • Why exploitation is possible: The library forwards user-controlled options to the Git process without filtering out dangerous flags or treating leading-dash revisions as invalid, enabling the injection of arbitrary Git options and, by extension, shell commands or file operations.

Why this happens

The underlying issue is a classic command injection pattern where a high-level library acts as a thin wrapper over a CLI tool but does not constrain which options can be passed through.

GitPython methods like Repo.archive() and git.ls_remote() accept keyword arguments that are converted into Git flags; without a denylist or allowlist, attackers can supply options such as --exec or --upload-pack that cause Git to run arbitrary executables.

Similarly, Repo.iter_commits() and Repo.blame() treat revision identifiers as opaque strings and fail to reject inputs that start with -, allowing them to be interpreted as additional Git options rather than commit-ish names.

This maps to CWE-77, where input that influences command-line construction is not validated, allowing attackers to change command behavior beyond intended parameters.

Potential impact

  • Execution of arbitrary commands under the privileges of the application process.
  • Remote compromise of application servers that rely on GitPython for repository operations.
  • Truncation or overwriting of arbitrary files accessible to the Git process via options that open paths with write access.
  • Disruption of application functionality, including denial of service when critical files are modified.
  • Potential escalation to broader system compromise if executed commands pivot to other components.

General mitigation guidance

Mitigation focuses on restricting how user input influences Git commands and enforcing strict option handling.

Recommended defensive patterns include:

  • Treating Git options and revision identifiers as controlled parameters, not arbitrary user input, and performing strict validation before passing them into GitPython.
  • Implementing allowlists of safe Git flags for each method, rejecting or stripping any option not explicitly required.
  • Normalizing and validating revision strings so they cannot start with - or contain embedded option-like segments.
  • Running Git operations under dedicated, least-privilege accounts and with minimized file-system access to reduce the blast radius of potential injection.
  • Encapsulating all Git interactions behind a narrow application API that never exposes raw Git options to external callers.

How teams detect issues like this

Detection typically involves examining both code and runtime behavior for unsafe command construction patterns.

Useful approaches include:

  • Static analysis rules that flag GitPython usage where untrusted input flows directly into Repo.archive(), git.ls_remote(), Repo.iter_commits(), or Repo.blame() parameters.
  • Code review checklists that require reviewers to verify any dynamic Git options are built from constants or validated against an allowlist.
  • Logging and monitoring of Git invocations, including capturing command-line arguments, to detect unexpected options like --exec, --upload-pack, or unusual leading-dash revisions.
  • Use of security-focused linters or automated review tools that model taint flows from request parameters into subprocess or CLI wrapper calls.

Sources

SourceLink
github.comgithub.com/gitpython-developers/GitPython/security/advisories/GHSA-956x-8gvw-wg5v
vulncheck.comvulncheck.com/advisories/gitpython-before-command-injection-via-unguarded-git-options

Frequently asked

questions

Yes, if an application exposes GitPython-powered features over a network interface and forwards user-controlled arguments into the affected methods, a remote attacker may exploit it. If all GitPython inputs are internal or constant, the practical exploitability is much lower.

An attacker needs the ability to influence arguments passed into Repo.archive(), git.ls_remote(), Repo.iter_commits(), or Repo.blame(). This typically corresponds to authenticated or unauthenticated users who can supply parameters to endpoints that use these APIs.

The safest pattern is to treat Git options as immutable application choices and never expose them directly to users. Implement allowlists for acceptable options, reject any argument that starts with -, and ensure revisions and paths are validated against expected formats before calling GitPython.

Design application boundaries so that external input cannot directly control low-level command options, especially when wrapping CLI tools. Combine strict input validation, centralized helper functions for external command calls, and automated checks in CI to detect instances where untrusted data influences command-line arguments.

Find out what's already
exploitable in your codebase.