dependency confusion (podmiana zależności)
| Po angielsku | dependency confusion |
|---|---|
| Którą formą pisać | po angielsku Polski odpowiednik istnieje, ale w praktyce nikt tak nie pisze. Zostaw angielski, polski trzymaj jako synonim. |
| Inne formy | podmiana zależności · atak na łańcuch dostaw przez repozytorium pakietów |
| Kategoria | Chmura, kontenery i łańcuch dostaw |
Dependency confusion (podmiana zależności) to atak na łańcuch dostaw (supply chain attack), w którym atakujący publikuje w publicznym repozytorium pakiet o tej samej nazwie co wewnętrzna biblioteka firmy. Jeśli menedżer pakietów sprawdza jednocześnie repozytorium prywatne i publiczne, może wybrać wersję atakującego i uruchomić jego kod w procesie budowania. Dokumentacja pip opisuje to wprost jako klasę problemów bezpieczeństwa: atakujący publikuje pakiet o tej samej nazwie w indeksie publicznym, a ten zostaje wybrany zamiast prywatnego [2]. Nazwę techniki nadali badacze, którzy w lutym 2021 roku opisali ją na przykładzie wielkich firm technologicznych [1].
Jak działa
Źródłem problemu jest sposób, w jaki narzędzia łączą kilka źródeł pakietów. Dokumentacja pip mówi, że między indeksami podanymi w --index-url i --extra-index-url nie ma priorytetu: sprawdzane są wszystkie, a wybierane jest „najlepsze” dopasowanie, czyli zwykle najwyższy numer wersji [2]. Wystarczy więc, że atakujący opublikuje pakiet o nazwie wewnętrznej biblioteki z bardzo wysoką wersją.
Warunkiem ataku jest poznanie nazwy wewnętrznego pakietu. Badacze opisani przez Sekuraka automatycznie przeglądali pliki JavaScript publikowane na stronach firm, w których takie nazwy często się pojawiają [1]. Kod w podstawionym pakiecie wysyłał dane do badaczy przez odpowiednio skonstruowane zapytania DNS [1], co działa nawet w mocno odseparowanych sieciach.
Przebieg ataku pokazuje schemat poniżej.
Zachowanie menedżerów pakietów
Podatność nie jest błędem jednego narzędzia, tylko skutkiem konfiguracji. Poszczególne ekosystemy różnią się domyślnym zachowaniem.
| Narzędzie | Zachowanie przy kilku źródłach | Zabezpieczenie |
|---|---|---|
| pip | brak priorytetu, wygrywa najwyższa wersja [2] | jeden indeks, skróty pakietów [2] |
| npm | pakiety bez zakresu są zawsze publiczne [3] | zakres organizacji, np. @firma/ [3] |
| Composer | repozytoria kanoniczne, packagist.org na końcu [4] | nie wyłączać kanoniczności [4] |
| NuGet | równoległe zapytania, kolejność niedeterministyczna [5] | jeden kanał z ustaloną kolejnością [5] |
W npm zakres działa jak przestrzeń nazw: pozwala utworzyć pakiet o nazwie takiej samej jak pakiet innego użytkownika bez konfliktu, a pakiety prywatne zawsze mają zakres [3]. Microsoft zauważa, że NuGet wysyła zapytania do wszystkich kanałów z konfiguracji równolegle i przetwarza odpowiedzi w kolejności nadejścia, co może dawać niespójne wyniki [5].
W WordPressie
Rdzeń WordPressa i wtyczki z katalogu WordPress.org nie są instalowane przez Composera, więc zwykła strona nie jest bezpośrednio narażona. Problem dotyczy firm i agencji, które budują własne wtyczki i motywy z użyciem menedżerów pakietów, a wewnętrzne biblioteki trzymają w prywatnym repozytorium.
Composer. Composer szuka pakietu w najwyższym repozytorium i przechodzi do następnego tylko wtedy, gdy go tam nie ma [4]. Dokumentacja wyjaśnia, że takie kanoniczne traktowanie jest bezpieczniejsze, bo pakiety oczekiwane z najważniejszych repozytoriów nigdy nie zostaną pobrane z innego [4]. Podaje też przykład odwrotny: gdy prywatne repozytorium jest niekanoniczne, a ktoś opublikuje w packagist.org wyższą wersję, Composer może zainstalować niewłaściwy pakiet [4]. Packagist.org jest dodawany domyślnie jako ostatnie repozytorium, chyba że się go wyłączy [4].
npm. Wtyczka z blokami buduje JavaScript przez npm. Wewnętrzna biblioteka nazwana bez zakresu, na przykład firma-ui, jest podatna, bo nazwę bez zakresu może zająć każdy w publicznym rejestrze [3]. Bezpieczniej używać zakresu organizacji.
Nazwy wewnętrznych pakietów wyciekają przez zbudowane pliki JavaScript i mapy źródeł zostawione na produkcji; zob. publicznie dostępne pliki wrażliwe.
Zagrożenia i skutki
Kod z podstawionej zależności uruchamia się tam, gdzie odbywa się instalacja: na komputerze programisty albo w potoku budowania. Dla firmy oznacza to zdalne wykonanie kodu (RCE) wewnątrz sieci i dostęp do sekretów potoku, czyli atak na potok CI/CD. Typowe skutki to eksfiltracja kluczy, tokenów i danych uwierzytelniających, a w dalszej kolejności podmiana budowanego oprogramowania.
MITRE ATT&CK klasyfikuje takie działania jako kompromitację zależności i narzędzi programistycznych, obejmującą popularne pakiety pip i npm używane jako zależności w wielu aplikacjach [7].
Jak się bronić
- Jedno źródło pakietów. Microsoft zaleca, aby plik konfiguracyjny, na przykład
.npmrcalbonuget.config, wskazywał tylko jeden kanał, który sam pobiera pakiety z rejestrów publicznych w ustalonej kolejności [5]. Dokumentacja pip odradza używanie--extra-index-urldo szukania pakietów prywatnych [2]. - Przestrzenie nazw. W npm wewnętrzne pakiety publikuje się w zakresie organizacji [3]. W Composerze nazwa pakietu zawiera prefiks dostawcy, a prywatne repozytorium powinno pozostać kanoniczne [4].
- Blokowanie wersji i skróty. MITRE zaleca przypinanie zależności do konkretnych wersji zamiast pobierania najnowszych przy każdym budowaniu [7]. Tryb sprawdzania skrótów w pip wymaga skrótu dla każdej zależności [2].
- Rezerwacja nazw. Po incydencie opisanym niżej zespół PyTorch zarejestrował w PyPI pusty pakiet o nazwie zależności, aby problem się nie powtórzył [6].
- Inwentaryzacja. Wykaz SBOM (wykaz komponentów oprogramowania) i zarządzanie podatnościami pozwalają ustalić, które projekty używają danej zależności. Pokrewne ataki to typosquatting i slopsquatting.
Historia i przykłady
Badanie z 2021 roku. 9 lutego 2021 roku Sekurak opisał wyniki badaczy, którzy wykonali swój kod w systemach Apple, Netflixa, Shopify, Ubera, PayPala i Microsoftu, publikując pakiety w npm, PyPI i RubyGems [1]. W ramach programów bug bounty otrzymali po 30 tysięcy dolarów od Shopify, Apple i PayPala oraz 40 tysięcy dolarów od Microsoftu [1].
PyTorch, grudzień 2022. Instalacje nocnych wersji PyTorch przez pip na Linuksie między 25 a 30 grudnia 2022 roku pobierały zależność torchtriton z PyPI zamiast z indeksu projektu [6]. Zespół PyTorch wyjaśnił, że indeks PyPI miał pierwszeństwo, więc zainstalowany był złośliwy pakiet o tej samej nazwie [6]. Program w pakiecie zbierał informacje o systemie, zawartość plików /etc/passwd, .gitconfig i katalogu .ssh, a następnie wysyłał je przez zaszyfrowane zapytania DNS [6]. Stabilne wydania PyTorch nie były zagrożone [6].
Przypisy
7- [1] Zaskakująca metoda infekcji wielkich (i mniejszych) firm. Wykonali swój kod w systemach Apple, Netflixa, Shopify, Ubera, PayPala, Microsoftu. Końca nie widać · Sekurak
- [2] pip install — pip documentation · Python Packaging Authority
- [3] About scopes · npm Docs
- [4] Repository priorities · Composer
- [5] What are upstream sources? — Azure Artifacts · Microsoft Learn
- [6] Compromised PyTorch-nightly dependency chain between December 25th and December 30th, 2022 · PyTorch
- [7] Supply Chain Compromise: Compromise Software Dependencies and Development Tools (T1195.001) · MITRE ATT&CK