Poprawka do dwóch plików konfiguracyjnych w publicznym repozytorium Snowflake’a czekała na scalenie dziesięć miesięcy. Do gałęzi głównej weszła 18 czerwca. Razem z nią weszła podatność pozwalająca wykonać dowolne polecenie na maszynie budującej projekt. Pięć dni później sięgnęła po nią firma badawcza Wiz, a całą sprawę opisała jako lukę stworzoną przez Copilot Autofix. Publiczna historia commitów tego nie potwierdza. Przypis do narzędzia GitHuba rzeczywiście w tym commicie jest, tylko pochodzi ze zmiany w innym pliku, która akurat podnosiła bezpieczeństwo. Wzorzec, którym dało się wejść, pojawił się osiemnaście dni później, osobnym commitem i bez przypisu do jakiegokolwiek narzędzia AI.
Co naprawdę zmienił commit współautorstwa Copilot Autofix
Zacznijmy od warstwy, której nie trzeba nikomu wierzyć na słowo. Pull request numer 1218 jest publiczny razem ze wszystkimi commitami. Otworzył go inżynier Snowflake’a 7 sierpnia 2025 roku, żeby przerobić dwa przepływy pracy obsługujące Jirę.
Drugi commit w tej gałęzi ma opis “copilot suggestion” i przypis wskazujący Copilot Autofix jako współautora. Dotyczy pliku jira_close.yml. Zmiana jest drobna, siedem linii dodanych i trzy usunięte. Polega na wyprowadzeniu wstawek ${{ }} z ciała skryptu do bloku env:. To dokładnie ten zabieg, który dokumentacja GitHuba zaleca jako obronę przed wstrzyknięciem.
Wkład narzędzia w tym pull requeście szedł więc w stronę bezpieczeństwa. Nie tylko nie usunęło zabezpieczenia, ale je dołożyło, i to w pliku, którego atak w ogóle nie dotyczył.
Podatny wzorzec pochodzi z zupełnie innego commita
Kod, przez który dało się wejść, jest w drugim pliku, jira_issue.yml. Wprowadził go commit z 25 sierpnia 2025 roku, osiemnaście dni po podpowiedzi Copilota, opisany jako refaktor tworzenia zgłoszeń w Jirze. Nie ma w nim przypisu do Copilota ani do żadnego innego narzędzia AI. Historia przypisuje go inżynierowi, który otworzył pull request.
Trzeba tu być uczciwym co do granic dowodu. Brak przypisu nie dowodzi, że przy pisaniu tej linii nic nie pomagało, bo nie każde narzędzie zostawia po sobie ślad w commicie. Dowodzi natomiast czegoś węższego i wystarczającego: udokumentowany wkład Copilot Autofix w tym pull requeście jest gdzie indziej i wygląda inaczej.
Zmiana zastąpiła gotową akcję z rynku GitHuba własnym skryptem powłoki wołającym Jirę przez curl. Tytuł zgłoszenia wjeżdża w tym skrypcie prosto do polecenia, w konstrukcji TITLE=$(echo '${{ github.event.issue.title }}' | sed ...).
Warto się przy tym zatrzymać, bo tu leży sedno sprostowania. Wiz pisze, że narzędzie AI usunęło istniejący w repozytorium wzorzec sanityzacji wejścia i zastąpiło go bezpośrednim rozwinięciem tekstu w skrypcie powłoki. Stan sprzed tej zmiany żadnego skryptu powłoki nie zawierał. Tytuł szedł do gotowej akcji atlassian/gajira-create. Nie wiemy, jak ta akcja radziła sobie z wejściem w środku, i nie musimy tego wiedzieć. Wystarczy, że w repozytorium nie widać usunięcia istniejącego wzorca sanityzacji w skrypcie powłoki, bo takiego skryptu wcześniej tam nie było.
Skąd w commicie scalającym wzięło się autorstwo AI
Wiz wskazuje konkretny commit z 18 czerwca 2026 roku i pisze, że wzorzec trafił tam kilka dni przed odkryciem. Ten commit istnieje i faktycznie ma w opisie przypis do narzędzia. Jest to jednak commit scalający cały pull request metodą squash.
Squash zgniata wszystkie commity gałęzi w jeden. Domyślna treść wiadomości takiego commita składana jest z opisów commitów scalanych, więc przypisy z nich mogą do niej trafić. W tym commicie stoją trzy linie Co-authored-by: dwaj inżynierowie i Copilot. Te same przypisy występują w commitach gałęzi. Data jest datą scalenia, nie datą napisania kodu. Dziesięć miesięcy historii tej gałęzi znika z widoku. Zostaje jeden wpis z jedną datą oraz listą współautorów, którzy w rzeczywistości pisali różne rzeczy w różnych plikach.
Warto zaznaczyć, czego z tego nie wiadomo. Treść wiadomości commita scalającego da się przed zatwierdzeniem zmienić ręcznie, a domyślny format zależy od ustawień repozytorium. Publiczna historia nie mówi więc, czy te przypisy znalazły się tam automatycznie, czy ktoś je zostawił świadomie. Wiadomo tyle, że powstał zapis, w którym narzędzie AI figuruje jako współautor commita obejmującego plik, którego jego udokumentowana podpowiedź nie dotyczyła. I taki zapis idzie potem dalej, do raportów i podsumowań.
Dlaczego zapis autorstwa zaczyna mieć znaczenie
Tu wchodzimy już w naszą ocenę, a nie w ustalenia z repozytorium, i warto to powiedzieć wprost. Przypis o współautorstwie w commicie był kiedyś ciekawostką. Robi się z niego dana, po którą coraz łatwiej sięgnąć, gdy pada pytanie, jaka część kodu w firmie powstaje z udziałem modeli. Jest pod ręką i wygląda na obiektywną, a to zwykle wystarczy, żeby trafiła do zestawienia.
Kłopot w tym, że przypis Co-authored-by służy do przypisania jednego commita wielu współautorom i tyle. Nie był projektowany jako miernik czegokolwiek. Ta historia pokazuje, że zapis może objąć plik, którego udokumentowana podpowiedź narzędzia nie dotyczyła. Liczby budowane na takich przypisach trzeba więc traktować jako przybliżenie, a nie pomiar.
Praktyczny wniosek jest nudny i dlatego łatwo go pominąć. Zanim zapis autorstwa posłuży za dowód w czymkolwiek, warto wiedzieć, jak powstaje w Waszym repozytorium. Sposób scalania ma tu znaczenie, bo decyduje, czy w historii zostaną osobne commity, czy jeden sklejony wpis.
Jak tytuł zgłoszenia zamieniał się w polecenie powłoki
Sama podatność jest w tej historii dowodem, a nie bohaterem, więc wystarczy jej kilka zdań. Przepływ pracy uruchamiał się przy założeniu nowego zgłoszenia. Tytuł zgłoszenia lądował wewnątrz apostrofów w poleceniu echo, a apostrof wpisany w tytule zamykał ten ciąg i pozwalał dopisać własne polecenie.
Tak działa cała ta klasa błędów w przepływach pracy. Dane pochodzące od kogokolwiek z zewnątrz trafiają do polecenia wykonywanego przez zautomatyzowany proces po stronie projektu. Dokumentacja GitHuba opisuje to wprost i dlatego zaleca przenoszenie takich wstawek do zmiennych środowiskowych.
Ta klasa błędu jest znana od lat i ma własną nazwę w dokumentacji GitHuba. Warto jednak zwrócić uwagę na jeden szczegół, bo tłumaczy, dlaczego takie rzeczy przechodzą przez przegląd. Zmiana wyglądała na porządki. Wymieniono zewnętrzną akcję na własny skrypt, co zwykle uchodzi za ograniczanie zależności, czyli za dobrą praktykę. Ryzyko siedziało nie w intencji, tylko w jednej linii w środku, i widać je dopiero wtedy, gdy zapyta się o zachowanie przy złośliwym tytule zgłoszenia.
Co ustalił agent Wiza i czego z tego nie wynika
Dalsza część opisu pochodzi wyłącznie od Wiza i tak trzeba ją traktować, bo firma opisuje skuteczność własnego produktu. Według niej podatność znalazł i wykorzystał samodzielnie działający agent, bez udziału człowieka, 23 czerwca. Agent wyprowadził token dostępowy do Jiry, uwierzytelniający jako konto działu jakości, z prawem odczytu projektów inżynierii, zgodności bezpieczeństwa i programu bug bounty.
Snowflake załatał to tego samego dnia, a token zrotował dzień później. Firma podaje też, że analiza logów audytowych nie wykazała dostępu żadnego podmiotu zewnętrznego w pięciodniowym oknie ekspozycji. To akurat ustalenie samego Snowflake’a i jest ono ważne, bo przesądza, że nie mówimy o włamaniu ani o wycieku danych. Sprawę ujawniono publicznie 25 lipca.
Nie zmienia to jednak sensu całej historii. Agent znalazł prawdziwy błąd w prawdziwym repozytorium i zrobił to szybko. Wątpliwość dotyczy wyłącznie tego, komu przypisano autorstwo błędu, i akurat ta część została opisana niezgodnie z zapisem w repozytorium. Nie twierdzimy, że ktoś zmyślił tę atrybucję, bo o intencji nie wiemy nic i nie mamy jak jej ustalić. Jednym z możliwych wyjaśnień jest odczytanie opisu commita scalającego zamiast historii gałęzi. Ten opis sam z siebie sugeruje współautorstwo narzędzia dla całej zmiany, choć nic nie mówi o tym, kto napisał którą linię.
Pierwsza Misja AI · Kodożercy
Używasz AI codziennie – ale czy robisz to dobrze?
Kurs Pierwsza Misja AI pokaże Ci techniki promptowania, które naprawdę działają. Praktyczne ćwiczenia z prawdziwym GPT-4, gamifikacja i certyfikat.
Sprawdź program kursu →

Najczęstsze pytania
Czy Copilot Autofix jest niebezpieczny?
Z tej historii nic takiego nie wynika, a jeden przypadek i tak nie byłby oceną narzędzia. W tym konkretnym pull requeście podpowiedź Copilot Autofix utwardziła przepływ pracy, przenosząc wstawki szablonu do zmiennych środowiskowych. Realny wniosek dotyczy nie narzędzia, tylko sposobu, w jaki czytamy przypisy autorstwa w commitach.
Czy dane Snowflake’a wyciekły?
Nie. Snowflake podaje, że analiza logów audytowych nie wykazała dostępu podmiotu zewnętrznego w oknie, w którym podatność była otwarta. Dostęp uzyskała firma badawcza, która zgłosiła sprawę producentowi, a token został zrotowany następnego dnia. Ustalenie Snowflake’a dotyczy więc braku nieuprawnionego dostępu z zewnątrz, a nie braku jakiegokolwiek udziału osób trzecich.
Kto czyta u was poprawkę bezpieczeństwa napisaną przez model
Praktyczna część tej historii nie dotyczy Copilota ani Wiza. Dotyczy układu, w którym gałąź stoi otwarta dziesięć miesięcy, rośnie o kolejne commity i zostaje scalona długo po tym, jak powstała. Nie wiemy, jak wyglądał przegląd w tym konkretnym przypadku, i nie zamierzamy tego zgadywać. Wiemy tylko, że taki rozjazd w czasie jest sytuacją, w której najłatwiej coś przeoczyć, bo kontekst sprzed roku zdążył wyparować wszystkim.
Kiedy do tego dochodzą podpowiedzi generowane automatycznie, przegląd zmienia się z czytania cudzego kodu w czytanie kodu bez autora. Podobny mechanizm opisywaliśmy przy kampanii podrzucającej pull requesty przez serwery MCP. Widać go też przy eksperymentach z wieloma agentami naraz. Liczba automatycznych wkładów w jedno repozytorium będzie rosła, a nie malała, i to jest chyba jedyna bezpieczna prognoza w tym temacie.
Nie chodzi przy tym o zakazywanie narzędzi. Podpowiedź, która przeniosła sekrety do bloku env:, była dobra i zrobiła dokładnie to, co powinna. Chodzi o to, że przegląd nastawiony na pytanie “czy ta zmiana działa” przepuszcza zmiany, które działają, a przy okazji coś otwierają. Pytanie “co ta zmiana zdejmuje” trzeba zadać osobno, bo samo się nie zadaje.
Stąd krótka lista rzeczy do sprawdzenia u siebie:
- czy gałąź otwarta dłużej niż kwartał wraca do przeglądu przed scaleniem, czy wchodzi na starej zgodzie,
- czy ktoś czyta pełen diff commita scalającego, a nie tylko poszczególne commity z gałęzi,
- czy przepływy pracy z uprawnieniami do sekretów mają osobną ścieżkę przeglądu,
- czy przypis o współautorstwie narzędzia AI jest u was traktowany jako informacja, czy jako podpis.
Podsumowanie
Najciekawsze w tej sprawie nie jest to, że kod z podatnością wszedł do gałęzi głównej, bo to akurat przydarza się każdemu. Ciekawe jest to, jak łatwo powstał zapis przypisujący ten kod maszynie. Nie trzeba było do tego niczyjej złej woli. Wystarczył sposób scalania, przypis pochodzący z jednego commita gałęzi i lektura opisu zamiast lektury zmian. Warto z tego wyciągnąć jeden nawyk, zanim podobny opis trafi do raportu w Waszej firmie. Zanim uznacie, że coś napisał model, sprawdźcie który commit i który plik, a nie sam przypis pod spodem. I zadajcie sobie drugie pytanie, trudniejsze: kto u Was czyta poprawkę bezpieczeństwa napisaną przez model, zanim wejdzie do gałęzi głównej.
Newsletter · DevstockAcademy & Kodożercy
Bądź na bieżąco ze światem IT, AI i automatyzacji
Co wtorek: newsy z branży, praktyczne tipy i narzędzia które warto znać. Zero spamu.




