GitPython: 단일 문자 kwarg 값 토큰 밀수를 통한 안전하지 않은 git 옵션 가드 우회로 인해 임의 명령 실행 가능
GitPython의 check_unsafe_options 가드(CVE-2026-42215 / GHSA-2f96에서 도입되고 이후 강화된 제어)는 모든 보호된 메소드(clone/clone_from, fetch/pull/push, ls_remote, iter_commits, blame, archive)에 대해 우회될 수 있습니다. 단일 문자 kwarg의 VALUE 내부에 옵션 토큰을 밀수입합니다. 기본 allow_unsafe_options=False 구성에서는 --upload-pack을 통해 임의의 명령이 실행됩니다.
가드는 kwarg KEYS에서만 후보 옵션 목록을 작성합니다. _option_candidates([], {"n":"--upload-pack=<cmd>"})는 ['-n']을 반환합니다(cmd.py:1042-1046은 값이 아닌 키에서 후보를 파생합니다). -n은 거부 목록에 없으므로 check_unsafe_options가 통과됩니다. 그러나 transform_kwarg('n', value, Split_single_char_options=True)(cmd.py:1600-1606)은 두 개의 argv 토큰 ['-n', '--upload-pack=<cmd>']을 방출합니다. 그런 다음 git은 두 번째 토큰을 --upload-pack으로 구문 분석하고 공격자가 제공한 명령을 실행합니다. 가드는 별도의 argv 토큰이 되는 값을 절대 검사하지 않습니다.
기본 구성에서 호스트 프로세스로 임의의 OS 명령 실행(--upload-pack을 통해)은 모두 이름 전용 _option_candidates를 통해 후보를 빌드하므로 모든 보호된 메소드에 영향을 미칩니다.
``파이썬 git import Repo에서 Repo.clone_from(bare_repo, out_dir, n="--upload-pack=touch /tmp/ACE;git-upload-pack")
보호된 개정 명령의 파일 쓰기 변형: `iter_commits('HEAD', g='--output=/path')` -> 후보 `['-g']` 통과, argv `['-g','--output=/path']`, 피해자 파일이 잘림.
## 공격 체인
1. 항목: 앱은 사용자 제공 옵션 dict -> `Repo.clone_from(url, path, n="--upload-pack=touch /tmp/ACE;git-upload-pack")`을 전달합니다. 가드: base.py의 `check_unsafe_options(options=_option_candidates([], kwargs), unsafe=unsafe_git_clone_options)`. 우회 증명: `_option_candidates([], {"n":"--upload-pack=..."})` -> `['-n']`(키 전용), 거부 목록에 없음 -> UnsafeOptionError 없음(실시간으로 확인됨).
2. 변환: `transform_kwarg('n', value, Split_single_char_options=True)` -> `['-n', '--upload-pack=touch /tmp/ACE;git-upload-pack']`. 가드: 없음(가드가 이미 이름만 후보자에게 전달됨). 우회 증명: 검증된 변환은 두 개의 토큰을 방출합니다.
3. 싱크: `git clone -n --upload-pack='touch ...;git-upload-pack' -- <src> <dst>`; git은 두 번째 토큰을 구문 분석하고 실행합니다. 영향: ACE(마커 생성, 엔드투엔드 확인).
## 증거 우회
HEAD에서 실시간 검증됨(태그 3.1.53): `_option_candidates`는 키 전용 후보 `['-n']`를 반환합니다. `transform_kwargs`는 밀수된 `--upload-pack=` 토큰을 내보냅니다. 페이로드가 포함된 clone_from은 마커 파일을 생성했습니다. 직접 이름 `upload_pack=` 형식으로 인해 UnsafeOptionError가 발생했습니다. 모든 이전 우회(GHSA-rpm5 밑줄 키, GHSA-2f96 긴 옵션 약어, GHSA-v396 결합된 짧은 옵션, GHSA-x2qx 분할 전 다중)는 HEAD에서 차단됩니다. 이는 고유한 kwarg-값->별도 토큰 벡터입니다.
## 영향을 받는 버전
`<= 3.1.53`
## 제안된 수정 사항
`split_single_char_options`가 적용될 때 `_option_candidates`가 단일 문자 kwarg VALUES에서 파생된 후보도 내보내도록 하거나, 재구성된 이름 전용 후보 목록이 아닌 완전히 변환된 argv에 대해 `check_unsafe_options`를 실행하세요.
---
**zx (Jace)**가 보고함 — GitHub: @manus-use
왜 이 VPI인가 (설명가능 · 실험적)
VPI 산정 기준
| 영향도 | 88.00 |
| 악용 신호(추가 악용신호 없음) | ×1.00 |
| VPI | 88.00 |
VPI 공식 vpi-v1 기준