CVE-2026-87817 dotyczy GitPythona przed 3.1.60. Problem to niewystarczająca walidacja lokalizacji git directory: złośliwe repozytorium może użyć śledzonych plików (gitdir, commondir, HEAD) do podszycia się pod strukturę Gita i umieścić malicious pre-commit hook w kontrolowanym katalogu. Gdy aplikacja wywoła index.commit(), hook uruchamia arbitrary code. Ciekawe jest to, że payload dostarczany jest jako repo data, a execution następuje dopiero podczas późniejszej operacji biblioteki.
index.commit() uruchamia pre-commit hook w kontekście procesu.Attack path: dane, które stają się kodem
To nie jest klasyczne „uruchomiłeś skrypt z repo”. Użytkownik może sądzić, że jedynie pracuje na danych Git. Warunki exploitacji: attacker kontroluje repo, repo zostaje otwarte/sklonowane w podatnym workflow, aplikacja dochodzi do index.commit(), a hook zostaje odnaleziony przez zmanipulowaną strukturę. Czyli package present != automatically exploitable — reachability jest kluczowe.
Dlaczego SCA myli się w obie strony
False positive operacyjny: GitPython jest zainstalowane, ale aplikacja tylko czyta historię, nigdy nie otwiera untrusted repos i nie woła commit — attack path bywa nieosiągalny. False negative: GitPython jest transitive dependency narzędzia CI/CD, dependency updatera albo AI agenta, który klonuje dowolne repozytoria — wtedy pojedynczy package finding ma ogromny blast radius. Szczególnie narażony jest wzorzec PR/repo URL → clone → modify files → index.commit() → push w botach code review, dependency updaterach, AI coding agents i release automation.
Weryfikacja na dwóch poziomach
Nie wystarczy pip freeze | grep GitPython. Component verification: GitPython ≥ 3.1.60. Workflow verification: CI image przebudowany, workery zrestartowane, długowieczne agenty na nowej wersji, brak starego package w cache virtualenv/kontenera, lockfile realnie rozwiązuje 3.1.60+. Dla kontenerów sprawdź runtime image digest, nie tylko manifest repo. Compensating controls do czasu upgrade: nie otwieraj untrusted repos, wyłącz workflow wykonujące commit, sandboxuj proces, używaj disposable workers, ogranicz sekrety joba, nie montuj host SSH credentials do build container.
Idealny temat na VEX
Dla jednej organizacji: GitPython present + untrusted repos: no + index.commit(): unreachable → not exploitable. Dla innej: GitPython present + public repo URLs accepted + index.commit() reachable + secrets mounted → high business risk. Ta sama paczka i wersja, zupełnie inna realna ekspozycja. Jeśli system przetwarzał attacker-controlled repos i wykonywał commits przed patchem, warto przejrzeć CI logs, child processes przy commit, zmiany filesystem, nowe dostępy do credentiali, egress i artifact tampering — samo skasowanie repo nie wystarcza, jeśli hook już się wykonał.
Powiązane na blogu
- VS Code: repo jako control plane — metadane repozytorium jako powierzchnia ataku
- functype-mcp: package specifier jako RCE — install i execution w jednym workflow
Źródła
- VulnCheck Advisory, 09.09.2026 — vulncheck.com
- GitHub Security Advisory GHSA-239g-whfq-7xj9 — github.com
Nota redakcyjna: stan informacji 10 września 2026. CVE-2026-87817 (GitPython < 3.1.60): impersonacja git directory prowadzi do wykonania pre-commit hooka przy index.commit(). Artykuł podkreśla reachability (które workflowy dochodzą do commitu untrusted repo) i dwupoziomową weryfikację, nie tylko numer paczki.