CSIRTS // UNIFIED SECURITY ADVISORY FEEDSYS ● ONLINE · POWERED BY INTELFUSIONS.COM

GHSA-r9mr-m37c-5fr3: GitPython: Unsafe git option guard bypass via single-character kwarg value token smuggling enables arbitrary command execution

highCVSS 8.8
Summary GitPython's check_unsafe_options guard (the control introduced by CVE-2026-42215 / GHSA-2f96 and hardened since) can be bypassed for every guarded method (clone/clone_from, fetch/pull/push, ls_remote, iter_commits, blame, archive) by smuggling an option token inside the VALUE of a single-character kwarg. In the default allow_unsafe_options=False configuration this yields arbitrary command execution via --upload-pack. Root Cause The guard builds its candidate option list from kwarg KEYS only: _option_candidates([], {"n":"--upload-pack=<cmd>"}) returns ['-n'] (cmd.py:1042-1046 derives the candidate from the key, never the value). -n is not on the denylist, so check_unsafe_options passes. But transform_kwarg('n', value, split_single_char_options=True) (cmd.py:1600-1606) emits two argv tokens ['-n', '--upload-pack=<cmd>']. git then parses the second token as --upload-pack and executes the attacker-supplied command. The guard never inspects the value that becomes a separate argv token. Impact Arbitrary OS command execution as the host process (via --upload-pack) in the default configuration, affecting all guarded methods since they all build candidates through the name-only _option_candidates. Proof of Concept from git import Repo Repo.clone_from(bare_repo, out_dir, n="--upload-pack=touch /tmp/ACE;git-upload-pack") /tmp/ACE created -> ACE. Direct-name form upload_pack="..." is correctly BLOCKED. File-write variant on a guarded revision command: iter_commits('HEAD', g='--output=/path') -> candidate ['-g'] passes, argv ['-g','--output=/path'], victim file truncated. Attack Chain 1. Entry: app forwards a user-supplied options dict -> Repo.clone_from(url, path, n="--upload-pack=touch /tmp/ACE;git-upload-pack"). Guard: check_unsafe_options(options=_option_candidates([], kwargs), unsafe=unsafe_git_clone_options) at base.py. Bypass proof: _option_candidates([], {"n":"--upload-pack=..."}) -> ['-n'] (key-only), not on denylist -> no UnsafeOptionError (verified live)

Details

Source
GitHub Security Advisories (INTL · database · site)
Severity
high — CVSS 8.8
Published
2026-07-24
Last updated
2026-07-24
Exploitation
Not in CISA KEV at last sync

Original advisory: https://github.com/advisories/GHSA-r9mr-m37c-5fr3

More from GitHub Security Advisories