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
- 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
scriptswpackage.json. - 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.
- 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.
- 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.
- Włącz uwierzytelnianie dwuskładnikowe (2FA) na wszystkich kontach. Jeśli hasło zostanie skradzione, drugi składnik powstrzyma nieautoryzowane logowanie.
- 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.
