To nie jest najlepszy dzień dla użytkowników NPM. Błąd w wersji 5.7.0 może uszkodzić wasz system operacyjny. Wygląda na to, że na skutek pomyłek twórców narzędzia do użytkowników trafiła bardzo popsuta jego wersja.
Pierwszy powszechnie zauważony raport problemu pochodzi od użytkownika Crunkle, który kilkanaście godzin temu utworzył na GitHubie zgłoszenie #19883 dotyczące anomalii, jakie zaobserwował po aktualizacji NPMa.
Po uruchomieniu komendy sudo npm z konta użytkownika, zgłaszający zauważył, że w jego systemie doszło do zmiany właściciela katalogów takich jak /etc, /usr, czy /boot. Zmiany zostały rekursywnie zastosowane również do wszystkich plików znajdujących się w tych katalogach, a właścicielem, zamiast roota, stało się konto z którego uruchomiono polecenie.
Zgłaszający wskazał, że winę za takie zachowanie NPMa prawdopodobnie ponosi commit 94227e1, a konkretnie błędne składanie ścieżek. Powiązany fragment kodu w oryginale miał ułatwiać życie użytkownikom poprzez automatyczne tworzenie nieistniejących katalogów (np. node_modules). Po wspomnianej poprawce funkcja tworzenia katalogów została rozszerzona również o sprawdzanie poprawności ustawienia uprawnień, co działo się za sprawą pomocniczego modułu correct-mkdir.js.
Kontrowersje
Błąd związany z wyliczaniem ścieżek prawdopodobnie istniał już wcześniej, ale nie został wykryty dopóki udogodnienia ograniczały się wyłącznie do tworzenia nieistniejących katalogów. Wszak omyłkowa próba stworzenia już istniejącego katalogu / albo /etc sama w sobie nie powoduje niczego złego, ale uruchomienie w takiej ścieżce komendy chown -R user:user / już tak.
Jeszcze więcej kontrowersji dodaje całej sprawie fakt, że na GitHubie wersja v5.7.0 została oznaczona jako „Pre-release” (wersja testowa/eksperymentalna), ale notka na ten temat z bloga npmjs.com w żaden sposób o tym nie wspomina. Brak wyróżnień w nazwach wersji próbnych (tzn. prefiksu pre, alpha, albo podobnego) stoi w konflikcie z przyzwyczajeniami użytkowników, a to zwiększa szansę omyłkowego wgrania poprawki na produkcję.
Oliwy do ognia dodaje fakt, że wywołanie komendy npm update -g powoduje aktualizację z wersji v5.6.0 do wersji v5.7.0, pomimo że rzekomo jest to „pre-release”.
Ale to nie koniec niespodzianek, ponieważ tydzień wcześniej ukazało się zgłoszenie #19829, które dokumentowało błąd w zrozumiały i prawidłowy sposób. Zgłaszający odwołał się nawet bezpośrednio do autora błędnego commitu:
/do wiadomości @iarna, który jest autorem linkowanego patcha :)
Pomimo wyraźnych starań, raport został całkowicie zignorowany, choć wtedy istniała znacznie większa szansa na rozwiązanie problemu w „bezbolesny” sposób.
Co robić?
Trzy godziny temu ukazał się patch w postaci wersji v5.7.1, która usuwa niebezpieczne zachowanie wprowadzone przez wersję poprzednią. Jeżeli jednak posiadacie NPM w wersji v5.6.0 albo niższej, sugerujemy tymczasowo wstrzymać się z wykonywaniem jakichkolwiek aktualizacji do momentu aż sytuacja się ustabilizuje.
Osobom posiadającym NPMa w wersji v5.7.0 sugerujemy wykonanie upgrade, ale bez wywoływania przy tym komendy npm. Najbezpieczniejszym rozwiązaniem będzie odinstalowanie menedżera i zainstalowanie go od nowa w „bezpiecznej” wersji.
Podsumowanie
Wystąpienie błędu po raz kolejny uderza w społeczność skupioną wokół Node.js. Na chwilę obecną nie wiadomo ile systemów zostało przypadkowo uszkodzonych. Warto podkreślić, że oprócz spowodowania awarii, przypadkowa zmiana uprawnień programów wykorzystujących setuid może wiązać się z poważnymi problemami bezpieczeństwa. Zaistniała sytuacja może być również dobrym sygnałem do ponownego przeanalizowania swoich wyborów dotyczących używanych narzędzi developerskich. Po raz kolejny bowiem (zapewnie nieumyślne) działanie pojedynczej osoby przyniosło ze sobą ryzyko wystąpienia globalnych problemów, co świadczy o tym, że proces rozwoju NPMa wciąż jest bardzo niedojrzały.
PS. Warto zapoznać się również z historią zgłoszenia #9359, gdzie zgłoszenie opatrzone tagiem „security” zostało automatycznie zamknięte przez robota ze względu na brak aktywności w ciągu 30 dni.
Komentarze
Ciekawe czy doczekam czasów kiedy w całym świecie „innowacji” javascriptowych bibliotek w końcu zapanuje jakiś porządek – całe Node powoli przejmuje „złą sławę” PHP
Jaką „złą sławę” PHP? Kolejny hejter który hejtuje by pohejtować, a w pehapie jedyne co napisał to hello world? ( ͡° ͜ʖ ͡°)
PHP akurat w tym względzie działa o niebo lepiej. Z Composerem nie ma problemów takich jak z npm.
Ostatnio nawet sam twórcy przyznali, że najlepszym rozwiązaniem problemów z npm jest `rm -rf node modules && npm install` http://blog.npmjs.org/post/171139955345/v570
Niestety ciągle JS jest jeszcze pełen mniejszych lub większych pułapek, nieścisłości. PHP jest dużo dojrzalszy, więcej rzeczy ma wbudowanych w sam język. Ma też dużo problemów i zaszłości, ale jednak jest stabilniejszy.
Na JavaScript jest hype, używany jest wszędzie, nawet tam gdzie nie ma takiej potrzeby. Panele banków przepisywane są na JS, a jak się otworzy konsolę to często jest czerwona ściana błędów. Jak dołożymy do tego mikro-modularność, to nawet najprostrzy projekt ma 100 zależności małych bibliotek, które uzupełniają braki samego języka. Dodając do tego brak namespace w npm bałagan robi się bardzo szybko.
http://www.phpsadness.com/sad/50
Zostawię to tutaj…
Yarn > Pobieranie plików ręcznie > NPM
Jakieś uzasadnienie, co konkretnie Yarn robi lepiej? Z mojego doświadczenia to jest to działania na MacOS ; ), ale może o czymś nie wiem, a chętnie się dowiem.
Niby linux taki bezpieczny system, a zeby odpalic jakis podrzedny programik trzeba uzywac sudo :P
Nigdy nie instaluję Node.js/NPM globalnie w systemie, używam albo NVM albo Docker dzięki czemu nie ma potrzeby używania „sudo npm” nawet przy instalacji globalnych paczek „-g”.
Używanie node bez nvm to jakaś porażka. W normalnej sytuacji instaluje się nvm i użytkownik może wykonać `npm install -g` w celu nie instalowania paczek globalnych do aplikacji bez problemu większego i bez sudo. Ponadto może sobie szybko zmienić wersję node do testów czy też wywalić wszystkie cache i paczki usuwająć odpowiedni dir w ~/.nvm/
Nie trzeba. Ale tak jest najprościej. Żaden system niestety nie obroni użytkownika przed głupotą… nawet nie powinien.
Rozumiem, że komputera już nie da się naprawić? Bo jak telefon jest „zbrickowany”, to znaczy, że koniec – to już można użyć go jako cegły – „my phone is a brick”.
Zgadzam się z Mikołajem. „Brick” w znaczeniu jakie zawsze znałem oznacza taki stan, gdzie dany sprzęt staje się tą właśnie 'cegłą’ z którą już nic nie da się zrobić. I tak też zrozumiałem tytuł. A z treści wynika jednak coś innego.
Jeśli znasz uprawnienia (właściciela) jaki był w tych katalogach to z poziomu livecd odzyskasz, jednakże pewnie byłoby to sporo roboty (część podrzędnych katalogów moze mieć jeszcze innego właściciela)
No wlasnie, gorzej jak jakies katalogi/pliki wewnatrz mialy innego wlasciciela. Dodatkowo prace skomplikowac moze fakt, ze to VM w jakiejs chmurze gdzie nie masz klasycznej konsoli i zeby w ogole dostac sie do systemu plikow, musisz zamontowac dysk pod jakas inna VM. NodeJS to g*wno.
Jeśli to VM w chmurze, która zajmowała się serwowaniem Node’a, to chyba to nie jest jakiś wielki problem postawić nową?
To prawda, tytuł jest niedekwatny do treści.
Czytaj ze zrozumieniem. System jest zbrickowany, a nie komputer.
Ale systemu nie da się zbrickować. Brick = fizyczne materialne urządzenie, które teraz służy za cegłę/przycisk do papieru.
Także zgadzam się z tezą, że tytuł jest nieadekwatny.
Większość przypadków „brickowania” Androida polega na tym, że wszystko da się odwrócić, tylko statystyczni użytkownicy nie mają odpowiedniego sprzętu/wiedzy. Analogicznie jest tutaj z systemem – można sobie rozwalić i nie ma jakiegoś dobrego „wbudowanego” sposobu naprawy, chociaż jakby ktoś się uparł to pewnie by się dało.
Beka z node :)
NodeJS powinien zniknąć razem z Flashem i Java. Mistrzostwem świata jest porzucanie projektów z dnia na dzień czy wręcz kuriozalne zalecenia przy aktualizacji modułów.
Flasha jeszcze rozumiem, ale Javę? Czyżbyś był kolejną ofiarą efektu Krugera-Dunninga jak większość polskich informatyków?
(Nie znam się ale trochę w Nodejs siedzę to się wypowiem)
Spora część frontendu (o ile już nie większość) używa nodejs do właśnie- developmentu, nie używa noda do backendu. Przykładowo transpilacje SASS do CSS nie wykonuje się już za pomocą rubyego a właśnie nodem. Dlaczego? W nodzie mogę sobie napisać skrypt który automatycznie będzie sprawdzał czy dokonałem zmiany w pliku i automatycznie wykona z nim określoną akcję. Mogę np jw pisać style w SCSS a skrypcik automatycznie będzie mi go transpilował do CSS, a co więcej może np automatycznie odświeżyć kartę przeglądarki na innym monitorze (lub urządzeniu- broswersync- i mogę od razu sprawdzać jak strona się wyświetla na tablecie).
I nie muszę nawet pisać tych skryptów sam – w sieci dostępne są gotowe startery np do Reacta, Angulara, Vue itd. używające Webpacka, Gulpa itp.
Aktualnie alternatywą mógł by być soft od InteliJ- np w WebStormie jest możliwość automatycznego transpilowania niektórych rozszerzeń np .scss -> .css lub .ts -> .js ale z kolei po co tego używać skoro poszczególne ustawienia dewelopera są zapisywane w podkatalogu projektu – ’.idea’ i nie jest commitowany do repo projektu? Takie rozwiązanie nie jest wygodne (i przenośne). Łatwiej np powiedzieć nowemu członkowi zespołu aby po prostu sclonował sobie repo i odpalił w folderze polecenie 'npm start’ i już może pracować- edytować pliki z folderu src a wszelkie zmiany będzie widział od razu w oknie przeglądarki (nie będzie jej musiał nawet odświeżać) a do tego co chwile w konsoli będą mu się pojawiały wyniki testów i błędy. Magic.
No ale łatwiej obrzucić fają technologię upraszczającą życie błotem nie wiedząc nawet jak i gdzie się ją wykorzystuje.
IMO lepiej jest narazić swoje lokalne środowisko developerskie na takie błędy jak w artykule niż robić wszystkie operacje ręcznie- wtedy o wiele łatwiej o niedopatrzenie które wyjdzie dopiero na produkcji a kto wie – wtedy może być już za późno
Choć fakt Node i npm mogły by być ciut lepiej dopracowane ale aktualnie brak lepszej alternatywy.
Czy słowa „kompilować” lub „przekodować” to już jest „oldschool”?
Jeszcze nie widziałem by ktoś używał spolszczonego „przekodować” ale można to tak mniej więcej rozumieć, natomiast kompilacja to też ciut inna liga – kompilacja – przekształcenie kodu źródłowego na maszynowy, a transpilacja (ang. transpilation) – kodu źródłowego jednego języka na kod źródłowy innego języka – bo przeglądarki nie obsługują SCSS/SASS, LESS, Stylus (transpilowane do CSS) i TypeScript, JSX, ES6, CoffeeScript też nie (transpilowane do JS)
W takim razie to jest TRANSLACJA.
Co proponujesz w zamian?
Każde uruchomienie komendy z sudo to ryzyko – w tym wypadku ewentualne szkody to wina użytkownika.
Po drugie każda aktualizacja globalnej paczki (u siebie czy na serwerze) powinna być poprzedzona właśnie sprawdzeniem czy aktualna wersja czegoś nie popsuła, czy nie ma „chorób wieku dziecięcego” itp.
Po trzecie jeśli npm (lub inna paczka) to zależność lokalna to trzymamy konkretną wersję w package-lock.json i tylko ją instalujemy (czy to przy CI, CD, testach itp.).
Po czwarte:
„Ale to nie koniec niespodzianek, ponieważ tydzień wcześniej ukazało się zgłoszenie #19829, które dokumentowało błąd w zrozumiały i prawidłowy sposób [..] Pomimo wyraźnych starań, raport został całkowicie zignorowany, choć wtedy istniała znacznie większa szansa na rozwiązanie problemu w „bezbolesny” sposób.”
– Pamiętajmy, że to open source – nikt nikomu nie płaci za codzienne testowanie i developerkę toteż nikt nie ma obowiązku żeby takie rzeczy robić :P Może to jest jakiś zgrzyt w community albo po prostu zbieg okoliczności, że główni developerzy nie mieli czasu się tym zająć.
W skrócie – jeśli sami sobie popsuliśmy system to mamy nauczkę na następny raz. Jeśli padła „produkcja” (tak jak pisał o tym jeden z użytkowników w tickecie) – no cóż – nauczka dla firmy aby poważnie się zastanowić czy pracownik się tym zajmujący ma odpowiednie kwalifikacje…
To, że coś jest open source, ma przyzerowy związek z tym, czy ktoś za to płaci. npm to normalna firma, gdzie developerzy i developerki za normalne pieniądze tworzą rozwiązania opensourcowe oraz SAAS. Pozwala się tego dowiedzieć 30 sekund w Google.
Co za baran odpala npm z sudo…
Gradacja jest jeszcze bardziej zabawna:
1. sudo su i jazda
2. NOPASSWD – przecież hasło przy sudo jest tak denerwujące…
3. sticky bit na wszystko