Jeśli śledzisz wpisy na moim blogu, zapewne wiesz, że skupiam się głównie na bezpieczeństwie w kontekście procesu tworzenia oprogramowania. Jednym z kluczowych zagadnień, którym się zajmuję, jest bezpieczeństwo używanych bibliotek. Czy zdajesz sobie sprawę, że istnieją ataki skierowane bezpośrednio na programistów, którzy importują biblioteki w sposób podobny do otrzymywania SMS-ów proszących o dopłatę 1,23 zł do przesyłki zatrzymanej przez kuriera?

Ataki phishingowe

Ataki mające na celu przekonanie użytkownika do kliknięcia w przesłany link są od dawna w czołówce najgroźniejszych zagrożeń w cyberprzestrzeni. Najbardziej typowy scenariusz obejmuje rejestrację domeny, która jest na tyle podobna do znanej marki, by cyberprzestępca mógł się pod nią podszyć. Następnie wysyła taki link do użytkownika z nadzieją, że ten kliknie w niego. Na stronie pojawia się logo Facebooka, ale niezauważalny dla wielu jest fakt, że domena to nie facebook.com, lecz na przykład facebook-app.app.

W ubiegłym tygodniu premiere miał raport CERT Orange za rok 2023 a w nim na potwierdzenie tezy powyżej możecie znaleść takie informacje jak:

Raport CERT Orange z 2023 roku, str. 14

Wykres przedstawiony powyżej może ilustrować skalę zagrożeń (skupiając się głównie na atakach obserwowanych w polskiej przestrzeni internetowej), z którymi na co dzień mierzą się specjaliści ds. bezpieczeństwa. Z drugiej strony pokazuje, z jak dużą czujnością użytkownicy powinni podchodzić do wiadomości, którymi są “atakowani” z różnych stron.

Przykłady domen, pod które podszywają się atakujący

źródło: [1] najczęściej atakowane domeny według CloudFlare wraz z przykładami

Nie jestem ekspertem w tej dziedzinie, ani na co dzień nie analizuję tego typu przypadków. Jeśli jesteś zainteresowany tematem podszywania się pod domeny oraz sposobami, w jakie firmy walczą z tym zagrożeniem, polecam kilka wartościowych materiałów:

  1. https://www.youtube.com/watch?v=7ufih0kr_84 ta prezentacja przedstawia jak niektóre instytucje próbują walczyć aby chronić swoich użytkowników
  2. https://www.youtube.com/watch?v=Z20XNp-luNA ta prezentacja koncentruje się na analizie i zrozumieniu phishingu, ze szczególnym uwzględnieniem jego psychologicznych aspektów.
  3. https://www.youtube.com/watch?v=Sd5NFVc9Wzs ta prezentacja koncentruje się na rosnącej roli zestawów phishingowych w gospodarce cyberprzestępczości.

Instalacja bibliotek programistycznych

W inżynierii oprogramowania przyjęły się dwie główne zasady: KISS – “keep it simple, stupid” (nie przekombinuj) oraz DRY – “don’t repeat yourself” (nie powtarzaj się). Ta druga zasada ogólnie dotyczy unikania powtarzania. Na przykład, jeśli funkcjonalność, tak jak sortowanie, jest już dostępna, dobrą praktyką jest skorzystać z niej zamiast pisać własną funkcję sortującą. Prawdopodobnie możesz sobie wyobrazić, że większość metod realizujących różnorodne logiki biznesowe została już napisana i udostępniona. Aby móc z nich skorzystać, należy pobrać odpowiednią bibliotekę z jakiegoś rejestru lub repozytorium, co umożliwi korzystanie z implementowanych w niej metod i funkcji.

I tutaj przychodzą z pomocą pluginy integracyjne, takie jak Maven, Gradle, npm czy pip, które są kluczowymi narzędziami w procesie rozwoju oprogramowania, ułatwiającym zarządzanie zależnościami oraz automatyzację budowania i dystrybucji aplikacji. Oto jak pomagają one w codziennej pracy programistów i jak można za ich pomocą instalować nowe biblioteki:

  1. Zarządzanie zależnościami: Automatycznie zarządzają zależnościami projektu, pobierając potrzebne biblioteki i ich zależności z centralnych repozytoriów, takich jak Maven Central.
  2. Automatyzacja budowania: Pozwalają na definiowanie procesów budowania projektu, w tym kompilacji, testowania i pakowania aplikacji.
  3. Standardyzacja projektów: Umożliwiają tworzenie standardowych szablonów projektów, co ułatwia współpracę i utrzymanie spójności w wielu projektach.

W praktyce, w zależności od pluginu musimy utrzymywać listę pakietów wykorzystywanych przez naszą aplikacje.

  • dla MVN mamy plik pom.xml
  • dla Gradle mamy build.gradle
  • dla npm mamy packages.json
  • dla PIP mamy requirements.txt

Importowanie pakietów

Zwykle, aby zainstalować jakąś bibliotekę Open Source, wystarczy zmodyfikować kod, np. plik pom.xml, albo skorzystać z konkretnej komendy, jak npm install -g marked. Ta komenda pobierze paczkę z rejestru i automatycznie zmodyfikuje package.json.

Często, gdy programista musi przeprowadzić taką operację, kopiuje kod bezpośrednio z dokumentacji (dostępnej na stronach takich jak npmjs.com, mvnrepository.com/repos/central lub GitHub), co minimalizuje ryzyko pomyłki. Skąd więc wziąć się może zagrożenie?

Zagrożenie pojawia się, gdy próbujemy działać na szybko, „z ręki”, „na słuch”. Na Slacku ktoś może napisać: „wykorzystaj bibliotekę marked z npmjs”, i w efekcie możemy wpisać npm install -g markedjs. Jeśli popełnimy błąd, NPM nas o tym poinformuje, ale co, jeśli taki pakiet jednak istnieje…

źródło: JFrog, przykład złośliwej biblioteki, która podszywa się pod bibliotekę Marked

Jak widzimy na screenie powyżej, na górze znajduję się zrzut z npmjs.com dla poprawnego pakietu. Pod nim znajduję się screen z podrobionego pakietu o nazwie markedjs. Nazwa pakietu, która jest zarówno w adresie URL jak i w nagłówku strony jest napisana mniejszą czcionką niż nagłowek H1 w pliku readme.md, renderowanym na stronie (który jest identyczny co oryginał). Nawet linki do repozytorium z kodem oraz stroną domową projektu są poprawne. Może uśpić czujność, prawda?

Na szczęście popularnie wykorzystywane rejestry, w których internauci i organizacje OpenSource umieszczają artefakty takie jak obrazy dockerowe czy właśnie biblioteki od dawna widzą ten problem i starają się proaktywnie wychwytywać tego typu sytuacje. Dzisiaj pakiet, który przedstawiłem powyżej wygląda tak:

Pakiety, które w ten sposób są usuwane z rejestru można liczyć w dziesiątkach dziennie.

Zagrożenia, które dotyczą zarządzania zależnościami

Tego typu zagrożenia mogą przyjmować 3 formy:

  1. Malicious Package (Złośliwy Pakiet) – Atak polegający na tworzeniu i rozpowszechnianiu pakietów zawierających złośliwy kod podszywając się pod inne znane pakiety. Te pakiety mogą być dodane do publicznych repozytoriów, takich jak npm, PyPI, czy Maven Central. Celem jest Infekcja jak największej liczby systemów poprzez zainstalowanie takiego pakietu jako zależności w różnych projektach. Złośliwe pakiety mogą ukrywać malware, skrypty szpiegujące, ransomware, czy inne formy złośliwego oprogramowania, które mogą być aktywowane po zainstalowaniu.
  2. Trojan Package (Pakiet Trojański) – Pakiety, które z pozoru wyglądają na bezpieczne i użyteczne, ale zawierają ukryty, złośliwy kod. Cel to przekonanie użytkownika do zainstalowania pakietu pod pretekstem jego użyteczności, podczas gdy w rzeczywistości służy on do szkodliwych działań.
  3. Dependency Confusion (Pomyłka Zależności) – Atak wykorzystujący niejednoznaczność i luki w zarządzaniu zależnościami przez systemy budowania aplikacji. Celem jest wykorzystanie błędów w konfiguracji zależności (np. niewłaściwe rozróżnienie między zależnościami wewnętrznymi a publicznymi). Atakujący rejestruje publicznie dostępny pakiet o tej samej nazwie, co używany wewnętrznie przez firmę pakiet, ale z wyższą wersją. Systemy automatycznie wybierają tę publiczną, wyższą wersję, co prowadzi do zainstalowania złośliwego kodu.

OWASP Top 10 dla CICD

Jeśli jeszcze nie widziałeś, OWASP poza popularną listą zagrożeń dla aplikacji Internetowych od jakiegoś czasu udostępnia listę najgroźniejszych zagrożeń dla procesu CICD:

Znalazły się tutaj 2 zagrożenia CICD-SEC-2 oraz CICD-SEC-8, które pośrednio lub bezpośrednio odnoszą się do problemów o których pisze w tym poście. Chcę tym jeszcze bardziej zwrócić Twoją uwagę na zagrożenia, jakie mogą wynikać z braku weryfikacji tego z czego korzysta Twoja aplikacja.

Jak się chronić przed zagrożeniami tego typu?

  1. Przykładaj uwagę do tego co importujesz do swojej aplikacji – jeśli kopiujesz kod, który trafia do pliku pom.xml itp. bierz go z oficjalnych źródeł
  2. Zaimplementuj mechanizm weryfikacji wykorzystywanych bibliotek – dbaj o to aby używać narzędzi, które weryfikują bezpieczeństwo zależności
  3. Twórz aplikacje w bezpiecznej architekturze. W najgorszym scenariuszu, w którym uruchomiony został złośliwy pakiet – powinien mieć on jak najmniejsze pole do popisu, a cała komunikacja wychodząca powinna być domyślnie blokowana.

Referencje:

Tags: