W tym tygodniu fałszywy klient podesłał mi do skrzynki złośliwe repozytorium GitHub, a samo uruchomienie skryptu startowego wymazało dwa dni mojej pracy i ujawniło wszystkie hasła zapisane w mojej przeglądarce.

„Klient” opublikował ofertę pracy na wysoko płatne stanowisko senior engineer, szybko nawiązał kontakt i przesłał profesjonalnie wyglądające repozytorium. Prośba była prosta: sklonuj, uruchom npm run dev i wyślij zrzut ekranu, aby udowodnić, że demo działa – bez umowy, bez sprawdzania przeszłości. W momencie uruchomienia serwera deweloperskiego, ukryty kod w pliku konfiguracyjnym połączył się z serwerem command-and-control (C2), pobrał payload drugiego etapu i rozpoczął wyciąganie danych uwierzytelniających z lokalnej maszyny.

Jak przebiegał atak

Złośliwy payload znajdował się w postcss.config.js – pliku, na który większość deweloperów tylko zerka, ponieważ zazwyczaj zawiera on kilka prostych reguł przetwarzania CSS. W tym przypadku atakujący dopisał linię zaciemnionego (obfuscated) kodu JavaScript daleko po prawej stronie legalnej instrukcji, wypełniając ją spacjami, aby wtopić się w tło. Gdy komenda npm run dev uruchomiła potok (pipeline) PostCSS, ukryta linia wykonała się niezauważona.

Malware wykonało trzy kroki w szybkim następstwie:

  • Kontakt z C2 – otworzyło połączenie sieciowe z serwerem kontrolowanym przez atakującego i zgłosiło zainfekowany host.
  • Pobranie drugiego etapu – pobrało dodatkowy kod zawierający rzeczywistą logikę eksfiltracji danych.
  • Kradzież danych uwierzytelniających z przeglądarki – na systemie macOS zapytało o klucz Chrome Safe Storage przechowywany w systemowym pęku kluczy (keychain). Jeśli użytkownik zatwierdził komunikat pęku kluczy, atakujący przejął każde hasło zapisane w Chrome.

Poza natychmiastową kradzieżą, payload zapisał się w kilku popularnych narzędziach deweloperskich — VS Code, npm, Discord — tak aby każde kolejne uruchomienie tych aplikacji ponownie inicjowało złośliwy kod. Zwykły restart nie usunął infekcji; kolejne npm install lub otwarcie edytora przywracało backdoor.

Czerwone flagi, które często są ignorowane

  • Prośby o uruchomienie kodu przed podpisaniem jakiejkolwiek umowy. Prawidłowe procesy rekrutacyjne zazwyczaj wymagają formalnej umowy przed udostępnieniem jakiejkolwiek własności intelektualnej.
  • Pliki skompresowane podszywające się pod „briefy projektowe”. Archiwa Zip lub RAR mogą ukrywać skrypty wykonywalne lub złośliwe pliki binarne.
  • Prośby o prywatne adresy e-mail, aby „obejść filtry platformy”. Ten podstęp ma na celu przeniesienie rozmowy poza chronioną platformę, na której można zgłosić nadużycie.
  • Opisy stanowisk wymagające od kandydata sfinansowania portfela kryptowalutowego lub zakupu tokenów testowych. Takie żądania są nietypowe dla prawdziwej pracy programistycznej.

Praktyczne kroki, aby zachować bezpieczeństwo

  1. Nigdy nie uruchamiaj kodu nieznajomego bez wcześniejszej inspekcji. Otwórz repozytorium w trybie tylko do odczytu (np. przez widok surowego pliku na GitHubie) i sprawdź każdy skrypt, zwłaszcza pliki konfiguracyjne oraz wpisy w sekcji scripts w package.json.
  2. Traktuj wszystkie załączniki jak zwykły tekst. Jeśli otrzymasz plik zip, wypakuj go w odizolowanym środowisku (sandbox) i sprawdź zawartość, zanim cokolwiek otworzysz.
  3. Używaj dedykowanego menedżera haseł zamiast pamięci przeglądarki. Nawet jeśli klucze przeglądarki zostaną przejęte, skarbiec menedżera haseł pozostanie odizolowany.
  4. Uruchamiaj niepewny kod w odizolowanej maszynie wirtualnej lub kontenerze bez dostępu do sieci. To blokuje atakującemu możliwość połączenia się z serwerem C2.
  5. Włącz uwierzytelnianie dwuskładnikowe (2FA) na wszystkich kontach. Jeśli hasło zostanie skradzione, drugi składnik powstrzyma nieautoryzowane logowanie.
  6. Dbaj o aktualność narzędzi deweloperskich i włącz automatyczne sprawdzanie integralności, jeśli jest to możliwe. Niektóre edytory ostrzegają obecnie, gdy pliki systemowe zostaną zmodyfikowane w nieoczekiwany sposób.

Jeśli podejrzewasz, że uruchomiłeś złośliwy kod, załóż, że system został przejęty. Zrób kopię zapasową niezbędnych danych, sformatuj dysk i przeinstaluj system operacyjny. Zwykły restart nie wyeliminuje mechanizmu utrzymywania się w systemie (persistence), który nadpisuje pliki w popularnych aplikacjach.

Podsumowując: jedna linia ukrytego kodu JavaScript może zmienić rutynowe demo w pełnoskalową operację kradzieży danych uwierzytelniających. Traktuj każde repozytorium jako niepewne, dopóki go nie zweryfikujesz, i spraw, aby izolacja stała się standardowym elementem Twojego procesu pracy. Koszt chwili pośpiechu jest znacznie wyższy niż wysiłek włożony w dwukrotne sprawdzenie pliku.