Node.js drošības atjauninājums: vai Jūsu versija vēl saņem labojumus?
21. oktobrī Node.js izlaida drošības labojumus 22., 24. un 26. līnijai. Kuras versijas ir drošas, kāpēc Node.js 18 un 20 labojumu nesaņems un kā pārbaudīt, kuru versiju izmanto Jūsu lietotne.
21. oktobrī Node.js izlaida drošības labojumus 22., 24. un 26. līnijai. Kuras versijas ir drošas, kāpēc Node.js 18 un 20 labojumu nesaņems un kā pārbaudīt, kuru versiju izmanto Jūsu lietotne.
Labojumus saņēma tikai tās versiju līnijas, kurām vēl ir atbalsts, un drošas ir versijas 22.23.4, 24.22.1 un 26.12.1 vai jaunākas tajā pašā līnijā. Node.js 18 un 20 atbalstu jau ir zaudējušas, tāpēc šajā Node.js drošības atjauninājumā labojumu tām nav un arī nebūs: ja Jūsu lietotne strādā uz kādas no tām, atjaunināšana nozīmē pāreju uz citu līniju.
Trešdien, 21. oktobrī, Node.js projekts izlaida drošības laidienus visām trim atbalstītajām līnijām, un tajā pašā dienā PHP izlaida ārkārtas labojumus ievainojamībām, kas ieguva nosaukumu PHP2Shell, taču tie ir divi atsevišķi notikumi ar atšķirīgu nopietnību. Node.js laidiens bija izziņots iepriekš, tā nopietnākās ievainojamības projekts ir novērtējis kā augstas, nevis kritiskas, un paziņojumā nav minēti ne pagaidu risinājumi, ne uzbrukumi reālajā vidē. Atjaunināšanu tas neļauj atlikt, bet pārvieto uzmanību: šoreiz lielākais risks ir nevis pašā laidienā, bet versijās, kuras to nesaņēma.
Kas tika labots oktobra Node.js drošības atjauninājumā
Node.js paziņojumā ir uzskaitītas desmit ievainojamības: četras projekts novērtējis kā augstas, trīs kā vidējas un trīs kā zemas, bet CVSS novērtējumu projekts šoreiz nav publicējis, tāpēc šajā rakstā izmantots tā paša vērtējums.
Nopietnākā no tām ir CVE-2026-111497. Projekts to nosauc par Brotli dekodētāja rakstīšanu ārpus atvēlētās atmiņas robežām, kas ļauj attālināti izpildīt kodu, un vērtē kā augstu. Brotli ir saspiešanas formāts, kura dekodētājs ir iebūvēts Node.js, un laidiena piezīmēs labojums ir aprakstīts kā izmaiņa šajā iebūvētajā bibliotēkā. Pa kuru ceļu ievainojamība ir sasniedzama, paziņojumā nav teikts, un arī Brotli izstrādātāju labojuma apraksts runā tikai par to, ka nederīga datu plūsma tagad tiek atpazīta agrāk. Tāpēc šeit nav minētas konkrētas funkcijas: droši var teikt tikai to, ka dekodētāja kļūda visvairāk attiecas uz lietotnēm, kuras atspiež Brotli datus no avota, kuram tās nevar uzticēties.
Trīs citas ievainojamības skar TLS sertifikātu pārbaudi, un tās nav viens un tas pats gadījums. Pirmā, ar augstu novērtējumu, skar tikai 26. un 24. līniju: resursdatora nosaukuma pārbaudi var apiet, ja IP adrese ir uzrakstīta ar cipariem pilnā platumā, piemēram, 127.0.0.1. Otrā, arī augsta, skar visas trīs līnijas: pārbaudi var apiet, ja resursdatora nosaukumu nestingri var nolasīt kā IP adresi. Trešā ir vidēja un arī skar visas trīs līnijas: nestandarta IPv4 pieraksts ļauj sertifikātā norādītajam DNS nosaukumam apliecināt IP adresi. Laidiena piezīmēs labojumi ir formulēti īsi: netipiski pierakstītas IP adreses tagad tiek noraidītas, un atsevišķi ir izlabota IP adrešu normalizācijas regresija. Visos trīs gadījumos runa ir par brīdi, kad Node.js darbojas kā klients, proti, kad pats veido šifrētu savienojumu ar citu serveri, nevis par brīdi, kad tas apkalpo savus apmeklētājus.
Ceturtā augstā novērtējuma ievainojamība ir dns.resolve funkcijā, kas apcirta nosaukumus, kuros ir nulles rakstzīme. Starp vidējām ir HTTP savienojumu atkārtotas izmantošanas kļūda, kurā atbilde, kas savienojumā ierakstīta pirms pieprasījuma nosūtīšanas, varēja tikt apstrādāta kā atbilde uz šo pieprasījumu, un kļūda, kuras dēļ crypto.randomUUID() un randomInt() nejaušības kešatmiņa tika saglabāta palaišanas momentuzņēmumos un vienā izpildāmā failā, tā ka katrs process atkārtoja tās pašas vērtības. Trīs zema novērtējuma ievainojamības skar ZIP failu apstrādi un Node.js atļauju modeli.
Kļūdu ar nejaušības kešatmiņu ir vērts saprast precīzāk, jo parastā gadījumā tā neko neietekmē. Tā attiecas tikai uz projektiem, kas palaižas no paša veidota momentuzņēmuma vai ir izplatīti kā viens izpildāmais fails (SEA), un tur tā nozīmē, ka katrs process, kas palaists no tā paša faila, saņēma tās pašas «nejaušās» vērtības. Ja šādā projektā ar crypto.randomUUID() vai randomInt() tika veidoti identifikatori vai pagaidu kodi, tie varēja atkārtoties starp procesiem, tāpēc pēc labošanas ir vērts pārbaudīt, vai kāda no šīm vērtībām netiek izmantota tur, kur tai jābūt neuzminamai.
Laidiens atjaunina arī vairākas iebūvētās atkarības, atkarībā no līnijas c-ares, OpenSSL, SQLite un Undici, uz kuras balstās iebūvētā fetch funkcija. Tāpat ir atjaunināts uzticamo sertifikātu iestāžu saraksts saistībā ar kompromitētu eMudhra starpsertifikātu, un TLS savienojumi tagad noraida ķēdes, kurās ir bloķētas publiskās atslēgas.
Kuras versijas ir drošas
Labotās versijas ir trīs, pa vienai katrai atbalstītajai līnijai: 22.23.4, 24.22.1 un 26.12.1. Viss, kas savā līnijā ir vecāks, ir skarts. Ne visas desmit ievainojamības skar visas līnijas: 26. līnijai ir visas desmit, 24. līnijai astoņas, bet 22. līnijai septiņas, jo divas zema novērtējuma kļūdas ir tikai jaunākajā līnijā un viena TLS kļūda neskar 22. līniju.
Atjaunināšana līnijas ietvaros ir mazākais iespējamais solis, un parasti tā ir arī drošākā izmaiņa, ko var izdarīt ražošanas vidē. Tomēr arī tā var mainīt uzvedību, un šoreiz ir konkrēts piemērs: labojums TLS pārbaudē tagad noraida netipiski pierakstītas IP adreses. Ja kāda lietotne savienojumos ar citu serveri savulaik izmantoja šādu pierakstu, pēc atjaunināšanas savienojums var neizdoties. Tas ir labots drošības caurums, nevis jauna kļūda, taču to ir vērts zināt pirms atjaunināšanas, nevis pēc tās.
Versiju līnija ir svarīgāka par versijas numuru
Līdz Node.js 26 katra lielā versija iet cauri vienam ciklam: vispirms tā ir aktuālā versija (Current), tad pāra numura versijas saņem aktīvo ilgtermiņa atbalstu (Active LTS), pēc tam pāriet uzturēšanas posmā (Maintenance LTS), kurā saņem tikai kritiskus kļūdu labojumus un drošības labojumus, un beigās atbalsts beidzas pavisam, savukārt nepāra numura versijas līdz 25. līnijai ilgtermiņa atbalstu nesaņēma. No Node.js 27 cikls mainās: saskaņā ar laidienu grafiku ilgtermiņa atbalstu saņems katra līnija, un visus 30 atbalsta mēnešus tā paliks aktīvajā posmā, bez uzturēšanas posma. Projekts pats raksta, ka ražošanas lietotnēm jāizmanto tikai aktīvā vai uzturēšanas posma ilgtermiņa atbalsta versijas.
Pašreizējām līnijām tuvākās posma maiņas notiek divos datumos. Saskaņā ar Node.js laidienu grafiku 24. līnija uzturēšanas posmā pārgāja 20. oktobrī, dienu pirms drošības laidiena, un 26. līnija ilgtermiņa atbalstu saņems 28. oktobrī. 22. līnija uzturēšanas posmā ir kopš 2025. gada 21. oktobra un atbalstu zaudēs 2027. gada 30. aprīlī, bet 24. līnija to zaudēs 2028. gada 30. aprīlī.
Praktiskā nozīme ir vienkārša: jautājums «vai mums ir jaunākā versija» pats par sevi neko daudz nepasaka, bet noderīgs ir jautājums «kurā līnijā mēs esam un līdz kuram datumam tā saņems labojumus». Pirmais jautājums atbildi maina katru mēnesi, otrais — reizi pāris gados, un tieši tāpēc otro ir viegli aizmirst.
Node.js 18 un 20: labojuma nebūs
Node.js paziņojumā ir teikums, kas šoreiz ir svarīgāks par visām desmit ievainojamībām: versijas, kurām atbalsts ir beidzies, drošības laidienā vienmēr ir skartas, un labojumu tām neizlaiž ne tagad, ne vēlāk, jo līnija, kurai atbalsts ir beidzies, vairs nesaņem nevienu laidienu.
Saskaņā ar laidienu grafiku 16. līnija atbalstu zaudēja 2023. gada 11. septembrī, 19. līnija 2023. gada 1. jūnijā, 18. līnija 2025. gada 30. aprīlī un 20. līnija 2026. gada 30. aprīlī. Pēdējais datums ir svarīgākais: 20. līnija atbalstu zaudēja pirms nepilniem sešiem mēnešiem, un projekts, kas uz tās tika uzsākts, joprojām var strādāt bez jebkādām redzamām problēmām. Tieši tas padara situāciju viltīgu, jo nekas tā darbībā neliecina, ka drošības labojumi tai vairs nepienākas.
Uzņēmumiem, kas nevar ātri pāriet uz atbalstītu līniju, Node.js paziņojums min vienu iespēju: komerciālu atbalstu versijām pēc uzturēšanas posma piedāvā OpenJS Ecosystem Sustainability Program partneri. Tas ir maksas pakalpojums, un tas ir pagaidu risinājums, nevis aizstājējs pārejai.
Kā pārbaudīt, kuru Node.js izmanto Jūsu lietotne
Pārbaude aizņem minūtes, bet ir viena vieta, kur to ir viegli izdarīt nepareizi: Node.js versija, ko rāda terminālis, ne vienmēr ir tā pati, ar kuru strādā lietotne.
Hostings ar cPanel. Izmantoto versiju rāda sadaļa Software → Setup Node.js App, kur katrai lietotnei ir sava rinda un versiju izvēlas no saraksta. Sarakstā ir tikai tās versijas, ko serverī ir uzstādījis hostinga sniedzējs. Komanda node -v šādā hostingā var parādīt citu versiju nekā šis iestatījums, tāpēc skatieties tieši uz attiecīgo rindu.
Savs serveris. Komanda node -v parāda to versiju, kas ir pirmā sistēmas ceļā, bet procesu pārvaldnieks, piemēram, PM2 vai systemd serviss, var palaist programmu ar pavisam citu izpildāmo failu. Ticamākā atbilde ir tā, ko process pats ziņo par sevi: process.version vērtība, piemēram, ierakstīta žurnālā palaišanas brīdī.
Konteineri. Docker vidē versiju nosaka attēls, nevis saimniekdators. Attēls, kas būvēts pirms 21. oktobra, labojumu nesatur neatkarīgi no tā, cik reižu konteiners ir pārstartēts, tāpēc attēls ir jāpārbūvē ar atjauninātu pamatattēlu.
Ja piekļuves nav. Tad jautājums ir hostinga sniedzējam vai izstrādātājam, kas to uztur. Formulējums, kas ietaupa saraksti: «Kuru Node.js versiju izmanto mūsu lietotne? Vai savā līnijā tā ir vismaz 22.23.4, 24.22.1 vai 26.12.1? Ja tā ir līnijā bez atbalsta, piemēram, 18. vai 20., kad plānota pāreja?»
Ko darīt šodien
Šodienas secība ir šāda: vispirms atjaunināt Node.js līdz labotajai versijai savā līnijā un pārstartēt katru procesu, kas to izmanto, tad pārbūvēt visu, kur izpildvide ir iebūvēta, un tikai pēc tam plānot pāreju tiem projektiem, kuri strādā uz līnijām bez atbalsta.
Pirmkārt, atjauniniet līnijas ietvaros. Uz 22.23.4, 24.22.1 vai 26.12.1 atkarībā no tā, kurā līnijā esat. Hostinga gadījumā to dara sniedzējs, un Jūsu darbs ir pārliecināties, ka lietotne izmanto atjaunināto versiju.
Otrkārt, pārstartējiet procesus. Process, kas jau strādā, turpina izmantot to Node.js, ar kuru tas tika palaists, un faila nomaiņa diskā to neietekmē. Tas pats bija spēkā arī ar PHP2Shell: pakotne ir nomainīta, bet vecais process turpina strādāt ar veco kodu.
Treškārt, pārbūvējiet to, kur izpildvide ir iebūvēta. Docker attēli ir jāpārbūvē ar atjauninātu pamatattēlu. Ja programmu izplatāt kā vienu izpildāmo failu (SEA), tajā ir iebūvēts pats Node.js, tāpēc sistēmā uzstādītās versijas atjaunināšana to neietekmē, un fails ir jāsabūvē no jauna ar laboto versiju. Tas pats attiecas uz palaišanas momentuzņēmumiem, ko skar nejaušības kešatmiņas kļūda.
Ceturtkārt, ja esat uz 18. vai 20. līnijas, plānojiet pāreju. Tas ir lielāks darbs nekā atjaunināšana līnijas ietvaros, tāpēc to ir vērts sākt tagad, un secība ir aprakstīta nākamajā sadaļā.
Kā pāriet no Node.js 18 vai 20
Pāreja starp lielajām versijām nav vienas komandas darbs, un to ir vērts darīt secīgi. Vispirms jāizvēlas mērķis. Vairumā gadījumu tā ir 24. līnija, kas labojumus saņems līdz 2028. gada 30. aprīlim; 22. līnija ir saprātīga izvēle tikai tad, ja kāda svarīga atkarība 24. līniju vēl neatbalsta, jo tās atbalsts beigsies gadu agrāk.
Tad jāatrod visas vietas, kur projekts nosaka savu Node.js versiju, jo to gandrīz vienmēr ir vairākas: package.json lauks engines, faili .nvmrc vai .node-version, Dockerfile pamatattēls, integrācijas vides konfigurācija un hostinga paneļa iestatījums. Ja nomaina tikai daļu no tām, dažādās vidēs strādā dažādas versijas, un kļūdas parādās tur, kur tās visgrūtāk atrast.
Pēc tam projekts testa vidē jāuzstāda no jauna ar jauno versiju un jāpalaiž testi. Īpaša uzmanība pienākas pakotnēm, kurās ir kompilēts kods: tās tiek būvētas konkrētai Node.js versijai, tāpēc pēc pārejas tās var būt jāpārbūvē vai jāatjaunina. Node.js katrai lielajai versijai publicē izmaiņu sarakstu, kurā atsevišķi atzīmētas izmaiņas, kas var salauzt esošu kodu, un to ir vērts izlasīt pirms pārejas, nevis pēc tās.
Tikai tad nāk ražošanas vide: versijas maiņa, procesu pārstartēšana un pārbaude, ka process.version rāda jauno versiju. Vecā versija dažas dienas var palikt pieejama atkāpšanās gadījumam, bet ne ilgāk, jo tieši tā ir versija, kurai labojumu vairs nebūs.
Kas netiek atjaunināts kopā ar Node.js
Node.js atjaunināšana salabo pašu izpildvidi un bibliotēkas, kas tajā ir iebūvētas, bet ne visu, ko lietotne izmanto, un tieši šeit visbiežāk paliek caurumi, kurus neviens neredz.
Atsevišķi instalētas pakotnes. Ja projekts savās atkarībās izmanto undici pakotni no npm, nevis iebūvēto fetch, šī pakotne atrodas projekta node_modules mapē, un Node.js laidiens to neaiztiek. Tas pats attiecas uz visām pārējām atkarībām: tās atjaunina pakotņu pārvaldnieks, un tikai tad, kad kāds to palaiž.
Uzticamo sertifikātu iestāžu saraksts. Pēc noklusējuma Node.js neizmanto operētājsistēmas sertifikātu iestāžu sarakstu, bet savu iebūvēto, un dokumentācijā teikts, ka tas ir Mozilla saraksta momentuzņēmums, kas tiek fiksēts laidiena brīdī. Tātad tādas izmaiņas kā šī laidiena reakcija uz kompromitēto eMudhra starpsertifikātu programma saņem tikai kopā ar izpildvides atjauninājumu, nevis kopā ar operētājsistēmas atjauninājumiem, ja vien tā nav īpaši konfigurēta izmantot sistēmas sarakstu.
Kā nākamo laidienu nepalaist garām
Node.js drošības laidienus izziņo iepriekš savā drošības lapā, norādot plānoto laidiena dienu, un šoreiz tieši tā arī notika. Tātad šī trešdiena nebija pārsteigums tiem, kas šo lapu uzrauga: atjaunināšanu varēja ieplānot jau iepriekš, nevis meklēt laiku tai pašā dienā.
Praktiski tas nozīmē, ka kādam ir jābūt atbildīgam par šo uzraudzību. Pārvaldītā hostingā to dara sniedzējs, bet savā serverī vai projektā, ko uztur paša komanda, ir vērts zināt, kurš tieši seko projekta paziņojumiem, kurš izlemj par atjaunināšanu un kurš pārbauda, ka pēc tās viss strādā. Ja uz šiem jautājumiem atbilde ir «neviens konkrēti», tieši tur arī ir lielākais risks, nevis kādā no desmit ievainojamībām.
Ja Node.js Jums ir tikai būvēšanas rīks
Daudzās Laravel un WordPress vietnēs Node.js serverī nestrādā vispār: tas darbina Vite vai līdzīgu rīku, kas no pirmkoda sagatavo CSS un JavaScript failus, un pēc tam apstājas. Šādā gadījumā situācija atšķiras no lietotnes, kas pati apkalpo pieprasījumus, jo būvēšanas process neatbild uz pieprasījumiem no interneta un neatspiež datus, ko tam atsūta nezināmi apmeklētāji.
Atšķiras nenozīmē, ka tas nav svarīgi. Būvēšanas rīki strādā izstrādātāju datoros un nepārtrauktās integrācijas vidē, lejupielādē pakotnes un veido savienojumus ar citiem serveriem, un ievainojamību apraksti ir pārāk īsi, lai droši pateiktu, kuri no šiem ceļiem ir skarti. Atjaunināt Node.js ir vērts arī tur, tikai pareizajā secībā: vispirms serveri, kur Node.js strādā tiešsaistē, pēc tam izstrādātāju datori un integrācijas vide.
Ir arī otrs iemesls, kas ar šo nedēļu nav saistīts. Būvēšanas vide bieži paliek uz tās Node.js versijas, ar kuru projekts kādreiz tika uzsākts, un tad kādu dienu jauna rīka versija vienkārši atsakās ar to strādāt. Pāreja uz atbalstītu līniju tad notiek steigā un nepiemērotā brīdī, tāpēc to ir vieglāk izdarīt tagad, kamēr tā ir plānots darbs.
Ko tas nozīmēja mūsu hostingā
Mūsu pārvaldītais hostings ir vieta mūsu pašu serverī, un katrs klients tajā izvēlas versiju caur hostinga paneli. Mūsu serverī Node.js 22. un 24. versiju līnija jau darbojas ar labotajām versijām 22.23.4 un 24.22.1. Klientiem, kuru projekti izmanto šīs līnijas, nekas nav jādara, izņemot pārliecināties, ka process pēc atjaunināšanas ir pārstartēts.
Godīgi jāpasaka arī otra puse. Serverī izvēlei joprojām ir pieejamas arī līnijas, kurām atbalsts ir beidzies, un tām labojuma nav — ne mūsu, ne kāda cita serverī, jo Node.js tādu labojumu neizlaiž. Ja Jūsu projektam ir izvēlēta kāda no tām, atjaunināšana nozīmē pāreju uz 22. vai 24. līniju, un to vislabāk darīt kopā ar pārbaudi, ka pēc pārejas viss strādā tāpat kā iepriekš.
Mūsu pārvaldītais hostings sākas no €45 mēnesī, un uzturētas izpildvides ir daļa no tā, par ko šajā summā maksā. Ja Jūsu lietotne vēl strādā uz Node.js 18 vai 20, pārrunāsim pāreju, pirms to izdarīt piespiež kāda nākamā drošības laidiena diena.
Bieži uzdotie jautājumi.
Kura Node.js versija ir droša?
Drošas ir 22.23.4, 24.22.1 un 26.12.1 vai jaunākas versijas tajā pašā līnijā. Viss, kas savā līnijā ir vecāks, ir skarts. Versijām, kuru līnijai atbalsts ir beidzies, piemēram, Node.js 18 un 20, drošas versijas nav vispār, jo tām labojumus neizlaiž.
Man ir Node.js 18 vai 20. Ko darīt?
Abām līnijām atbalsts ir beidzies: 18. līnijai 2025. gada 30. aprīlī, 20. līnijai 2026. gada 30. aprīlī. Labojums tām nav un nebūs, tāpēc vienīgais risinājums ir pāreja uz atbalstītu līniju. 24. līnija saņems labojumus līdz 2028. gada 30. aprīlim, 22. līnija līdz 2027. gada 30. aprīlim. Pāreju ir vērts vispirms izmēģināt testa vidē.
Vai šis Node.js drošības atjauninājums ir tas pats, kas PHP2Shell?
Nē. Abi notikumi bija 21. oktobrī, taču tie ir atsevišķi. PHP2Shell bija divas kritiskas ievainojamības pašā PHP. Node.js drošības laidiens bija izziņots iepriekš, tā nopietnākās ievainojamības ir novērtētas kā augstas, un paziņojumā nav minēti uzbrukumi reālajā vidē.
Vai pietiek atjaunināt Node.js, ja lietotne jau strādā?
Nē, process ir jāpārstartē. Process, kas jau strādā, turpina izmantot to Node.js, ar kuru tas tika palaists. Ja lietotne ir Docker attēlā vai izplatīta kā viens izpildāmais fails (SEA), tajā ir iebūvēts pats Node.js, un tas ir jāpārbūvē ar laboto versiju.
Mūsu Laravel vai WordPress vietnē Node.js izmanto tikai Vite būvēšanai. Vai tas mūs skar?
Mazāk nekā lietotni, kas pati apkalpo pieprasījumus, jo būvēšanas process neatbild uz pieprasījumiem no interneta. Tomēr būvēšanas rīki lejupielādē pakotnes un veido savienojumus ar citiem serveriem, tāpēc Node.js ir vērts atjaunināt arī izstrādātāju datoros un integrācijas vidē, tikai pēc serveriem.
Vai ir pagaidu risinājumi, ja atjaunināt uzreiz nevar?
Node.js paziņojumā pagaidu risinājumi nav minēti. Vienīgais ieteikums ir lietot atbalstītu versiju saskaņā ar laidienu grafiku. Versijām, kurām atbalsts ir beidzies, Node.js min komerciālu atbalstu, ko piedāvā OpenJS Ecosystem Sustainability Program partneri.
Kā uzzināt, kuru Node.js versiju izmanto lietotne cPanel hostingā?
Sadaļā Software → Setup Node.js App, kur katrai lietotnei ir sava rinda ar izvēlēto versiju. Komanda node -v terminālī var parādīt citu versiju nekā lietotnes iestatījums, tāpēc skatieties tieši uz lietotnes rindu.
Serveri, mitināšana un uzturēšana ES — Frankfurtē, Helsinkos vai Rīgā, ar monitoringu 24/7. Pilna pārvaldība: atjauninājumi, drošība un veiktspēja, automātiskas dublējumkopijas ar pārbaudītu atjaunošanu, SSL sertifikāti, CDN un DDoS aizsardzība. Migrējam no esošā mitinātāja bez dīkstāves un skalējam pēc slodzes.