Cloudanix VulnDB

GHSA-mv93-w799-cj2w

High · 7.0

GitPython: Newline injection in config_writer() section parameter bypasses CVE-2026-42215 patch, enabling RCE via core.hooksPath

CVSS

7.0

EPSS

—

Published

May 8, 2026

CISA due date

—

Cloudanix analysis

Act now SSVC: Track

A flaw in how Git configuration is written lets attackers who control certain inputs redirect Git's hook scripts, allowing them to run their own code on developers' machines.

Chainable
Exploitation
Remote Unauthenticated
Attacker needs
None
Complexity
Low
Impact
Remote Code Execution
Component
Library
Class
Improper Input Validation
Remediation
Upgrade
Effort
Medium
Patch risk
Low

What it actually does

Incomplete newline sanitization in GitPython's config set_value allows untrusted section and option parameters to reach configparser, enabling forged section headers such as [core] with hooksPath in .git/config.

Why it matters to the business

Attackers who can influence Git configuration values can redirect hook execution to attacker-controlled directories, resulting in remote code execution on any system that triggers Git hooks.

How an attack unfolds

An attacker supplies a crafted section name containing newline and bracket characters to set_value, causing the library to write an additional [core] section that points hooksPath at a malicious directory; when any Git operation later invokes a hook, the attacker's script executes.

How to fix it

Upgrade GitPython to a version that performs newline validation on section and option parameters before passing them to configparser; until then, sanitize all inputs to set_value and avoid using untrusted data for configuration keys.

How to confirm the fix worked

Review source for calls to set_value, confirm that section and option strings are validated for newlines and brackets, and test with inputs containing \n[core] sequences to ensure they are rejected.

Typical attack path

  1. Identify code paths that call GitPython config.set_value with attacker-controlled section or option strings
  2. Craft a section value containing newline and [section] syntax to inject a forged [core] entry
  3. Set hooksPath to a directory containing a malicious executable named after a common hook
  4. Trigger any Git operation that runs hooks to achieve code execution

How to detect it

Search Git repository histories and running processes for unexpected hooksPath directives or pre-commit/post-checkout scripts originating outside the repository; inspect config writes that contain bracket or newline characters in section names.

  • hooksPath=
  • [core]
  • set_value.*\n\[
  • evil_hooks

What your security team should do

  • Prioritize upgrade of GitPython across all repositories once a corrected release is available
  • Add input sanitization for any configuration APIs that accept section or option names
  • Scan codebases for direct use of GitConfigParser.set and related methods
  • Monitor for unexpected [core] or hooksPath entries in .git/config files

The record

Summary The patch for CVE-2026-42215 (GitPython 3.1.49) validates newlines only in the value parameter of set_value(). The section and option parameters are passed to configparser without any newline validation. An attacker who controls the section argument can inject \n to write arbitrary section headers into .git/config, including a forged [core] section with hooksPath pointing to an attacker-controlled directory, leading to RCE when any git hook is triggered. Details File: git/config.py — GitPython 3.1.49 (latest patched version) ```python def set_value(self, section: str, option: str, value) -> "GitConfigParser": value_str = self._value_to_string_safe(value) # only value is validated if not self.has_section(section): self.add_section(section) # section not validated super().set(section, option, value_str) # option not validated return self ``` _write() formats section headers as "[%s]\n" % name. When section = "user]\n[core", this writes [user]\n[core]\n — two valid section headers — into .git/config. PoC ```python import git, os, subprocess repo = git.Repo.init("/tmp/bypass_test") os.makedirs("/tmp/evil_hooks", exist_ok=True) with open("/tmp/evil_hooks/pre-commit", "w") as f: f.write("#!/bin/sh\nid > /tmp/rce_proof.txt\n") os.chmod("/tmp/evil_hooks/pre-commit", 0o755)

Affected packages

Ecosystem Package Introduced Fixed

Related vulnerabilities