Trzej badacze spędzili miesiące na nieatakowaniu piaskownicy

Eilon Cohen, Dan Lisichkin i Ariel Fogel z Pillar Security postawili wąskie pytanie o piaskownice dostarczane razem z agentami kodującymi opartymi na AI. Nie o to, czy mury wytrzymują, lecz o to, czy stoją we właściwym miejscu. 20 lipca 2026 roku zaczęli publikować odpowiedź w cyklu, który nazwali Week of Sandbox Escapes, po jednym tekście dziennie, o Cursorze, OpenAI Codex CLI, Google Gemini CLI i Google Antigravity.

Za każdym razem agent zachowywał się poprawnie. Nie wyszedł poza przyznaną mu przestrzeń roboczą i nie złamał żadnej reguły, której piaskownica pilnuje. Zapisał plik. Proces spoza piaskownicy odczytał ten plik, uznał go za wiarygodny i wykonał to, co w nim stało. Do ucieczki doszło, choć agent ani razu nie dotknął granicy.

Pillar zamyka ustalenie w jednym zdaniu: zasięg rażenia agenta to nie proces agenta, lecz wszystko, co agent może zapisać, a czemu host później zaufa. To zdanie jest sednem sprawy i wyjaśnia, dlaczego łatanie pojedynczych błędów tematu nie zamyka.

Jedno gniazdo tłumaczy trzy z czterech produktów

Najczytelniejsze ustalenie jest zarazem najmniej egzotyczne. Codex CLI, Cursor i Gemini CLI mogły ze swoich piaskownic sięgnąć do lokalnego gniazda Dockera. Uprzywilejowany demon na hoście uruchomi kontener każdemu, kto umie się z nim porozumieć, a taki kontener działa już całkowicie poza piaskownicą. Jeden biuletyn bezpieczeństwa, GHSA-v4xv-rqh3-w9mc, obejmuje trzy z czterech badanych produktów. Błąd jest naprawiony.

Codex miał jeszcze drugi problem, innego rodzaju. Jego lista poleceń uznanych za bezpieczne ufała poleceniom po nazwie. Przepuszczała git show jako operację wyłącznie odczytu, nie biorąc pod uwagę, co niebezpieczne argumenty przekazane do git show potrafią w rzeczywistości zrobić. Poprawiono to w wersji 0.95.0, a za zgłoszenie wypłacono nagrodę w kategorii podatności o wysokiej wadze.

Czytane razem, oba przypadki układają się we wzorzec. Oba to listy dozwolonych. Oba napisano pod kątem tego, co operator widzi, czyli ścieżki gniazda i nazwy polecenia, a nie pod kątem tego, co kryje się za nimi, gdy już się do nich dotrze.

Ucieczki poszły przez pliki, którym twój edytor i tak ufa

Cursor dostarczył trzy przypadki. Agent mógł podmienić interpreter w wirtualnym środowisku Pythona i poczekać, aż uruchomi go rozszerzenie Pythona samego edytora, które działa bez piaskownicy. Mógł założyć katalog Gita pod niestandardową nazwą, tak że reguły piaskownicy oparte na ścieżkach przestawały pasować, a potem pozwolić, by wychwycił go fsmonitor. Mógł też podrzucić do przestrzeni roboczej konfigurację hooka, którą narzędzia wykonywały poza piaskownicą. Ten ostatni przypadek ma numer CVE-2026-48124 i biuletyn GHSA-pc9j-3qc2-95wv, a wszystkie trzy naprawiono w Cursorze 3.0.0.

Dwa ustalenia Google pochodzą z tej samej rodziny. Profil Seatbelt dla macOS stojący za Antigravity napisano jako listę zakazów, która przepuszcza wszystko, czego wprost nie wymieniono, a konfiguracja zadań .vscode potrafiła obejść zabezpieczenia Secure Mode. Google napisał badaczom, że raport jest wyjątkowej jakości, po czym zaklasyfikował ustalenia jako trudne do wykorzystania, bo wymagają socjotechniki, i na tej podstawie obniżył ich wagę.

Klasyfikacja broni się we własnej logice, ale dla kogoś, kto te narzędzia u siebie uruchamia, nic z niej nie wynika. Socjotechnika w przypadku agenta to zdanie w pliku README, komentarz pod zgłoszeniem albo akapit w dokumentacji zależności. Czytanie niezaufanego tekstu to zwyczajny dzień pracy agenta.

Granica, którą kupiłeś, to nie granica, którą masz

Każdy z tych produktów przedstawia piaskownicę jako zabezpieczenie, dzięki któremu autonomiczne programowanie staje się dopuszczalne. Taką odpowiedź dostaje przegląd bezpieczeństwa i z tego powodu wydano zgody. Badanie pokazuje, że piaskownica panuje nad jedną rzeczą, nad procesem agenta. Nigdy nie była obietnicą dotyczącą przestrzeni roboczej.

To przestrzeń robocza jest właściwą powierzchnią ataku, bo czyta ją długa lista procesów zaprojektowanych całe lata przed agentami, a każdy z nich zakłada, że to, co czyta, napisał człowiek. Rozszerzenie Pythona. Demon Gita. Gniazdo Dockera. Hook pre-commit. Instalator zależności. Runner CI klonujący gałąź. Żadnego z nich nie zbudowano po to, by traktować zawartość repozytorium jako wrogie wejście, a każdy z nich właśnie tak dziś ją traktuje.

Przedmiot nadzoru wybrano więc źle. Właściciele zatwierdzali agenty. Polityki wymaga natomiast przestrzeń robocza, a reguła jest krótka: repozytorium, do którego agent AI ma prawo zapisu, jest niezaufanym wejściem dla każdego procesu położonego dalej, na równi z plikiem przesłanym przez obcą osobę.

Co zmienić w tym tygodniu

Zacznij od gniazda, bo jeden biuletyn objął trzy z czterech produktów. Żaden agent kodujący nie potrzebuje dostępu do gniazda Dockera, a jego odebranie to zmiana konfiguracji, nie projekt. Potem zaktualizuj wersje. Cursor 3.0.0 i Codex CLI 0.95.0 to naprawione linie, a narzędzia deweloperskie aktualizują się osobno u każdego użytkownika, a nie w całej flocie naraz, więc poprawka wydana przez dostawcę to nie to samo co poprawka w rękach twoich inżynierów.

Trwała zmiana dotyczy tego, gdzie agenty działają. Gałąź, której dotknął agent, powinna trafiać do CI jako niezaufana, co w praktyce znaczy, że potok nie uruchamia pochodzących z niej hooków, zadań ani interpreterów, dopóki człowiek nie zatwierdzi zmian. To decyzja o potoku, a nie o narzędziu, i przetrwa kolejne ujawnienie.

Na gruncie NIS2 incydent, który zaczyna się w edytorze programisty, a kończy w twoim potoku produkcyjnym, podlega zgłoszeniu w tym samym terminie co każdy inny. Obowiązek nie rozróżnia napastnika, który wyłudził dane od inżyniera phishingiem, od agenta, który przeczytał zatruty plik README, więc zabezpieczenie musi stać tam, gdzie potok potrafi je wyegzekwować.