Poznaj AI! Obejrzyj bezpłatnie szkolenie jutro o godz. 10:00 lub 19:00
Asystent AI kradnie prywatny kod z GitLaba za pomocą prompt injection
Agenty LLM na stałe wpisały się w dziedzinę rozwoju oprogramowania. Chociaż nie zanosi się na to, aby miały zastąpić programistów, to ich integracja ma znacznie ułatwić i przyspieszyć ich pracę. Oprócz narzędzi takich jak Cursor.sh (IDE wspierane generatywnym AI) firmy oferujące platformy do przechowywania kodu w repozytoriach Git (GitHub i Gitlab) umożliwiają implementację “cyfrowych asystentów” takich jak GitHub Copilot czy Gitlab Duo. W założeniach produkty te mają oferować analizę kodu, commitów czy wspomagać programistów w rozumieniu zgłoszonych podatności. Jednak jak w większości rozwiązań opartych na LLMach, we wczesnym stadium rozwoju, pojawia się ten sam problem – wstrzykiwanie promptów.
TLDR:
- Duo, czyli asystent dostępny w serwisie GitLab był podatny na ataki prompt injection.
- Niefortunny zbieg okoliczności spowodował, że odpowiedzi LLMa pozwalały na renderowanie niektórych tagów HTML, a to z kolei umożliwiło eksfiltrację danych z prywatnych repozytoriów, issues, merge requestów na serwery kontrolowane przez atakujących
- Atak mógł zostać ukryty przy pomocy Unicode i kodowania base16
Badacze z Legit znaleźli szereg podatności, które opierają się na umieszczeniu dodatkowych instrukcji w kodzie umieszczonym w repozytorium, ale nie tylko. Miejscem wstrzyknięcia mogą być też commity, merge requesty, issues czy komentarze. Aktywny asystent może zostać zaatakowany na wielu płaszczyznach. Efektem takich nadużyć może być kradzież kodu z prywatnych repozytoriów, manipulacje odpowiedziami, które trafiają do użytkowników czy wyciek zgłoszonych, ale nie opublikowanych jeszcze podatności.

Aby utrudnić wykrycie ataku, badacze zastosowali znane sztuczki takie jak ASCII Smuggling, czyli metodę opartą na wykorzystaniu tagów Unicode niewidocznych w interfejsie użytkownika. Takie prompty, mogą być niezauważalne dla użytkownika, jednak LLM przetworzy je w normalny sposób (i wykona…). Inne metody ukrywania złośliwych instrukcji dla modeli językowych, to np. kodowanie do base16 czy wykorzystanie KaTeXu.
W wyniku zamieszczenia dodatkowych instrukcji dla modelu można go zmusić, na przykład, do umieszczenia złośliwego kodu w repozytorium lub do zatajenia przed użytkownikiem faktu wprowadzenia niepożądanych zmian, takich jak dodanie backdoorów w nowym commicie.

Developerzy mogą zostać zaatakowani też w trochę inny sposób – model może zostać wykorzystany do phishingu, przekonania programisty, aby ten kliknął w link dostarczony przez atakującego. Wykorzystanie markdowna do renderowania odpowiedzi asystenta znacznie ułatwia ten proceder.

Jakby tego było mało, to sam interfejs Duo pozwala na bardzo ciekawy atak – odpowiedzi generowane przez model w formacie markdown są przesyłane strumieniowo do frontendu, gdzie są dynamicznie renderowane (przy użyciu biblioteki asynchronicznej). To powoduje, że możliwe było dodanie prompta, który powodował załączenie w odpowiedzi HTMLa, który następnie był poprawnie parsowany przez przeglądarkę.

Tym samym atakujący mógł otrzymać informację (pingback) w momencie gdy przeglądarka programisty załaduje obrazek z zewnętrznego, kontrolowanego przez atakującego, serwera.
W tej sytuacji nasuwa się oczywiste pytanie – czy ten primitive pozwala na atak XSS (Cross-Site Scripting)? Autorzy badania oczywiście też o tym pomyśleli – niestety jak zauważyli, dane generowane przez AI trafiają do funkcji sanityzującej z biblioteki DOMPurify, która dobrze radzi sobie z XSSami.
Przedstawione podatności nie odpowiadają jednak na pytanie, jak atakujący może wykradać dane z prywatnych projektów. Odpowiedź, do jakiej dotarli badacze, znajduje się w dokumentacji asystenta, który działa w kontekście użytkownika-ofiary (tzn. ma takie same uprawnienia). Oznacza to, że atakujący, który nie ma dostępu do prywatnego projektu, wciąż może zmusić model do złośliwego zachowania, jeśli zostanie uruchomiony przez użytkownika z odpowiednimi uprawnieniami.
Przykładowo – Duo może wytłumaczyć zawartość merge requestu, mimo że użytkownik w danym momencie go nie analizuje.

Struktura URL merge requestu jest przewidywalna, więc istnieje szansa na jej odgadnięcie (lub dokonanie ataku iteracyjnego do momentu trafienia odpowiedniego identyfikatora).
Wstrzykując (oczywiście ukryte z wykorzystaniem wyżej przedstawionych technik) polecenie do publicznego projektu, atakujący może poprosić o wyciągnięcie konkretnych informacji z prywatnego projektu użytkownika. Gdy ten skorzysta z asystenta, wykonana zostanie także ukryta część wstrzykniętego prompta, polegająca na zakodowaniu wartości pożądanych przez atakującego i ich eksfiltracji na jego serwer.

Jak słusznie zauważają badacze – to nie wszystkie możliwości wykorzystania Duo. Użytkownicy mają też dostęp do prywatnych issue, które mogą zawierać poufne informacje o podatnościach odkrytych w projekcie. Korzystanie z asystenta przez użytkownika z uprawnieniami do takich informacji, może skutkować ich wyciekiem – zanim jeszcze zostaną załatane. To powoduje, że ataki na asystentów takich jak Duo, są bardzo wygodną i stosunkowo prostą metodą na pozyskiwanie błędów typu one-day.
Gitlab odpowiedział na zgłoszenie badaczy, potwierdzając podatności i wprowadził niezbędne łatki ograniczające renderowanie tagów HTML w odpowiedzi modelu oraz przeciwdziałające wstrzykiwaniu promptów. O ile ten pierwszy problem był stosunkowo prosty do rozwiązania, o tyle prompt injection nie jest podatnością prostą do wyeliminowania co prawdopodobnie wkrótce zaowocuje nowatorskim jailbreakiem.
Badaczom gratulujemy pomysłowego znaleziska!
~Black Hat Logan