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



CVE-2026-78679

CVE-2026-78679: Arbitrary File Read via Command-Line Option Injection in GitPython

Amit Schendel
Amit Schendel
Senior Security Researcher

Sep 8, 2026·5 min read·26 visits

Executive Summary (TL;DR)

GitPython prior to version 3.1.59 fails to validate positional parameters in TagReference.create(), enabling command-line option injection (like --file) that allows attackers to perform arbitrary file reads.

A command-line option injection vulnerability in GitPython allows low-privilege or unauthenticated actors to read arbitrary local files. The flaw resides in the TagReference.create() function, which fails to evaluate positional arguments against the library's unsafe-option denylist, enabling the execution of native git commands with injected option flags.

Vulnerability Overview & Component Architecture

GitPython is a popular Python library used to interact with Git repositories by wrapping the native git command-line interface. When developers invoke high-level API functions such as TagReference.create(), GitPython processes these calls into structured arguments and executes a git subprocess. The security boundary of GitPython relies on the assumption that arbitrary user input cannot alter the execution context of the underlying git binary.\n\nTo prevent command injection and option injection, GitPython implements a validation component called Git.check_unsafe_options(). This mechanism evaluates provided flags against a predefined denylist of dangerous options (e.g., --file or -F for git-tag), which could read or write external files. If a forbidden option is identified, the library raises an UnsafeOptionError exception to prevent execution.\n\nThe vulnerability CVE-2026-78679 exists because the invocation of this validation mechanism in the tagging module completely bypassed positional arguments. Because GitPython does not append a double-dash (--) separator to isolate options from positional inputs during command synthesis, the underlying git command-line parser treats positional values starting with a hyphen as options. This logical oversight permits an attacker to perform unauthorized out-of-band file read operations.

Root Cause & Argument Validation Bypass

The core defect resides within the create method of the TagReference class inside git/refs/tag.py. When a developer executes TagReference.create(), the method processes multiple arguments: repo, path, reference, and any additional keyword arguments passed via **kwargs. To ensure safety, the function relies on Git.check_unsafe_options(), which in turn calls Git._option_candidates() to extract potential option strings for scanning.\n\nIn the vulnerable implementation, the invocation was structured as Git._option_candidates([], kwargs). The first argument of _option_candidates is designed to receive a list of positional arguments, while the second processes keyword arguments. By passing an empty list ([]) as the first argument, GitPython's validation system only evaluated keys and values found inside the kwargs dictionary.\n\nConsequently, the positional arguments path and reference were never processed by the validation routine. When a caller passes a value starting with a hyphen (such as --file=/etc/passwd) as the reference argument, it completely evades the check. The resulting system call compiles these arguments directly into a shell-less command array, causing native git to interpret the injected positional argument as an option flag.

Code-Level Analysis and Remediation Diff

Analyzing the implementation details highlights how the validation bypass was constructed and subsequently corrected. In vulnerable versions of GitPython, the validation bypass occurred directly before the command execution phase because of the incorrect array passing.\n\nBelow is a comparative breakdown of the vulnerable code and the official patch introduced in commit 1b0d2d9b91575f7db44ef4ff58ac37fc9335e5f6:\n\npython\n# VULNERABLE CODE PATH (git/refs/tag.py)\ndef create(cls, repo, path, reference=\"HEAD\", force=False, ... allow_unsafe_options=False, **kwargs):\n # ...\n if not allow_unsafe_options:\n # BUG: Passing empty list [] ignores the positional parameters 'path' and 'reference'\n Git.check_unsafe_options(\n options=Git._option_candidates([], kwargs),\n unsafe_options=cls.unsafe_git_tag_options,\n clusterable_short_options=\"46adefilnqsv\",\n )\n # ...\n\n\nThe patch resolves the logical flaw by explicitly adding path and reference to the list of candidates passed to _option_candidates(). This ensures that even when user input is mapped to positional arguments, it is analyzed prior to subcommand construction.\n\npython\n# PATCHED CODE PATH (git/refs/tag.py)\ndef create(cls, repo, path, reference=\"HEAD\", force=False, ... allow_unsafe_options=False, **kwargs):\n # ...\n legacy_ref = kwargs.pop(\"ref\", None)\n if legacy_ref:\n reference = legacy_ref\n\n if not allow_unsafe_options:\n # FIX: 'path' and 'reference' are now passed in the candidates list\n Git.check_unsafe_options(\n options=Git._option_candidates([path, reference], kwargs),\n unsafe_options=cls.unsafe_git_tag_options,\n clusterable_short_options=\"46adefilnqsv\",\n )\n # ...\n\n\nBy incorporating the positional parameters, any input starting with a hyphen in either path or reference is subjected to the same denylist matching as standard keyword arguments. This prevents the execution pipeline from accepting external options under the guise of positional operands.

Exploitation Methodology & PoC Execution

Exploiting this vulnerability requires that an application exposes the path or reference parameters of TagReference.create() to user-controlled inputs. When this condition is met, an attacker can specify a value designed to act as a Git option. For example, setting the reference parameter to --file=/etc/passwd triggers the flaw.\n\nmermaid\ngraph LR\n A[\"User Input: reference = '--file=/etc/passwd'\"] --> B[\"TagReference.create() called\"]\n B --> C{\"Is input in kwargs?\"}\n C -- \"No, it is positional\" --> D[\"Bypasses check_unsafe_options()\"]\n C -- \"Yes\" --> E[\"Blocked by check_unsafe_options()\"]\n D --> F[\"Git Command execution: git tag tag_name --file=/etc/passwd\"]\n F --> G[\"Git reads /etc/passwd as tag annotation message\"]\n G --> H[\"Attacker reads tag metadata to exfiltrate file content\"]\n\n\nDuring subprocess execution, the native git CLI processes the options sequentially. The presence of --file=/etc/passwd instructs the git tag command to read the target file's contents from disk and embed them as the annotation message for the newly generated tag. Since the command executes under the privileges of the Python application process, it can read any file the application has permission to access.\n\nOnce the tag is created, the attacker retrieves the contents of the target file by querying the tag's metadata. In GitPython, this is accomplished by reading the message property of the returned TagReference or by issuing a git show command on the repository. This represents a highly reliable out-of-band data exfiltration channel.

Remediation, Patching, & Input Sanitization

The primary remediation for CVE-2026-78679 is upgrading the GitPython library to version 3.1.59 or later. This release updates all reference creation utilities to evaluate positional parameters, thereby closing the command-line option injection pathway. Organizations should review their dependency manifests and update their environments immediately.\n\nIn environments where upgrading the library is not immediately feasible, developers must implement strict input validation on all parameters passed to GitPython APIs. Any user-controlled value destined for GitPython must be validated to ensure it does not start with a hyphen character (-), which is the universal prefix for command-line options.\n\nAdditionally, implementing input filtering using a whitelist of allowed characters (such as alphanumeric characters, dashes, and underscores) represents an effective defense-in-depth strategy. Developers should also verify that the underlying execution environment enforces least-privilege principles, limiting the files accessible to the application worker processes in the event of an exploitation attempt.

Official Patches

gitpython-developersSecurity Patch Commit

Fix Analysis (1)

Technical Appendix

CVSS Score
7.1/ 10
CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:N/VA:N/SC:N/SI:N/SA:N
EPSS Probability
0.24%
Top 85% most exploited

Affected Systems

Applications incorporating GitPython versions 3.1.33 through 3.1.58 that allow user control over TagReference positional parameters.

Affected Versions Detail

Product
Affected Versions
Fixed Version
GitPython
gitpython-developers
>= 3.1.33, < 3.1.593.1.59
AttributeDetail
CWE IDCWE-73
Attack VectorNetwork (AV:N)
CVSS v4.0 Score7.1
EPSS Score0.00241
ImpactArbitrary File Read / Information Disclosure
Exploit StatusProof-of-Concept (PoC)
KEV StatusNot Listed

MITRE ATT&CK Mapping

T1048Exfiltration Over Alternative Protocol
Exfiltration
T1083File and Directory Discovery
Discovery
CWE-73
External Control of File Name or Path

The software allows user input to control or influence paths or file names passed to file system APIs without sufficient validation.

Known Exploits & Detection

GitHubAdvisory text containing reproduction scripts and technical details.

Vulnerability Timeline

Vulnerability reported and initial fix pull request drafted by developers
2026-08-04
Security patch commit 1b0d2d9b91575f7db44ef4ff58ac37fc9335e5f6 authored
2026-08-05
CVE-2026-78679 and GHSA-3wxw-xv34-2frg published
2026-08-25

References & Sources

  • [1]GitHub Security Advisory GHSA-3wxw-xv34-2frg
  • [2]CVE.org CVE Record - CVE-2026-78679
  • [3]GitPython v3.1.59 Release
  • [4]NVD - CVE-2026-78679

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

•37 minutes ago•CVE-2026-112906
4.7

CVE-2026-112906: Mutual Exclusion Bypass via Inode Recycling and Time Tracking Race in filelock

A local race condition and mutual exclusion bypass vulnerability exists in filelock versions 4.1.0 through 4.2.0. On Linux filesystems with rapid inode reuse, a local attacker can manipulate modification timestamps and lock files to cause waiting processes to falsely evict active soft lock markers.

Amit Schendel
Amit Schendel
5 views•6 min read
•about 2 hours ago•CVE-2026-114055
7.5

CVE-2026-114055: Uncontrolled Resource Consumption in vLLM via Unvalidated Multimodal Kwargs

vLLM prior to version 0.31.0 contains an uncontrolled resource consumption vulnerability (CWE-400) in its HTTP API request handling logic. Unauthenticated remote attackers can transmit per-request keyword arguments (`mm_processor_kwargs` and `media_io_kwargs`) that are passed directly into internal multimodal preprocessing pipelines, causing CPU/GPU memory exhaustion and crashing the engine process.

Amit Schendel
Amit Schendel
5 views•5 min read
•about 3 hours ago•CVE-2026-62204
6.6

CVE-2026-62204: Arbitrary Bazaar Package Overwrite in SiYuan via Parameter Mismatch

An insufficient verification of data authenticity vulnerability in SiYuan prior to version 3.7.4 allows an attacker to overwrite arbitrary installed marketplace packages (plugins, widgets, themes, and templates). By providing a mismatched package name and package archive repository URL during a Bazaar installation request, arbitrary file write into trusted plugin directories can be achieved, enabling persistence and execution across application restarts.

Alon Barad
Alon Barad
7 views•5 min read
•about 4 hours ago•CVE-2026-115478
7.1

CVE-2026-115478: Incorrect Authorization and Incomplete Cleanup in obsidian-tc

In obsidian-tc versions 1.0.1 through 1.31.3, memory lifecycle tools fail to validate note ownership prior to rematerializing Markdown files and execute non-atomic SQLite database mutations. An authorized caller can overwrite arbitrary note bodies on disk and cause persistent desynchronization between the database memory graph and physical vault files.

Amit Schendel
Amit Schendel
8 views•5 min read
•about 5 hours ago•CVE-2026-115477
7.1

CVE-2026-115477: Human-in-the-Loop Authorization Bypass in obsidian-tc

A high-severity authorization bypass vulnerability in obsidian-tc allows clients to bypass Human-In-The-Loop (HITL) confirmation prompts over Streamable HTTP deployments. Due to incomplete validation of returned prompt responses, an attacker echoing a signed requestState token can force execution of destructive vault operations even if a human user declines or cancels the prompt.

Alon Barad
Alon Barad
10 views•5 min read
•about 6 hours ago•CVE-2026-113790
6.0

CVE-2026-113790: Uncontrolled Resource Consumption in pypdf Container Parsing

A Denial of Service (DoS) vulnerability in pypdf versions prior to 6.21.0 allows remote attackers to cause high CPU and memory resource exhaustion by supplying PDF files containing oversized or deeply nested arrays, dictionaries, or content streams.

Alon Barad
Alon Barad
8 views•5 min read