CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



GHSA-3F7W-8RR8-F37F

GHSA-3f7w-8rr8-f37f: Arbitrary File Overwrite and Read via Unguarded Argument Forwarding in GitPython

Alon Barad
Alon Barad
Software Engineer

Aug 4, 2026·5 min read·38 visits

Executive Summary (TL;DR)

GitPython versions prior to 3.1.57 are vulnerable to argument injection, enabling arbitrary file overwrite via IndexFile.checkout() and arbitrary file read via TagReference.create() because keyword arguments are forwarded unsanitized to the underlying git binary.

An argument injection vulnerability in GitPython allows remote or local attackers to execute arbitrary file reads or arbitrary file overwrites via unsafe command option forwarding. This occurs because the wrapper methods `IndexFile.checkout()` and `TagReference.create()` fail to validate parameters before passing them to system-level git invocations.

Vulnerability Overview

GitPython is a Python library used to interact with Git repositories by abstracting command-line operations into Pythonic APIs. The library provides high-level classes such as IndexFile and TagReference to manage git indexes and reference tags respectively. When these classes perform actions, they serialize programmatic options and dispatch execution to the local system's git binary.

The attack surface exists within any API wrapper that passes developer-controlled keyword arguments directly to the underlying shell command execution. By default, GitPython features an opt-in parameter validation system called Git.check_unsafe_options(). However, because this verification is not enforced globally at the execution dispatcher layer, any API wrapper that omits the validation remains completely unguarded.

Two critical wrapper methods are vulnerable to this design pattern. The IndexFile.checkout() method forwards arguments to git checkout-index, which accepts the --prefix option to redirect file creation outside the workspace. The TagReference.create() method forwards arguments to git tag, which accepts the -F or --file options to read local system files and return them in-band. This leads to arbitrary file write (integrity and availability compromise) and arbitrary file read (confidentiality compromise).

Root Cause Analysis

The root cause of this vulnerability lies in improper validation of command-line arguments, classified under CWE-88 (Argument Injection) and CWE-20 (Improper Input Validation). GitPython relies on individual, opt-in implementations of Git.check_unsafe_options() inside wrapper functions to maintain security. If a wrapper accepts **kwargs and passes them directly to the git command execution without sanitization, an attacker who controls the arguments can inject system flags.

In IndexFile.checkout(), the python method forwards arguments to git checkout-index. The --prefix=<path> command-line option specifies a prefix directory to prepend to checked-out paths. Because there is no check preventing the use of --prefix, an attacker can specify absolute directories or directory traversal sequences. This allows the application to write files from the repository to arbitrary paths on the local filesystem, overwriting existing files if run with appropriate permissions.

In TagReference.create(), the method maps to the git tag command. The command-line utility supports the -F <file> and --file=<file> options to import a tag message from a target file. Because GitPython does not filter these options, an attacker can specify a sensitive system file as the source. GitPython subsequently reads this file, associates it with the created tag object, and exposes its raw contents when the application accesses the TagReference.tag.message property.

Code Analysis

Before the patch, git/index/base.py contained the following unsafe forwarding mechanism:

def checkout(self, paths=None, force=False, fprogress=lambda *args: None, **kwargs):
    # Unsanitized kwargs are passed directly to checkout_index
    proc = self.repo.git.checkout_index(*args, **kwargs)

Because there is no invocation of Git.check_unsafe_options() or defined blocked option list, any keys in kwargs are converted directly into command-line arguments. For example, passing prefix='/tmp/' evaluates to --prefix=/tmp/ in the shell execution.

Similarly, git/refs/tag.py contained the following definition:

def create(cls, repo, path, reference="HEAD", logmsg=None, force=False, **kwargs):
    # Forwarded directly to the underlying git wrapper without verification
    # kwargs can contain 'F' or 'file' keys

To address this, the patch introduces class-level variables specifying banned options and updates the method signatures to accept allow_unsafe_options: bool = False. Inside the methods, an explicit check validates the passed arguments against the blocklist unless allow_unsafe_options is set to True:

# Inside IndexFile
unsafe_git_checkout_index_options = ["--prefix"]
 
# Validation check added to checkout()
if not allow_unsafe_options:
    Git.check_unsafe_options(
        options=Git._option_candidates([], kwargs),
        unsafe_options=self.unsafe_git_checkout_index_options,
    )

Exploitation and Proof-of-Concept

Exploitation requires the attacker to be able to supply or influence the keyword arguments (**kwargs) passed to either of the vulnerable methods. This scenario typically occurs in web applications, automated CI/CD pipelines, or repository management dashboards that accept custom execution configurations from users.

To perform an arbitrary file overwrite, an attacker invokes index.checkout() with a custom prefix argument pointing to a system target. The following proof-of-concept demonstrates how the exploit redirects repository files to write directly into /tmp/target_dir/ instead of the local repository workspace:

from git import Repo
import os
 
repo = Repo("/path/to/repo")
# Executes 'git checkout-index -a -f --prefix=/tmp/target_dir/'
repo.index.checkout(prefix="/tmp/target_dir/", a=True, f=True)

To perform an arbitrary file read, the attacker targets TagReference.create() by specifying the -F parameter with the target file path. When GitPython spawns the process, it reads the target file and records its content as the tag message. The application can then read the sensitive file content in-band:

from git import Repo
from git.refs.tag import TagReference
 
repo = Repo("/path/to/repo")
# Executes 'git tag -a -f -F /etc/passwd leak_tag'
tag_ref = TagReference.create(repo, "leak_tag", force=True, a=True, F="/etc/passwd")
leaked_data = tag_ref.tag.message
print(leaked_data)

Impact Assessment

The impact of these two primitives is high. The arbitrary file overwrite primitive enables attackers to compromise system integrity. If the application runs with root privileges or within a user directory, an attacker can overwrite critical files such as .bashrc, .ssh/authorized_keys, or configuration files, potentially escalating privileges or achieving remote code execution.

The arbitrary file read primitive directly breaks confidentiality. In automated environments, this allows attackers to leak configuration properties, local environment variables, system user information (such as /etc/passwd), or application source code. The data is returned directly to the calling context, which may output it to web interfaces or log collectors.

Because the underlying vulnerability pattern (opt-in security checks) relies on manual application on a per-wrapper basis, additional undocumented wrappers may still expose similar argument injection vectors. The CVSS score of 8.1 reflects high integrity and availability impact, though configuration-dependent confidentiality impacts are also severe.

Official Patches

gitpython-developersFix Commit
gitpython-developersPull Request

Fix Analysis (1)

Technical Appendix

CVSS Score
8.1/ 10
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:H

Affected Systems

GitPython

Affected Versions Detail

Product
Affected Versions
Fixed Version
gitpython
gitpython-developers
< 3.1.573.1.57
AttributeDetail
CWE IDCWE-88 (Argument Injection), CWE-20 (Improper Input Validation)
Attack VectorNetwork
CVSS Score8.1
ImpactHigh (Arbitrary File Overwrite / Arbitrary File Read)
Exploit StatusProof-of-Concept Available
KEV StatusNot Listed

MITRE ATT&CK Mapping

T1202Indirect Command Execution
Execution
T1059Command and Scripting Interpreter
Execution
CWE-88
Improper Neutralization of Argument Delimiters in a Command ('Argument Injection')

The application constructs an OS command using keyword arguments but does not neutralize or validate elements that can modify the command's actions, leading to argument injection.

Vulnerability Timeline

Security researchers identify 14 unguarded command-execution call sites on GitPython version 3.1.55.
2026-07-25
Core developers patch the vulnerability in commit 3af0c2516c5e18c829da30338614688f6b69b49c.
2026-07-26
Official security advisory GHSA-3f7w-8rr8-f37f is published alongside library version 3.1.57.
2026-08-03

References & Sources

  • [1]GitHub Security Advisory GHSA-3f7w-8rr8-f37f
  • [2]GitPython Pull Request 2193
  • [3]GitPython Fix Commit
  • [4]GitPython Source Repository
  • [5]GitPython Release 3.1.57

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.

More Reports

•32 minutes ago•CVE-2026-107723
8.1

CVE-2026-107723: Silent Claim-Validator Bypass in NearForm fast-jwt via Array Payload Type Confusion

A high-severity type-confusion vulnerability exists in NearForm fast-jwt prior to version 6.3.0. The vulnerability allows attackers to bypass crucial claim validation steps (such as expiration, issuer, audience, and subject validations) by presenting a validly signed JSON Web Token structured as a JSON array instead of a JSON object. This occurs because the library's decoder fails to reject JSON arrays during type evaluation.

Alon Barad
Alon Barad
3 views•6 min read
•about 2 hours ago•CVE-2026-107721
5.9

CVE-2026-107721: Time Validation Bypass in NearForm fast-jwt due to Loose Temporal Option Validation

NearForm fast-jwt prior to version 6.3.0 is vulnerable to an input validation flaw where configuring verifier properties (such as clockTolerance, clockTimestamp, and cacheTTL) with non-finite values like Infinity or NaN allows attackers to bypass temporal claim validations, including expiration (exp) and activation (nbf) boundaries. This validation bypass can result in unauthorized session persistence and cache poisoning.

Amit Schendel
Amit Schendel
3 views•6 min read
•about 3 hours ago•CVE-2026-107722
9.8

CVE-2026-107722: Algorithm Confusion via Non-Whitespace Prefix Bypass in fast-jwt

A critical cryptographic vulnerability in fast-jwt versions 6.2.x prior to 6.3.0 allows unauthenticated remote attackers to execute an asymmetric-to-symmetric algorithm confusion attack due to incomplete validation of leading non-whitespace prefixes.

Amit Schendel
Amit Schendel
3 views•5 min read
•about 4 hours ago•CVE-2026-107720
7.4

CVE-2026-107720: Signature Verification Bypass in NearForm fast-jwt

CVE-2026-107720 is a critical signature verification bypass vulnerability in NearForm's fast-jwt Node.js library. Under specific configurations where the token verifier is initialized with a falsy cryptographic key (such as an empty string or null) and a non-empty algorithms allowlist, the library erroneously skips signature validation. This allows unauthenticated remote attackers to submit fabricated, unsigned JSON Web Tokens and bypass the authorization boundary of the application entirely.

Amit Schendel
Amit Schendel
6 views•7 min read
•about 5 hours ago•CVE-2026-107715
6.8

CVE-2026-107715: Information Disclosure and Credential Leakage in Ruby Mechanize via Cross-Origin Redirections

Ruby Mechanize prior to version 2.14.1 contains an information disclosure vulnerability. When executing cross-origin HTTP redirects, global headers configured on the Mechanize agent (such as Authorization or Session Cookies) are dynamically re-applied to the subsequent request, bypassing the internal header-stripping logic. An attacker who controls a redirection endpoint can capture sensitive bearer tokens or cookies.

Alon Barad
Alon Barad
6 views•7 min read
•about 6 hours ago•CVE-2026-107399
6.8

CVE-2026-107399: Information Disclosure via HTML Meta-Refresh in Ruby Mechanize

An origin trust boundary failure in the Ruby mechanize library (prior to v2.14.1) allows unauthenticated remote web servers to harvest sensitive global request headers, such as Authorization Bearer tokens and cookies, by utilizing HTML-level meta-refresh redirection tags. Standard HTTP-level redirect boundaries were not applied to document-level redirects, creating a vector for cross-origin credential leakage during automated crawls.

Amit Schendel
Amit Schendel
5 views•5 min read