
ZCode potajemnie wysyła całą historię Git na serwery Alibaba Cloud
ZCode, desktopowa aplikacja programistyczna od Z.ai, po zalogowaniu użytkownika po cichu pakuje cały workspace – wraz z pełną historią .git, cache’em LFS i reflogami – i wysyła go do chmury Aliyun OSS. Odkrycie należy do programisty ukrywającego się pod nickiem ferstar, który przebadał aplikację metodą reverse engineeringu i opisał wyniki na swoim blogu.
TL;DR: Programista ferstar przebadał deskę ZCode od Z.ai i odkrył, że aplikacja po zalogowaniu po cichu pakuje cały workspace, w tym pełną historię .git, cache LFS i reflogi, po czym wysyła ją do Aliyun OSS. Klucz deszyfrujący przechowuje serwer, przełączniki w interfejsie nie zatrzymują przesyłania, a polityka prywatności nie wspomina o takiej praktyce.
Co dokładnie odkrył programista reverse-engineeringu ZCode?
ferstar ustalił, że ZCode w stanie zalogowanym automatycznie tworzy migawki całego katalogu roboczego i wysyła je do zewnętrznego magazynu obiektowego Aliyun OSS. W spakowanej paczce znajduje się pełna historia repozytorium Git, cache Git LFS oraz reflogi, czyli dane, które w wielu projektach obejmują także pracę sprzed lat. W swoim poście na X badacz zapytał wprost firmę Z.ai, dlaczego aplikacja robi to bez zgody użytkownika, wskazując jednocześnie na trzy problemy: serwerowy klucz deszyfrujący, brak wyłącznika w interfejsie oraz brak informacji w polityce prywatności. Na przykład opis całej analizy opublikował 18 września na swoim blogu, wraz z pełną ścieżką techniczną od wykrycia do wniosków.
Całość zaczęła się przypadkiem. ferstar podczas porządkowania dysku zauważył, że katalog ~/.zcode zajmuje ponad 700 MB, a następnie postanowił sprawdzić, co tak naprawdę siedzi w środku. Z tego pozornie błahego pytania wynikła pełna analiza aplikacji, którą polecam przeczytać w całości – źródło.
Dlaczego archiwum o rozmiarze 313 MB zwróciło uwagę badacza?
Pierwszym sygnałem był plik archiwum o rozmiarze 313 MB, który utknął w stanie „pending”, czyli oczekiwania na wysyłkę. Tak duży plik w katalogu narzędzia do programowania to dobry powód, by zadać pytanie, co on zawiera i dokąd zmierza. ferstar zaczął więc śledzić logi aplikacji, a następnie dotarł do plików asar, w których spakowany jest kod desktopowej aplikacji Electron.
Dalsza analiza pokazała, że w spakowanym workspace niemal 90% objętości stanowił katalog .git. Zatem to, co aplikacja definiuje jako „snapshot projektu”, w praktyce oznacza pełną historię wersji, tagi, gałęzie i obiekty LFS. Dla firmowych repozytoriów to potencjalnie najcenniejsza część całego kodu. W testowanym przez badacza workspace znajdowało się łącznie 42 411 plików przygotowanych do wysłania.
Gdzie trafiają migawki z ZCode i jak wygląda ścieżka przesyłania?
Migawki trafiają do magazynu obiektowego Aliyun OSS, czyli infrastruktury chmurowej należącej do Alibaba Cloud. Ścieżka przesyłania wygląda tak: aplikacja w tle pakuje workspace, tworzy zaszyfrowane archiwum, po czym odpytuje backend o parametry uploadu i wysyła paczkę do bucketu w OSS. Cały proces rozgrywa się bez widocznych komunikatów w interfejsie.
Przebieg można opisać w kilku krokach:
- aplikacja wykrywa stan zalogowania użytkownika,
- w tle pakuje cały katalog roboczy razem z .git, cache LFS i reflogami,
- archiwum jest szyfrowane, ale klucz kontroluje serwer,
- paczka trafia do Aliyun OSS, a lokalnie pozostaje ślad w postaci dużych plików,
- przełączniki dostępne w UI nie przerywają tego procesu.
W rezultacie nawet użytkownik, który świadomie wyłączył opcje synchronizacji w ustawieniach, nie ma gwarancji, że dane nie opuszczą jego maszyny. To właśnie ten rozdźwięk między interfejsem a rzeczywistym zachowaniem aplikacji budzi największe obawy.
Dlaczego klucz deszyfrujący należy do serwera, a nie do użytkownika?
Archiva tworzone przez ZCode są szyfrowane, jednak klucz deszyfrujący przechowuje serwer, a nie użytkownik lokalny. W praktyce oznacza to, że szyfrowanie nie chroni prywatności programisty wobec operatora usługi – to on dysponuje jedynym kompletem danych potrzebnych do odczytania migawki. Co więcej, użytkownik nie ma żadnej technicznej możliwości przejęcia kontroli nad tym mechanizmem, bo klucz nigdy nie opuszcza infrastruktury Z.ai.
Z perspektywy bezpieczeństwa to istotny szczegół. Szyfrowanie po stronie klienta ma sens wtedy, gdy klucz pozostaje u właściciela danych. Gdy klucz trzyma serwer, mamy do czynienia z kontrolą dostępu po stronie dostawcy, a nie z ochroną treści. Dlatego ferstar wskazał ten element jako jeden z najpoważniejszych problemów całego mechanizmu.
Moim zdaniem (i na blogu piszę o tym często, choćby w tekście ZCode: Claude Code from the Makers of GLM) warto traktować każdy katalog .git jako dane wrażliwe. Zawiera on nie tylko kod, ale też historię decyzji, adresy commitów i czasem dane wrażliwe zaciągnięte przypadkiem. Przykłady takich wycieków znanych z historii – choćby wyciek 12 TB ze Steama – pokazują skalę potencjalnych strat, gdy archiwa wersji trafiają tam, gdzie nie powinny.
Co tak naprawdę znajduje się w przesyłanych pakietach?
W spakowanych migawkach ZCode znajduje się niemal cała zawartość katalogu roboczego, a około 90% objętości stanowi katalog .git. To oznacza pełną historię commitów, gałęzie, tagi, cache Git LFS oraz reflogi. W testowanym przez ferstara workspace przygotowano do wysłania łącznie 42 411 plików. Innymi słowy, aplikacja nie wysyła obecnego stanu kodu, lecz kompletną historię projektu.
Co więcej, reflogi rejestrują także operacje lokalne, które nigdy nie trafiły do zdalnego repozytorium. Dla zespołów oznacza to potencjalne ujawnienie eksperymentalnych gałęzi, porzuconych podejść czy danych wcommitowanych przypadkowo. Zatem zakres przesyłanych danych wykracza poza to, co widzi serwer Git w firmie. Nie można natomiast potwierdzić na podstawie źródeł, czy aplikacja filtruje jakiekolwiek pliki przed pakowaniem – analiza ferstara wskazuje raczej na pakowanie całości.
Czy przełączniki w interfejsie zatrzymują wysyłanie danych?
Nie. ferstar ustalił, że opcje dostępne w ustawieniach ZCode nie przerywają procesu tworzenia i wysyłania migawek. Użytkownik może wyłączyć synchronizację w UI, a aplikacja mimo to nadal pakuje workspace i przesyła go do Aliyun OSS. Ta rozbieżność między interfejsem a rzeczywistym zachowaniem była jednym z głównych zarzutów w poście na X, w którym badacz zapytał wprost firmę Z.ai o powody takiego działania.
Na przykład toggles w aplikacji działają tu wyłącznie kosmetycznie – dają złudzenie kontroli, nie rzeczywisty wyłącznik. Wobec tego użytkownik, który świadomie zdecydował o braku synchronizacji, nie ma żadnej technicznej gwarancji respektowania tej decyzji. Serwer z kolei przechowuje jedyny klucz deszyfrujący, więc nawet zaszyfrowane paczki pozostają czytelne dla operatora usługi. Brak działającego wyłącznika to zatem problem konstrukcyjny, nie kosmetyczny.
Co na ten temat mówi polityka prywatności Z.ai?
Polityka prywatności Z.ai nie informuje o pakowaniu całych workspace i wysyłaniu pełnej historii Git do Aliyun OSS. ferstar wskazał ten brak wprost jako jedną z trzech głównych nieprawidłowości obok serwerowego klucza i nieaktywnych przełączników. Innymi słowy, aplikacja wykonuje operację, o której dokumentacja milczy.
Zatem użytkownik nie może na podstawie dostępnych dokumentów ustalić, do czego migawki są wykorzystywane ani jak długo są przechowywane. W takiej sytuacji rozsądne założenie jest jedno: jeśli dane opuściły maszynę, trzeba liczyć się z ich dalszym istnieniem poza kontrolą autora.
Jak można zablokować to zachowanie na poziomie systemu?
Ponieważ przełączniki w UI nie działają, jedyną skuteczną barierą pozostaje kontrola na poziomie systemu operacyjnego. badacz opisał w analizie sposoby blokady komunikacji aplikacji, choć szczegółowa konfiguracja zależy od środowiska. Działania, które mają sens:
- uruchamianie ZCode wyłącznie w izolowanym środowisku, na przykład w kontenerze lub maszynie wirtualnej,
- blokowanie ruchu sieciowego aplikacji na poziomie firewalla do momentu zakończenia pracy nad kodem,
- obserwowanie katalogu ~/.zcode pod kątem rosnących plików archiwów, bo duże paczki w stanie „pending” sygnalizują przygotowywaną wysyłkę,
- oddzielenie firmowych repozytoriów od maszyn, na których ZCode ma konto zalogowane,
- monitorowanie ruchu wychodzącego do infrastruktury Alibaba Cloud.
Na przykład sama obecność archiwum utknęłego w kolejce – jak w przypadku pliku o rozmiarze 313 MB – bywa pierwszym sygnałem ostrzegawczym. Zatem regularny podgląd tego katalogu to najprostsza forma kontroli. Pełną ścieżkę analizy opisuje autor w źródle.
Co ta sytuacja mówi o zaufaniu do narzędzi AI do programowania?
Pokazuje, że narzędzia agenticzne z dostępem do całego workspace wymagają traktowania jak oprogramowanie z pełnym dostępem do danych, a nie jak zwykły edytor. ZCode łączy trzy cechy podnoszące ryzyko: pakowanie całości katalogu roboczego, brak działającego wyłącznika oraz milczenie polityki prywatności. Żaden z tych elementów osobno nie musiałby być dyskwalifikujący. Razem tworzą mechanizm przesyłania danych, o którym użytkownik nie wie.
Dlatego analiza ferstara ma wartość wykraczającą poza jeden produkt. W ZCode: Claude Code from the Makers of GLM pisałem o aplikacji jako narzędziu programistycznym, a dzisiejsze odkrycie pokazuje drugą stronę takiej integracji. Z kolei historia wycieków, choćby wyciek 12 TB ze Steama, udowadnia, że skutki ujawnienia archiwów wersji odciskają się latami. Narzędzia działające w tle wymagają więc audytu, nie zaufania na słowo.
Często zadawane pytania
Czy ZCode przesyła dane nawet gdy użytkownik tego nie chce?
Tak. Zgodnie z analizą ferstara aplikacja w stanie zalogowanym pakuje workspace i wysyła migawki do Aliyun OSS niezależnie od ustawień. Przełączniki w interfejsie nie przerywają tego procesu, a w spakowanej paczce testowego workspace znalazło się 42 411 plików, w tym pełna historia .git.
Kto może odszyfrować przesłane migawki workspace?
Klucz deszyfrujący przechowuje wyłącznie serwer Z.ai, a nie użytkownik lokalny. Zatem szyfrowanie chroni paczki w transporcie, ale nie przed operatorem usługi, który dysponuje jedynym kompletem danych do odczytu. Użytkownik nie ma technicznej możliwości przejęcia kontroli nad tym mechanizmem.
Czy polityka prywatności Z.ai informuje o takim przesyłaniu?
Nie. ferstar wskazał w swoim poście na X, że polityka prywatności zawiera zerowe informacje o pakowaniu workspace i wysyłaniu pełnej historii Git do Aliyun OSS. Źródła nie potwierdzają żadnego oświadczenia ani aktualizacji dokumentów ze strony firmy po publikacji analizy 18 września.
Jak użytkownik może ochronić swoje repozytoria?
Najskuteczniejsze są bariery na poziomie systemu, bo ustawienia aplikacji nie działają: uruchamianie ZCode w izolacji, blokada ruchu sieciowego firewalla oraz trzymanie firmowych repozytoriów poza maszynami z zalogowanym kontem. Ponadto kontrola katalogu ~/.zcode pozwala wykryć przygotowywane archiwa. W Artifacts: wersjonowana pamięć, która mówi w języku Git opisywałem, dlaczego historia w Gicie sama w sobie bywa danymi wrażliwymi.
Podsumowanie
Sprawa ZCode daje kilka konkretnych wniosków:
- aplikacja w stanie zalogowanym pakuje cały workspace razem z .git, cache LFS i reflogami, po czym wysyła go do Aliyun OSS,
- przełączniki w interfejsie nie zatrzymują przesyłania, więc jedyną skuteczną kontrolą jest firewall lub izolacja,
- klucz deszyfrujący przechowuje serwer, więc szyfrowanie nie ogranicza dostępu operatora usługi,
- polityka prywatności nie wspomina o tej praktyce,
- katalog ~/.zcode i duże pliki w stanie „pending” pozwalają wykryć przygotowywaną wysyłkę.
Jeśli korzystasz z ZCode lub podobnego narzędzia agenticznego, sprawdź dziś ustawienia sieciowe aplikacji i zajrzyj do katalogu ~/.zcode. Potwierdzone mechanizmy opisuje pełna analiza ferstara – warto ją przeczytać w całości, zanim kolejne migawki opuszczą Twoją maszynę.