CVE-2026-44244

GHSA-v87r-6q3f-2j67 HIGH
Published May 6, 2026

`GitConfigParser.set_value()` passes values to Python's `configparser` without validating for newlines. GitPython's own `_write()` converts embedded newlines into indented continuation lines (e.g. `\n` becomes `\n\t`), but Git still accepts an indented `[core]` stanza as a section header — so the...

Full CISO analysis pending enrichment.

Affected Systems

Package Ecosystem Vulnerable Range Patched
GitPython pip <= 3.1.48 3.1.49
15.6K OpenSSF 5.3 80 dependents Pushed 8d ago 100% patched ~0d to patch Full package profile →

Do you use GitPython? You're affected.

Severity & Risk

CVSS 3.1
7.8 / 10
EPSS
N/A
Exploitation Status
No known exploitation
Sophistication
N/A

Attack Surface

AV AC PR UI S C I A
AV Local
AC Low
PR Low
UI None
S Unchanged
C High
I High
A High

Recommended Action

Patch available

Update GitPython to version 3.1.49

Compliance Impact

Compliance analysis pending. Sign in for full compliance mapping when available.

Frequently Asked Questions

What is CVE-2026-44244?

GitPython: Newline injection in config_writer().set_value() enables RCE via core.hooksPath

Is CVE-2026-44244 actively exploited?

No confirmed active exploitation of CVE-2026-44244 has been reported, but organizations should still patch proactively.

How to fix CVE-2026-44244?

Update to patched version: GitPython 3.1.49.

What is the CVSS score for CVE-2026-44244?

CVE-2026-44244 has a CVSS v3.1 base score of 7.8 (HIGH).

Technical Details

NVD Description

`GitConfigParser.set_value()` passes values to Python's `configparser` without validating for newlines. GitPython's own `_write()` converts embedded newlines into indented continuation lines (e.g. `\n` becomes `\n\t`), but Git still accepts an indented `[core]` stanza as a section header — so the injected `core.hooksPath` becomes effective configuration. Any Git operation that invokes hooks (commit, merge, checkout) will then execute scripts from the attacker-controlled path. The vulnerability is not merely malformed config output: GitPython's own writer converts embedded newlines into indented continuation lines, but Git still accepts an indented `[core]` stanza as a section header, so the injected `core.hooksPath` becomes effective configuration. This was found while auditing MLRun's `project.push()` method, which passes `author_name` and `author_email` directly to `config_writer().set_value()` with no sanitization. Both parameters cross a trust boundary — they are caller-supplied API inputs that end up in `.git/config`. PoC (standalone, no MLRun required): ```python import git, subprocess, os repo = git.Repo("/tmp/testrepo") with repo.config_writer() as cw: cw.set_value("user", "name", "foo\n[core]\nhooksPath=/tmp/hooks") r = subprocess.run(["git", "config", "core.hooksPath"], cwd="/tmp/testrepo", capture_output=True, text=True) assert r.returncode == 0 print(r.stdout.strip()) # /tmp/hooks os.makedirs("/tmp/hooks", exist_ok=True) open("/tmp/hooks/pre-commit", "w").write("#!/bin/sh\nid > /tmp/pwned\n") os.chmod("/tmp/hooks/pre-commit", 0o755) repo.index.add(["README"]) repo.git.commit(m="test") print(open("/tmp/pwned").read()) # uid=... ``` Tested on GitPython 3.1.46, git 2.39+. Impact: This is persistent repo config poisoning. Any user who can supply `author_name` or `author_email` to an application calling `config_writer().set_value()` can redirect Git hook execution to an arbitrary path. In a multi-user or hosted environment (e.g. a shared MLRun server where multiple users push to the same repositories), one user can poison the `.git/config` of a shared repo and have their hooks run in the context of every subsequent Git operation by any user. On single-user deployments, the impact depends on whether the application later invokes Git hooks automatically. Remediation: `set_value()` should raise on CR, LF, or NUL in values rather than silently pass them through: ```python import re if isinstance(value, (str, bytes)) and re.search(r"[\r\n\x00]", str(value)): raise ValueError("Git config values must not contain CR, LF, or NUL") ``` Rejecting is safer than stripping — a stripped newline might indicate the caller is passing unsanitized input at a higher level, and silent normalization masks that. Affected wherever `config_writer().set_value(section, key, user_input)` is called with external input.** GitPython is a dependency of DVC, MLflow, Kedro, and others — worth auditing their `set_value()` call sites for externally influenced inputs.

CVSS Vector

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

Timeline

Published
May 6, 2026
Last Modified
May 6, 2026
First Seen
May 7, 2026