Dwie złośliwe wersje axios trafiły na npm 31 marca 2026. Maintainerzy usunęli je po trzech godzinach. Pipeline podpisywania aplikacji macOS w OpenAI zdążył w tym czasie pobrać i wykonać jedną z nich.
Ścieżka ataku była prosta. Atakujący przejął maszynę głównego maintainera axios przez socjotechnikę, obszedł 2FA i opublikował dwie zatrute wersje: axios@1.14.1 i axios@0.30.4. Obie deklarowały fantomową zależność plain-crypto-js@4.2.1, której wcześniej nigdy nie było na npm. Ukryty w niej ładunek to wieloplatformowy dropper RAT zaprojektowany do utrwalania i wykradania zmiennych środowiskowych, kluczy SSH oraz poświadczeń.
Jak złapało OpenAI
Workflow GitHub Actions do podpisywania kodu macOS w OpenAI odwoływał się do axios przez pływający tag wersji, czyli standardowy zakres semver, którego większość projektów używa bez zastanowienia. Pipeline CI uruchomił się w trakcie trzygodzinnego okna kompromitacji, pobrał zatrutą wersję axios@1.14.1 i wykonał ją jako część builda.
Pipeline podpisywania z definicji działa z podwyższonymi uprawnieniami. Potrzebuje dostępu do certyfikatów podpisywania, entitlementów i tokenów notaryzacji. Trudno o gorszy kontekst do uruchamiania niezweryfikowanego kodu.
Przebieg ataku
| Krok | Działanie | Rezultat |
|---|---|---|
| 1 | Socjotechnika + RAT na maszynie maintainera | Dostęp do konta npm |
| 2 | Ominięcie 2FA, publikacja axios@1.14.1 | Złośliwy pakiet na npm |
| 3 | OpenAI GH Actions pobrał pływający tag | Zatruta zależność w buildzie |
| 4 | Krok builda uruchomił dropper RAT | Pipeline podpisywania skompromitowany |
| 5 | Ekspozycja certyfikatów | Wszystkie aplikacje macOS do ponownego podpisania |
OpenAI twierdzi, że dane użytkowników nie zostały naruszone. Dobór słów ma tu znaczenie. Kiedy dropper RAT uruchomi się wewnątrz Twojego pipeline'u podpisywania, "dane nie zostały naruszone" i "nie wykryliśmy naruszenia" opisują dwie różne rzeczy. Szczegółów dochodzenia technicznego jak dotąd nie opublikowano.
Sprzątanie
OpenAI unieważnia wszystkie certyfikaty podpisywania macOS i przebudowuje od zera cztery produkty: ChatGPT Desktop, Codex, Atlas i Codex CLI. Każdy użytkownik macOS będzie musiał zaktualizować aplikacje. Twardy deadline to 8 maja 2026, po tej dacie starsze wersje przestaną działać.
To właściwa reakcja. Rotacja certyfikatów jest kosztowna i uciążliwa, ale alternatywą jest zaufanie, że dropper RAT w Twoim środowisku podpisywania niczego nie dotknął. Złe miejsce na rozdawanie zaufania.
Chart data
| Label | Value |
|---|---|
| Publikacja na npm (00:21) | 0 min |
| Zgłoszenia społeczności (01:00) | 39 min |
| Kontakt z npm (01:38) | 77 min |
| Usunięcie pakietów (03:15) | 174 min |
Prawdziwa lekcja
Kompromitacja axios dotknęła znacznie więcej projektów niż sam OpenAI. Przypadek OpenAI jest najbardziej pouczający, bo pokazuje, co się dzieje, kiedy pływająca zależność spotyka uprzywilejowane środowisko CI.
Przypięcie do hasha commita zamiast taga semver zapobiegłoby temu całkowicie. Tak samo kontrola lockfile'a przerywająca build przy nieoczekiwanych nowych zależnościach. Tak samo uruchomienie podpisywania w izolowanym środowisku bez dostępu sieciowego do npm. Żadna z tych praktyk nie jest egzotyczna, po prostu nie są domyślne.
Pełne ujawnienie: rozwijam PromptScript. Ten sam problem nieprzypiętych zdalnych źródeł ma tam inny kształt. promptscript.lock zapisuje dokładne hashe commitów dla każdego zdalnego importu, więc reprodukowalność obejmuje cały projekt, a nie pojedynczy pakiet. Opiszę to szerzej w osobnym artykule.
Trzy godziny, jeden pływający tag, rotacja certyfikatów w całej linii produktów. Łańcuch dostaw jest dokładnie tak mocny, jak najbardziej leniwy wpis w Twoim package.json.
Źródła: OpenAI