W sieci dostarczania treści cdnjs, oferowanej przez firmę Cloudflare w celu przyspieszenia dostarczania bibliotek JavaScript, zidentyfikowano krytyczną lukę, która umożliwia wykonanie dowolnego kodu na serwerach CDN. Niebezpieczeństwo problemu jest potęgowane przez fakt, że z tego serwisu korzysta około 12,7% wszystkich stron internetowych, a kompromitacja infrastruktury pozwala na podmienianie bibliotek dostarczanych przez dowolną z tych stron.
Usługa cdnjs pobiera pakiety z Git lub repozytorium NPM, a następnie umożliwia dowolnej stronie korzystanie z sieci dostarczania treści Cloudflare do przyspieszenia ładowania bibliotek JavaScript za darmo. Podczas analizy kodu komponentów cdnjs opublikowanego na GitHubie odkryto, że do rozpakowywania pakietów NPM w archiwach tgz używany jest standardowy moduł archive/tar w języku Go, który zwraca listę plików tak, jak są, bez normalizacji ścieżek. W przypadku, gdy skrypt rozpakowuje zawartość na podstawie podanej listy, obecność w archiwum plików w postaci „../../../../../../tmp/test” może prowadzić do nadpisania dowolnych plików w systemie, w zależności od uprawnień.
Założono, że atakujący może złożyć wniosek o dodanie swojej biblioteki do cdnjs i załadować do repozytorium NPM specjalnie przygotowane archiwum zawierające pliki z symbolami „../” w ścieżkach. Na serwerach cdnjs okresowo wykonywana jest operacja „autoupdate”, w której obsługa ładuje nowe wersje proponowanej biblioteki i rozpakowuje zawartość. Dzięki plikom z ścieżkami „../” atakujący może doprowadzić do nadpisania plików ze skryptami usługi i wykonania swojego kodu na serwerze którym dokonano rozpakowywania.
W przypadku pobierania aktualizacji z Git stwierdzono, że obsługa pobierająca aktualizacje nie uwzględniała dowiązań symbolicznych podczas kopiowania plików z Gita. Ta właściwość umożliwiała organizację odczytu jakichkolwiek plików z serwery poprzez dodawanie dowiązań symbolicznych do Gita.
Eksperymenty z demonstracją włamania do cdnjs w celu uzyskania nagrody na HackerOne rozpoczęto od weryfikacji hipotezy dotyczącej odczytu plików. Do repozytorium Git biblioteki JavaScript przekazywanej przez CDN dodano symboliczne odwołanie test.js, wskazujące na plik /proc/self/maps. Po publikacji nowej wersji biblioteki, mechanizm aktualizacji przetworzył to repozytorium i opublikował wskazany plik w cdnjs (test.js został utworzony jako symboliczne odwołanie i przy zapytaniu o ten plik zwracał zawartość /proc/self/maps).
Podstawiając symboliczne odwołanie do pliku /proc/self/environ, autor badania zauważył, że w przekazanych danych znajdują się wartości zmiennych środowiskowych GITHUB_REPO_API_KEY i WORKERS_KV_API_TOKEN. W pierwszej zmiennej przechowywany był klucz do API umożliwiający zapis do repozytorium robocdnjs na GitHubie. W drugiej zmiennej przechowywany był token do magazynu KV w cdnjs. Wykorzystując uzyskane informacje, przestępca mógł wprowadzić zmiany w cdnjs i całkowicie skompromitować infrastrukturę.
Źródło: opennet.ru
