Npm install i pobrany trojan – złośliwa wersja paczki axios

avlab.pl 2 godzin temu
Zdjęcie: RAT npm install


30 marca pojawiła się niepokojąca informacja o udostępnieniu wersji bardzo popularnej paczki NPM axios. Atak był o tyle dopracowany, iż złośliwy kod nie został dodany bezpośrednio do modułu axios. Zamiast tego zmodyfikowano zależności, aby przy instalacji pobierana była adekwatna szkodliwa paczka, czyli plain-crypt-js. Logika NPM domyślnie pozwala na wykonanie kodu przez zależności (w ramach postinstall), co z kolei umożliwiło zainstalowanie trojana RAT – malware, które pobiera polecenia z serwera atakującego.

Trojan był dostępny w trzech wersjach dla systemów Windows, Linux i macOS. W tym wypadku nie sprawdziło się więc podejście, iż wyłącznie Windows jest podatny na działanie złośliwego oprogramowania. Co więcej, trojan po instalacji wykonywał pewne działania „maskujące” – plik package.json był podmieniany na oficjalną wersję oraz usuwano katalog plain-crypt-js z node_modules. Na komputerze użytkownika pozostawał więc sam trojan, bez istotnych śladów wskazujących na jego pochodzenie.

Polecam zapoznanie się także z opisem przedstawionym przez zespół Elastic Security Labs, bo zawiera istotne informacje, ale w bardziej skondensowanej i czytelnej formie niż w przypadku źródłowego opracowania. Widoczne są lokalizacje, w których dostarczone malware było zapisywane.

Niestety samo usunięcie wymienionych plików nie będzie wystarczające, ponieważ atakujący mógł skutecznie uzyskać nieautoryzowany dostęp do wrażliwych danych. W przypadku projektów programistycznych może to być m.in. zestaw kluczy API, haseł, sekretów czy „ukrytych” adresów URL zawartych w plikach .env.

Złośliwe wersje axios to 1.14.1 i 0.30.4. Wersja 1.14.1 była oznaczona jako latest, więc jeżeli aktualizowaliśmy ostatnio moduły bez określonych konkretnych wersji, to najpewniej została pobrana. Należy zweryfikować, czy w pliku package.json zdefiniowana jest wersja latest. jeżeli tak i wykonywano aktualizacje, należy przeprowadzić zmiany wszelkich dostępów, a system zainstalowany na hoście najlepiej przeinstalować (lub przywrócić obraz dysku z wcześniejszej kopii zapasowej).

axios jest często wykorzystywaną paczką, o czym świadczy ilość pobrań – w ubiegłym tygodniu było to ponad 100 milionów. Nie jest to w żadnym wypadku podrzędny projekt.

Powodem naruszenia (to przykład ataku supply-chain) było przejęcie konta lidera projektu Jasona Saaymana. Warto zresztą przeczytać dyskusję na temat tej sytuacji w serwisie GitHub.

Kolejny raz jest okazja do przypomnienia o dobrej praktyce unikania tagu latest (bądź niedefiniowania żadnego, co sugeruje właśnie latest) – niezależnie, czy w kontekście wersji paczek czy też obrazów Docker. Użycie latest powoduje, iż za każdym razem otrzymamy wersję najnowszą. Pomijając tak skrajne sytuacje jak opisana, nie mamy pewności, iż najnowsza możliwa wersja będzie kompatybilna z naszym środowiskiem. Zdarzało się także, iż pod tagiem latest ukryta była wadliwa wersja (testy też mogą zawodne), co spowodowało różne przestoje w pracy.

Istotne jest również użycie lokalnego serwera hostującego paczki (NPM, Maven, Composer itd.) bądź obrazy. Dzięki temu unikamy każdorazowego odpytywania serwerów źródłowych, a to wiąże się z szybszym czasem pobierania – kluczowym przede wszystkim w procesach CI/CD. Dodatkowo ewentualna niedostępność oficjalnego repozytorium nie będzie miała w takim scenariuszu większego wpływu. Nie zapominajmy, iż zastosowanie lokalnego repozytorium paczek pozwoli też na zablokowanie dostępu do sieci Internet chociażby z maszyn używanych w CI/CD.

Równie znaczące jest korzystanie z cache. W przypadku lokalnej pracy nie będzie to aż tak zauważalne, bo nie wymaga żadnej konfiguracji. Użycie cache w ramach CI/CD może wymagać dostosowania – nie jest to wyjątkowo skomplikowana czynność – natomiast korzyści potrafią być znaczące (czas budowy / kompilacji zostanie zredukowany się do kilku minut).

Trzeba też odnotować korzyści, jakie ma zastosowanie konteneryzacji w samym CI/CD. choćby jeżeli pobrana została zainfekowana paczka, to szkodliwy kod wykonał się jedynie na poziomie kontenera – nie miał dostępu do innych zasobów, a kontener został automatycznie usunięty natychmiast po zakończeniu etapu budowania nowej wersji naszej aplikacji. jeżeli runner nie miał dostępu do Internetu, to już zupełnie możemy wykluczyć szanse na kompromitację naszego środowiska. Oczywiście ważne jest bezpieczne przechowywanie sekretów, a najlepiej unikanie zapisywania kluczy itd. w repozytorium, ale ogólne podejście z użyciem kontenerów zamiast budowy bezpośrednio na serwerach jest całkowicie optymalne.

Zaznaczenia wymaga, iż w opisywanym ataku złośliwy kod działał w systemie użytkownika, który pobrał paczkę axios. jeżeli w przyszłości zmiana dodana przez atakującego będzie wykonywana po stronie klienta aplikacji, to rzecz jasna powyższa praktyka nie zapobiegnie negatywnym skutkom.

Podobne ataki mają szanse na powodzenie, bo obecne trendy programistyczne raczej skłaniają się ku korzystaniu z gotowych rozwiązań zamiast wytwarzania całego systemu „manualnie”. axios to zwykły klient HTTP, a jego funkcjonalności są już praktycznie natywne w nowszych wersjach Node.js, co jednak w żaden sposób nie wpływa na zmniejszenie jego rozpoznawalności. Masowe korzystanie z AI również nie poprawia tej sytuacji, bo modele raczej unikają stosowania tzw. dobrych praktyk.

Idź do oryginalnego materiału