IlmHamroh
JavaScript Full-stack/16-qism. Frontend asboblari: npm, bundlerlar, config16/48-dars26 daqiqa
Mundarija (33)

Ta'minot zanjiri xavfsizligi: npm audit, postinstall, typosquatting va provenance

Qisqacha: Har npm paketi — siz o'qimagan begona kod, va u o'rnatish paytidayoq kompyuteringizda ishga tushishi mumkin. Ta'minot zanjiri (supply chain) hujumi sizni emas, siz ishonadigan paketni buzadi. Himoya qatlamlari: npm audit — ma'lum zaifliklar, npm audit signatures — registr imzosi, allowScripts va ignore-scripts — o'rnatish skriptlari, min-release-age — juda yangi versiyani kutish. vazifalar ga bugun .npmrc va CI'da imzo tekshiruvi qo'shiladi.

Bu darsda

  • Ta'minot zanjiri hujumi nima ekanini haqiqiy hodisalar (2017–2025) misolida tushuntira olasiz.
  • npm audit hisobotini o'qiysiz va npm audit fix qachon xavfli ekanini bilasiz.
  • postinstall skripti nima qila olishini ko'rasiz va uni allowScripts, ignore-scripts bilan boshqarasiz.
  • Imzo, provenance va trusted publishing nima ekanini, npm audit signatures chiqishini o'qiysiz.
  • min-release-age ning foydasi va narxini haqiqiy misolda o'lchaysiz.

Oldin bilishingiz kerak: npm buyruqlari chuqur, Lock-fayllar va npm ci, .npmrc va registry sozlamalari, pnpm, Paket tanlash va baholash.

1. Nega bu kerak?

Paket tanlash darsida Sardor paketni o'rnatishdan oldin baholashni o'rgandi: litsenziya, oxirgi versiya, yuklanishlar soni. Lekin bir savol ochiq qoldi. Yaxshi, mashhur, ishonchli paket ertaga buzilsa-chi?

Bu nazariya emas. 2025-yil 8-sentabrda chalk va debug kabi 18 ta paketning zararli versiyalari chiqdi. Ularni haftasiga 2 milliarddan ortiq marta yuklab olishadi. Muallif yolg'on xatga ishonib, npm hisobining parolini va 2FA kodini soxta saytga kiritgan edi. Bir haftadan keyin "Shai-Hulud" nomli o'z-o'zidan tarqaladigan dastur (worm) 500 dan ortiq paketni zararladi.

Bunday hujum ta'minot zanjiri hujumi (supply chain attack) deyiladi. Hujumchi sizning kodingizni emas, siz ishonadigan boshqa kodni buzadi. «Bahor» oshxonasi tilida: oshpaz toza, retsept to'g'ri — lekin bozordagi go'sht yetkazib beruvchi buzilgan mahsulot keltirdi. Oshxona eshigini qancha mustahkam qulflamang, zarar ichkaridan keladi.

npm buyruqlari darsida vazifalar 8 ta paket tanlab, 102 tasini o'rnatganini ko'rgan edik. Ya'ni 94 ta paketni siz umuman tanlamagansiz. Ularning har biri — zanjirning bir halqasi.

2. Hujum qayerdan keladi

2.1 Beshta eshik

Diagrammada paket muallifdan sizning kompyuteringizgacha bo'lgan yo'l va har bosqichdagi hujum turi:

flowchart TB
  M["Muallif hisobi"] --> R["npm registry"]
  R --> I["npm install"]
  I --> S["postinstall skripti"]
  I --> B["dist/ — brauzerga"]
  H1["Fishing, o'g'irlangan token"] -.-> M
  H2["O'xshash nom<br/>(typosquatting)"] -.-> R
  H3["Kompyuterdagi sirlar<br/>o'g'irlanadi"] -.-> S
  H4["Foydalanuvchi hamyoni"] -.-> B

Uzluksiz o'qlar — paketning odatiy yo'li. Uzuq o'qlar — hujumchi qayerga urishi. Pastdagi ikki halqaga e'tibor bering: zararli kod yo sizning kompyuteringizda (postinstall), yo saytingiz foydalanuvchisining brauzerida ishlaydi.

2.2 Haqiqiy hodisalar

Sana Hodisa Eshik
2017-08 crossenv — cross-env ga o'xshash nom, muhit o'zgaruvchilarini o'g'irlagan o'xshash nom
2018-11 event-stream — yangi "yordamchi" muallif flatmap-stream bog'liqligini qo'shgan; Copay bitcoin hamyoni nishon muallif almashgan
2021-10 ua-parser-js 0.7.29, 0.8.0, 1.0.0 — buzilgan hisob, kripto-mayner va parol o'g'risi hisob o'g'irlangan
2024-03 xz-utils 5.6.0–5.6.1 (npm emas, Linux) — ikki yil ishonch qozongan "muallif" orqa eshik qo'ygan muallif almashgan
Sana Hodisa Eshik
2025-09-08 chalk, debug va yana 16 paket — fishing, brauzerda kripto-o'tkazmalarni almashtiruvchi kod hisob o'g'irlangan
2025-09-14 Shai-Hulud — postinstall orqali tokenlarni o'g'irlab, qurbonning boshqa paketlarini ham zararlagan; 500+ paket postinstall
2025-11-21…24 Shai-Hulud 2.0 — endi preinstall da, 25 000+ GitHub repozitoriy preinstall

Har qatorning manbasi dars oxiridagi «Manbalar» bo'limida. Ikki jadval telefonga sig'ishi uchun bo'lingan.

crossenv ni o'zingiz tekshirishingiz mumkin. Registr hamma narsani eslaydi:

bash
npm view crossenv
text
crossenv@0.0.2-security | Proprietary | deps: none | versions: 4
security holding package
https://github.com/npm/security-holder#readme

dist
.tarball: https://registry.npmjs.org/crossenv/-/crossenv-0.0.2-security.tgz
.shasum: ffd6ae6a6e9035d811f6dde88f8393c63b71ad6e
.integrity: sha512-Zet/ldwzo70I+vUnjM9yHCWo2iqK/RM2s2VnZDNPE/fN062UXYXGqu9Hd7HlhNVhnYGclPcjNoySWhug5lctHw==

maintainers:
- npm <npm@npmjs.com>

dist-tags:
latest: 0.0.2-security

published over a year ago by npm <npm@npmjs.com>

security holding package — "xavfsizlik uchun egallab turilgan paket". npm zararli paketni o'chirib, nomni o'zi egallab oldi, toki uni boshqa hech kim qayta ishlata olmasin. Tarixni esa npm view crossenv time buyrug'i ko'rsatadi: paket 2017-07-19 da yaratilgan va bir kunda cross-env ning haqiqiy versiya raqamlarini (5.0.1, 6.0.3…) takrorlab chiqqan. 2017-08-01 da npm uni almashtirgan.

2.3 Typosquatting

Typosquatting ("xato yozuvni egallash") — mashhur paketga o'xshash nom bilan zararli paket chiqarish: crossenv va cross-env, vitee va vite. Hujumchi kimdir shoshib xato yozishini kutadi. npm buyruqlari darsida npm view vitee ni ko'rgan edik: paket bor, lekin tavsifi va litsenziyasi yo'q.

Bugun yana bir yangi eshik bor — AI yordamchilar. Ular ba'zan mavjud bo'lmagan paket nomini "o'ylab topadi", hujumchilar esa aynan shu nomlarni egallab qo'yadi (AI natijasini tekshirish darsida ko'rgan edik). Qoida bitta: yangi nomni o'rnatishdan oldin npm view bilan kartasini ko'ring va nomni rasmiy hujjatdan ko'chiring.

Tekshirib ko'ring: chalk hodisasida Sardor hech qanday xato qilmagan: to'g'ri nomli, mashhur paketni o'rnatgan. Unda nega zarar ko'rishi mumkin edi?

Javob

Chunki buzilgan narsa — paketning o'zi, yangi versiyasi. Sardorning package.json ida "chalk": "^5.3.0" kabi diapazon bo'lsa, o'sha soatlarda qilingan npm install zararli yangi versiyani "mos keladi" deb olib kelardi. Lock-fayl va npm ci bunga qarshi birinchi to'siq: ular yangi versiyani o'z-o'zidan olmaydi.

3. npm audit: ma'lum zaifliklar

3.1 Hisobotni o'qish

Zaiflik (vulnerability) — paketdagi xavfsizlik teshigi, uni topib e'lon qilishadi va yangi versiyada yamashadi. E'lon GitHub Advisory Database'ga yoziladi, har biriga GHSA-… raqami beriladi. npm audit lock-fayldagi hamma versiyani shu bazaga yuboradi va javobni ko'rsatadi.

Darsdagi hamma chiqish 2026-10-07 da Windows 11, Node 24.21.0 va npm 11.19.0 bilan sinov papkalarida olingan. Xato jurnali yo'lini … bilan qisqartirdik.

Sinov loyihasida ataylab eski nanoid (buyurtma raqami yasaydigan kichik paket) o'rnatamiz:

bash
npm i -E nanoid@3.3.4
text
added 1 package, and audited 2 packages in 1s

1 high severity vulnerability

To address all issues, run:
  npm audit fix --force

Run `npm audit` for details.

Endi hisobotning o'zi. U uzun, lekin tuzilishi oddiy: avval paket va zaif versiyalar, keyin jiddiylik, keyin har zaiflik bitta qatorda. Birinchi ikki qatorga qarang:

bash
npm audit
text
# npm audit report

nanoid  <=3.3.17
Severity: high
Predictable results in nanoid generation when given non-integer values - https://github.com/advisories/GHSA-mwcw-c2x4-8c55
nanoid: non-secure generators can loop indefinitely with negative size - https://github.com/advisories/GHSA-28wg-ghj8-5hjv
nanoid: custom generators can loop indefinitely when size is zero - https://github.com/advisories/GHSA-2v37-7h3g-55p8
nanoid: Integer Overflow or Wraparound - https://github.com/advisories/GHSA-xwg4-73v4-xw9w
fix available via `npm audit fix --force`
Will install nanoid@3.3.20, which is outside the stated dependency range
node_modules/nanoid

1 high severity vulnerability

To address all issues, run:
  npm audit fix --force
Qator Ma'nosi
nanoid <=3.3.17 qaysi paket, qaysi versiyalar zaif
Severity: high jiddiylik: low, moderate, high, critical
Predictable results … GHSA-… har zaiflik — bir qator, havolasi bilan
outside the stated dependency range tuzatish package.json dagi chegaradan tashqarida
node_modules/nanoid diskdagi joyi

Birinchi zaiflik tarjimasi: "butun bo'lmagan qiymat berilsa, nanoid oldindan aytib bo'ladigan natija beradi". Buyurtma raqamini taxmin qilish mumkin bo'lsa, begona odam boshqaning buyurtmasini ko'rishi mumkin.

3.2 Chiqish kodi va --audit-level

Zaiflik bo'lsa, npm audit 1 bilan tugaydi — CI'da shu to'xtatadi. Chegarani --audit-level bilan ko'tarish mumkin:

bash
npm audit --audit-level=critical; echo "exit $?"

Hisobot o'sha-o'sha chiqdi, oxirgi qator esa exit 0. "Faqat critical bo'lsa to'xta" — high darajali zaiflik ko'rinadi, lekin zanjirni to'xtatmaydi. Ko'p jamoa CI'da --audit-level=high ishlatadi. Yana bir foydali bayroq — --omit=dev: faqat brauzerga yoki serverga boradigan paketlarni tekshiradi.

3.3 npm audit fix va --force

bash
npm audit fix
text
up to date, audited 2 packages in 1s

# npm audit report
…
1 high severity vulnerability

To address all issues, run:
  npm audit fix --force

Hech narsa o'zgarmadi (o'rtadagi takroriy hisobotni … bilan qisqartirdik). Sabab — -E: biz aniq "3.3.4" yozganmiz, tuzatish esa 3.3.20 da. npm audit fix package.json dagi chegaradan chiqmaydi. --force chiqadi:

bash
npm audit fix --force
text
npm warn using --force Recommended protections disabled.
npm warn audit Updating nanoid to 3.3.20, which is outside your stated dependency range.

changed 1 package, and audited 2 packages in 1s

found 0 vulnerabilities

Bu safar tuzatish shu MAJOR ichida edi (3.x). Lekin --force kerak bo'lsa, MAJOR versiyani ham o'rnatib yuborishi mumkin — ya'ni kodingizni buzadigan yangilashni. Shuning uchun qoida: --force dan oldin hisobotdagi Will install … qatorini o'qing. Versiya MAJOR bo'lsa — Bog'liqliklarni yangilash strategiyasi darsidagidek, alohida qaror.

Diqqat: npm audit faqat ma'lum va e'lon qilingan zaifliklarni biladi. 2025-yil 8-sentabrdagi chalk versiyasi chiqqan zahoti found 0 vulnerabilities derdi: hali hech kim e'lon qilmagan edi. npm buyruqlari darsidan yana bir saboq: internetsiz npm audit ham "0" deydi. "0" — "xavfsiz" degani emas.

Tekshirib ko'ring: CI'da npm audit qadami birdan qizil bo'ldi, lekin hech kim kodga tegmagan. Qanday bo'lishi mumkin?

Javob

Bazaga yangi zaiflik qo'shilgan. Lock-fayl o'sha-o'sha, lekin kecha ma'lum bo'lmagan teshik bugun e'lon qilindi. npm audit natijasi kodga emas, vaqtga ham bog'liq. Shuning uchun ko'p jamoa uni har pushda emas, alohida jadval bilan (masalan, har kuni) yuritadi va yangi topilmani alohida vazifa qiladi.

4. O'rnatish skriptlari: eng xavfli eshik

4.1 postinstall nima qila oladi

scripts chuqur darsida pre/post skriptlarni ko'rgan edik. Paketning package.json ida ham shunday skriptlar bo'ladi: preinstall, install, postinstall. Ular siz paketni o'rnatganingizda, sizning kompyuteringizda, sizning huquqlaringiz bilan ishga tushadi. Kodni import qilish shart emas — npm install ning o'zi yetadi.

Zararsiz namoyish. menyu-rang degan kichik paket yasadik, postinstall ida mana bu fayl:

js
// Zararsiz namoyish: o'rnatish paytida bu fayl ISHGA TUSHADI.
// Haqiqiy zararli paket shu yerda tokenlarni o'g'irlaydi
const { writeFileSync } = require("node:fs");
const keys = Object.keys(process.env).length;
const text = `postinstall ishladi; muhitda ${keys} ta o'zgaruvchi\n`;
// INIT_CWD — npm install chaqirilgan papka (loyiha ildizi)
writeFileSync(`${process.env.INIT_CWD}/IZ.txt`, text);
console.log(text.trim());

npm pack bilan arxivga yig'ib, boshqa loyihaga o'rnatdik:

bash
npm i ../menyu-rang/menyu-rang-1.0.0.tgz
text
added 1 package, and audited 2 packages in 857ms

found 0 vulnerabilities
npm warn install-scripts 1 package has install scripts not yet covered by allowScripts:
npm warn install-scripts   menyu-rang@1.0.0 (postinstall: node postinstall.js)
npm warn install-scripts
npm warn install-scripts Run `npm install-scripts ls` to review, or `npm install-scripts approve <pkg>` to allow.

Loyiha papkasida yangi fayl paydo bo'ldi:

bash
cat IZ.txt
text
postinstall ishladi; muhitda 130 ta o'zgaruvchi

Skript 130 ta muhit o'zgaruvchisini ko'rdi. CI'da ular orasida NPM_TOKEN, GITHUB_TOKEN, bulut kalitlari bo'lishi mumkin. Shai-Hulud aynan shunday ishladi: postinstall tokenlarni topdi, ularni ochiq GitHub repoga yukladi va o'g'irlangan npm token bilan qurbonning boshqa paketlariga ham o'zini qo'shib chiqardi.

Yana bir narsaga qarang: npm skriptning console.log ini ko'rsatmadi. O'rnatish skriptlari sukut bo'yicha jim ishlaydi (ko'rish uchun --foreground-scripts).

4.2 allowScripts: npm 11 dagi ruxsat ro'yxati

Yuqoridagi npm warn install-scripts qatoriga qaytamiz: "1 ta paketda allowScripts qamramagan o'rnatish skriptlari bor". npm 11.19.0 yangi siyosatni olib keldi. Uning hujjatida yozilgan: hozircha bu ro'yxat maslahat darajasida (skriptlar baribir ishlaydi, faqat ogohlantiradi), keyingi nashrlarda esa ko'rib chiqilmagan skriptlar to'siladi.

Haqiqiy paket bilan ko'ramiz. esbuild (tez transpiler, Transpilyatsiya darsida) o'rnatishda o'z dasturini tekshiradigan postinstall ga ega:

bash
npm i -D -E esbuild@0.28.2
text
added 2 packages, and audited 3 packages in 2s

found 0 vulnerabilities
npm warn install-scripts 1 package has install scripts not yet covered by allowScripts:
npm warn install-scripts   esbuild@0.28.2 (postinstall: node install.js)
npm warn install-scripts
npm warn install-scripts Run `npm install-scripts ls` to review, or `npm install-scripts approve <pkg>` to allow.

Skript nima qilishini ko'rib chiqdik (node_modules/esbuild/install.js — o'z binar faylini tekshiradi) va ruxsat beramiz:

bash
npm install-scripts approve esbuild
text
Approved esbuild:
  added esbuild@0.28.2

package.json ga yangi maydon yozildi:

json
{
  "allowScripts": {
    "esbuild@0.28.2": true
  }
}

Bu ogohlantirishni 16-qismda ko'p ko'rasiz: esbuild ko'p vositalarning (Vite 7 va undan eskilari, tsx, test vositalari) ichida keladi. E'tibor bering — skript to'silmagan: esbuild --version ishlaydi, ogohlantirish faqat "buni hali hech kim ko'rib chiqmagan" deydi. Vite 8.3.3 ning o'zi esbuild'siz: toza loyihada npm i -D -E vite@8.3.3 — added 15 packages … found 0 vulnerabilities, ogohlantirishsiz (Rolldown va Lightning CSS tayyor dasturlarini skriptsiz, optionalDependencies orqali oladi). npm nega bunga e'tibor qaratmoqda? Shai-Hulud kabi hujumlar aynan o'rnatish skriptlari orqali tarqaldi: ro'yxat tuzilgach, npm keyingi versiyalarda ko'rib chiqilmagan skriptlarni to'sishga o'tadi.

Ruxsat versiyaga bog'langan. esbuild 0.28.3 chiqsa, uning skripti yana "ko'rib chiqilmagan" bo'ladi — chunki buzilgan versiya aynan yangi versiya bo'lib keladi. Kerakmas skriptni rad etish ham mumkin. core-js ning postinstall i faqat homiylik xabarini chiqaradi:

bash
npm install-scripts deny core-js
text
Denied core-js:
  added core-js

Endi "core-js": false — bu paketning skripti hech qachon ishlamaydi. Siyosatni qat'iy qilish uchun — --strict-allow-scripts (yoki .npmrc da strict-allow-scripts=true). Uni menyu-rang li loyihada sinadik:

bash
npm ci --strict-allow-scripts
text
npm error code ESTRICTALLOWSCRIPTS
npm error --strict-allow-scripts: 1 package(s) have install scripts not covered by allowScripts:
npm error   menyu-rang@1.0.0 (install: (install scripts present))
npm error Approve them with `npm install-scripts approve`, deny them with `npm install-scripts deny`, or bypass this check with `--dangerously-allow-all-scripts`.
npm error A complete log of this run can be found in: …

O'rnatish to'xtadi — ko'rib chiqilmagan skript bor. --dangerously-allow-all-scripts ("xavfli: hammasiga ruxsat") nomi ataylab qo'rqituvchi qilingan.

4.3 ignore-scripts: hammasini o'chirish

Eski va qo'pol usul — ignore-scripts=true yoki --ignore-scripts: hech qanday o'rnatish skripti ishlamaydi.

bash
npm ci --ignore-scripts
npx esbuild --version
text
added 3 packages, and audited 4 packages in 1s

found 0 vulnerabilities
0.28.2

esbuild skriptsiz ham ishladi: uning dasturi alohida paketda (@esbuild/win32-x64) keladi, skript faqat tekshiradi. Lekin ba'zi paketlar skriptsiz ishlamaydi — masalan, C++ da yozilgan qismini kompyuteringizda yig'adiganlari (rasm bilan ishlaydigan sharp ning eski versiyalari, bcrypt). Bunda ignore-scripts ularni jimgina buzadi.

Usul Nima qiladi Qachon
hech narsa hamma skript ishlaydi — (bugungi sukut)
allowScripts faqat ko'rib chiqilganlar jamoaviy loyiha, npm 11.19+
strict-allow-scripts ko'rib chiqilmagan bo'lsa — xato CI
ignore-scripts hech biri skriptsiz paketlar, tez sinov

pnpm bu masalada oldinroq. pnpm darsida ko'rdik: 10-versiyadan beri u bog'liqliklarning skriptlarini sukut bo'yicha ishlatmaydi. pnpm 12.10.1 da pnpm add -D esbuild@0.28.2 ERR_PNPM_IGNORED_BUILDS xatosi bilan tugaydi, ruxsat esa pnpm approve-builds bilan allowBuilds ro'yxatiga yoziladi. G'oya npm'dagi allowScripts bilan bir xil, faqat pnpm'da u allaqachon majburiy.

Tekshirib ko'ring: Nega allowScripts paket nomiga emas, esbuild@0.28.2 ga — aniq versiyaga ruxsat yozadi?

Javob

Chunki xavf aynan yangi versiyada keladi. Shai-Hulud mashhur paketlarning yangi versiyasini zararli postinstall bilan chiqargan. Ruxsat nomga yozilganda, ertangi buzilgan versiya ham avtomatik ruxsat olardi. Versiyaga yozilsa — har yangilashda skriptni qayta ko'rib chiqasiz.

5. Imzo, provenance va trusted publishing

5.1 Registr imzosi

npm registry har paketni o'z maxfiy kaliti bilan imzolaydi. Raqamli imzo (signature) — "bu faylni aynan men berdim va u o'zgarmagan" degan, soxtalashtirib bo'lmaydigan belgi. Ochiq kalitlar registry.npmjs.org/-/npm/v1/keys manzilida. npm audit signatures o'rnatilgan har paketni shu kalit bilan tekshiradi. vazifalar da (bugungi holat):

bash
npm audit signatures
text
audited 102 packages in 6s

102 packages have verified registry signatures

30 packages have verified attestations
(use --json --include-attestations to view attestation details)

Birinchi qator: 102 paketning hammasi haqiqatan npm registry'dan, o'zgartirilmagan holda kelgan. Bu sizni soxta oyna (mirror) yoki o'rtadagi tarmoq hujumidan himoya qiladi.

5.2 Provenance: paket qayerda yig'ilgan

Ikkinchi qatordagi attestation (tasdiqnoma) — boshqa narsa. U "paketni kim, qaysi repodan, qaysi commitdan, qaysi CI'da yig'gan" degan imzolangan yozuv. Bu yozuv provenance ("kelib chiqish") deyiladi. Bozor tilida: imzo — "mahsulot omborimizdan, qadoq ochilmagan" muhri, provenance esa — "qaysi fermada, qaysi kuni yetishtirilgan" sertifikati.

bash
npm view vite@8.3.3 dist.attestations --json
text
{
  "url": "https://registry.npmjs.org/-/npm/v1/attestations/vite@8.3.3",
  "provenance": {
    "predicateType": "https://slsa.dev/provenance/v1"
  }
}

Vite 8.3.3 ning provenance'i bor. Uni npmjs.com dagi paket sahifasida "Provenance" belgisi bilan ham ko'rasiz: undan repo va commitga havola bor. Provenance'i bor paketni muallifning kompyuteridan o'g'irlangan token bilan chiqarib bo'lmaydi — u faqat repodagi ochiq CI jarayonidan keladi.

5.3 Trusted publishing

npm buyruqlari darsida npm view vite ning oxirgi qatorini o'qigan edik: published yesterday by GitHub Actions <npm-oidc-no-reply@github.com>. Bu trusted publishing ("ishonchli nashr"). Paketni odam emas, GitHub Actions chiqargan, va unda uzoq muddatli token umuman yo'q: GitHub har ishga tushirishda npm'ga qisqa muddatli, faqat shu repoga bog'langan ruxsat beradi (OIDC orqali). O'g'irlaydigan token yo'q — Shai-Hulud ishlatgan eshik yopiq.

Shai-Hulud'dan keyin npm qoidalari keskin o'zgardi (GitHub, 2025-09-22 va 2025-12-09 e'lonlari):

  • Kompyuterdan nashr qilish uchun 2FA (ikki bosqichli tasdiq) majburiy; SMS va ilova kodlari o'rniga fishingga chidamli kalitlar (FIDO) tavsiya qilinadi.
  • Eski "klassik" tokenlar 2025-12-09 da butunlay bekor qilindi. npm login endi 2 soatlik sessiya beradi.
  • Nashr qiladigan granular tokenlar ko'pi bilan 7 kun yashaydi; tavsiya etilgan yo'l — trusted publishing.

Siz hozircha paket chiqarmaysiz (bu — kurs oxirida). Lekin npm hisobingiz bo'lsa, bugunoq 2FA'ni yoqing: npmjs.com → Account → Two-Factor Authentication.

5.4 Socket.dev va boshqa skanerlar

npm audit faqat e'lon qilingan zaifliklarni biladi. Socket.dev kabi xizmatlar boshqa savolni beradi: "bu versiya nima qiladi?" Ular yangi versiyada paydo bo'lgan o'rnatish skripti, tarmoqqa murojaat, shifrlangan (obfuskatsiya qilingan) kod, muallif almashuvi kabi belgilarni topadi. GitHub'ga ilova sifatida ulanadi va PR'da "bu yangilashda postinstall qo'shildi" deb yozadi. Ochiq loyihalar uchun bepul rejasi bor. Biz uni o'rnatmaymiz — g'oyasini bilish yetarli: xulqni kuzatish ma'lum zaifliklar ro'yxatidan oldin ogohlantiradi.

Tekshirib ko'ring: npm audit signatures "102 verified registry signatures" dedi. Bu vazifalar dagi paketlarning hech birida zararli kod yo'q degani-mi?

Javob

Yo'q. Imzo faqat "paket registry'dan, o'zgarmagan holda keldi" deydi. chalk ning zararli versiyasi ham haqiqiy registry imzosiga ega edi — uni muallif hisobidan registry'ning o'zi qabul qilgan. Imzo yo'lni himoya qiladi, mazmunni emas. Mazmun uchun — npm audit, skript siyosati va vaqt bilan kutish.

6. min-release-age: yangi versiyani kutib turish

6.1 G'oya

Hodisalar jadvaliga yana qarang. chalk ning zararli versiyalari taxminan ikki soat yashadi. Shai-Hulud versiyalari bir-ikki kunda o'chirildi. Ya'ni zararli versiya odatda yangi bo'ladi. Agar siz faqat bir necha kun "yashab ko'rgan" versiyalarni o'rnatsangiz, ko'p hujum sizgacha yetmaydi.

npm 11 da buning uchun min-release-age sozlamasi bor (kunlarda). Sinov loyihasida 7 kun bilan:

bash
npm i -D -E vite@8.3.3 --min-release-age=7
text
npm error code ETARGET
npm error notarget No matching version found for vite@8.3.3 with a date before 30/09/2026, 11:42:24.
npm error notarget In most cases you or one of your dependencies are requesting a package version that doesn't exist.
npm error A complete log of this run can be found in: …

"30/09/2026 dan oldingi sanali vite@8.3.3 topilmadi". Vite 8.3.3 2026-10-06 da chiqqan — bir kunlik. Versiyasiz so'raymiz:

bash
npm i -D -E vite --min-release-age=7
text
added 15 packages, and audited 16 packages in 7s

1 high severity vulnerability

To address all issues, run:
  npm audit fix

Run `npm audit` for details.

package.json ga "vite": "8.3.1" yozildi — 7 kundan eski eng yangi versiya. Lekin endi zaiflik paydo bo'ldi!

6.2 Narxi: tuzatish ham kutadi

bash
npm explain source-map-js
text
source-map-js@1.2.1 dev
node_modules/source-map-js
  source-map-js@"^1.2.1" from postcss@8.5.28
  node_modules/postcss
    postcss@"^8.5.28" from vite@8.3.1
    node_modules/vite
      dev vite@"8.3.1" from the root project

Zaif paket — source-map-js 1.2.1, Vite → PostCSS orqali kelgan. Tuzatilgan 1.2.2 esa 2026-09-30 14:08 (UTC) da chiqqan — 7 kunlik chegaradan bir necha soat keyin. .npmrc ga min-release-age=7 yozib, npm audit fix qildik:

bash
npm audit fix
text
up to date, audited 16 packages in 1s

# npm audit report

source-map-js  1.0.0 - 1.2.1
Severity: high
source-map-js allows event-loop denial of service through indexed source-map section offsets - https://github.com/advisories/GHSA-68fv-2mgg-jv7q
fix available via `npm audit fix`
node_modules/source-map-js

1 high severity vulnerability

To address all issues, run:
  npm audit fix

Tuzatish ham to'sildi — u ham "juda yangi". Chiqish kodi 1. Bu min-release-age ning narxi: zararli yangi versiyadan himoya qiladi, lekin xavfsizlik tuzatishini ham kechiktiradi. Chiqish yo'li — istisno:

text
min-release-age=7
min-release-age-exclude=source-map-js

Shu .npmrc bilan npm audit fix — changed 1 package … found 0 vulnerabilities, source-map-js@1.2.2 o'rnatildi.

pnpm'da xuddi shu g'oya — pnpm-workspace.yaml dagi minimumReleaseAge (daqiqada, 10080 = 7 kun):

text
  × adding a new package
  ╰─▶ 1 version does not meet the minimumReleaseAge constraint:
        vite@8.3.3 was published at 2026-10-06T04:10:19.326Z, within the
      minimumReleaseAge cutoff (2026-09-30T06:44:13.536Z)

6.3 Nega vazifalar da yo'q

vazifalar kursda "aniq, joriy versiyalar" bilan yuradi: Vite 8.3.3 chiqqanining ertasiga o'rnatilgan va sinalgan. min-release-age=7 bilan bu mumkin emas edi. Bundan tashqari, loyihamiz paket chiqarmaydi va har versiyani qo'lda, aniq tanlaydi (save-exact, lock, npm ci). Shuning uchun biz uni namoyish qildik, lekin kanonga yozmadik — bu ongli savdolashuv.

Ish joyidagi qoida boshqacha bo'lishi mumkin: avtomatik yangilanadigan katta loyihalarda 1–7 kunlik kutish keng tarqalgan. Muhimi — tanlovni bilib qilish va xavfsizlik tuzatishlari uchun istisno yo'lini bilish.

Tekshirib ko'ring: Malika: "min-release-age=30 qo'yaylik — 30 kun kutsak, yanada xavfsiz" dedi. Qanday e'tiroz bildirasiz?

Javob

30 kun davomida hamma xavfsizlik tuzatishlari ham to'siladi: ma'lum zaiflik bir oy ochiq turadi. Hujumlarning ko'pi soatlar yoki kunlar ichida topiladi, shuning uchun bir necha kundan keyin foyda deyarli oshmaydi, zarar esa o'sadi. Ko'p jamoa 1–7 kun tanlaydi va shoshilinch tuzatishni min-release-age-exclude bilan o'tkazadi.

7. Hujumchi nigohi

Hujumchi «Bahor» saytiga to'g'ridan-to'g'ri hujum qilmaydi. U eng zaif halqani izlaydi:

  1. Sardorning kompyuteri. Sardor npm i vitee deb xato yozdi. Paketning postinstall i .env fayllarni, ~/.npmrc dagi tokenni, SSH kalitlarni o'qib, tashqariga yuboradi. Qarshi: npm view bilan tekshirish, allowScripts ning ogohlantirishini o'qish, tokenlarni loyiha papkasida saqlamaslik.
  2. CI. GitHub Actions'da npm install — yangi versiya kirib keladi, postinstall GITHUB_TOKEN ni o'g'irlaydi. Qarshi: CI'da faqat npm ci (lock'dagi aniq versiyalar), permissions: contents: read (Actions orqali deploy darsidagidek eng kam huquq), npm audit signatures.
  3. Foydalanuvchining brauzeri. Buzilgan kutubxona dist/ ga tushadi va saytingizda ishlaydi — chalk hodisasidagi kabi fetch ni "o'rab", ma'lumotni almashtiradi. Qarshi: brauzerga boradigan bog'liqliklar kam bo'lsin (vazifalar da bittagina — web-vitals), CSP va Trusted Types (XSS va DOM xavfsizligi) begona manzilga so'rovni to'sadi.

vazifalar ning himoyasi qatlam-qatlam. Unda aniq versiyalar (save-exact), lock va npm ci, CI'da imzo tekshiruvi, o'rnatish skripti bor paket umuman yo'q (npm install-scripts ls — No packages with unreviewed install scripts.), brauzerda CSP bor. Hech bir qatlam o'zi yetarli emas — lekin birgalikda hujumni ancha qimmatlashtiradi.

8. Ko'p uchraydigan xatolar

Xato Nega xavfli To'g'risi
CI'da npm install yangi (zararli bo'lishi mumkin) versiya kirib keladi npm ci
npm audit fix --force ni o'qimasdan MAJOR o'rnatib, kodni buzishi mumkin Will install … ni o'qing
"0 vulnerabilities — xavfsiz" faqat e'lon qilinganlar qatlamli himoya
tokenni .npmrc ga yozib, commit qilish repo bilan birga tarqaladi ${NPM_TOKEN} yoki trusted publishing

To'rtinchi qatorni .npmrc darsidan eslang: loyihadagi .npmrc git'ga kiradi. Unga //registry.npmjs.org/:_authToken=npm_XXXX… kabi haqiqiy tokenni hech qachon yozmang.

9. Mashqlar

Mashqlar kurs/mashqlar/16/16-taminot/ da.

1-mashq (oson): Hisobotni o'qing

«npm audit: ma'lum zaifliklar» bo'limidagi nanoid hisobotiga qarab javob bering:

  • Zaif versiyalar chegarasi:
  • Jiddiylik darajasi:
  • Nechta alohida zaiflik (GHSA) sanalgan:
  • Nega oddiy npm audit fix tuzatmadi?
Yechim

<=3.3.17, high, 4 ta GHSA-… havola. Oddiy fix package.json dagi chegaradan chiqmaydi: u yerda aniq "3.3.4" yozilgan, tuzatish esa 3.3.20 da (outside the stated dependency range). --force chegarani buzadi — shuning uchun avval qaysi versiya o'rnatilishini o'qish kerak.

2-mashq (o'rta): Skript siyosati

Yangi papkada npm init -y, keyin npm i -D -E esbuild@0.28.2 va npm i -E core-js@3.50.0.

  1. npm install-scripts ls nechta paketni ko'rsatadi?
  2. esbuild'ga ruxsat bering, core-js'ni rad eting. package.json dagi allowScripts qanday ko'rinadi?
  3. node_modules ni o'chirib, npm ci --strict-allow-scripts. Xato chiqadimi?

Yordam: core-js ning skriptini npm view core-js@3.50.0 scripts bilan o'qing — u nima qiladi?

Yechim
  1. Ikkita: esbuild@0.28.2 (postinstall: node install.js) va core-js@3.50.0 (postinstall: node -e "try{require('./postinstall')}catch(e){}").
  2. npm install-scripts approve esbuild va npm install-scripts deny core-js:
json
{
  "allowScripts": {
    "esbuild@0.28.2": true,
    "core-js": false
  }
}

Ruxsat versiyaga bog'langan, rad etish esa nomga — rad etilgan paketning hech bir versiyasi skript ishlatmaydi.

  1. Xato yo'q: added 3 packages, … found 0 vulnerabilities. Hamma skript ko'rib chiqilgan. core-js'ning skripti faqat homiylik haqidagi xabarni chiqaradi, kutubxona ishlashiga ta'sir qilmaydi.

3-mashq (qiyin): Lock-fayl tekshiruvchisi

lock-tekshir.mjs yozing. U auditLock(lock) funksiyasini eksport qiladi: package-lock.json obyektini olib, uch ro'yxat qaytaradi — installScripts (o'rnatish skripti bor paketlar), notRegistry (resolved manzili https://registry.npmjs.org/ bilan boshlanmaydiganlar), noIntegrity (integrity maydoni yo'qlar). Har element — nom@versiya. Fayl buyruq qatoridan ishga tushirilganda lock'ni o'qib, natijani chiqarsin va oxirgi ikki ro'yxatdan biri bo'sh bo'lmasa, chiqish kodi 1 bo'lsin.

Ishoralar:

  • Lock'da (lockfileVersion: 3) paketlar lock.packages obyektida: kalit — "node_modules/esbuild" kabi yo'l, "" — ildiz loyiha (uni tashlang). Ichma-ich paket kaliti "node_modules/a/node_modules/b" — nom oxirgi node_modules/ dan keyin.
  • Skripti bor paketda npm "hasInstallScript": true yozadi.
  • info.resolved?.startsWith(…) — optional chaining: resolved yo'q bo'lsa ham xato bermaydi.
  • import.meta.main — Node 24 da: fayl to'g'ridan-to'g'ri node fayl.mjs bilan ishga tushirilganda true, import qilinganda false. process.exitCode = 1 — dasturni to'xtatmay, chiqish kodini belgilaydi.
  • Funksiyani node:test bilan sinang: kichik soxta lock obyekti yetarli.
Yechim

lock-tekshir.mjs:

js
// lock-tekshir.mjs — package-lock.json dagi xavf belgilari
import { readFileSync } from "node:fs";

const REGISTRY = "https://registry.npmjs.org/";

// "node_modules/a/node_modules/b" → "b"
function packageName(path) {
  return path.slice(path.lastIndexOf("node_modules/") + 13);
}

export function auditLock(lock) {
  const installScripts = [];
  const notRegistry = [];
  const noIntegrity = [];
  for (const [path, info] of Object.entries(lock.packages)) {
    if (path === "" || info.link) continue; // ildiz va havolalar
    const id = `${packageName(path)}@${info.version}`;
    if (info.hasInstallScript) installScripts.push(id);
    if (!info.resolved?.startsWith(REGISTRY)) notRegistry.push(id);
    if (!info.integrity) noIntegrity.push(id);
  }
  return { installScripts, notRegistry, noIntegrity };
}

// node lock-tekshir.mjs <papka>/package-lock.json
if (import.meta.main) {
  const file = process.argv[2] ?? "package-lock.json";
  const lock = JSON.parse(readFileSync(file, "utf8"));
  const report = auditLock(lock);
  for (const [key, list] of Object.entries(report)) {
    console.log(`${key}: ${list.length ? list.join(", ") : "—"}`);
  }
  const bad = report.notRegistry.length + report.noIntegrity.length;
  process.exitCode = bad ? 1 : 0;
}

13 — "node_modules/" satrining uzunligi. info.link — workspace yoki npm link havolasi (Begona paketni tuzatish darsida), unda arxiv yo'q.

Test (lock-tekshir.test.mjs) ning asosiy holati:

js
import { test } from "node:test";
import assert from "node:assert/strict";
import { auditLock } from "./lock-tekshir.mjs";

const R = "https://registry.npmjs.org/";

test("o'rnatish skripti, begona manba va integrity'siz paket", () => {
  const lock = {
    packages: {
      "": { name: "menyu" },
      "node_modules/esbuild": {
        version: "0.28.2",
        resolved: `${R}esbuild/-/esbuild-0.28.2.tgz`,
        integrity: "sha512-x",
        hasInstallScript: true,
      },
      "node_modules/a/node_modules/rang": {
        version: "1.0.0",
        resolved: "https://example.com/rang-1.0.0.tgz",
      },
    },
  };
  assert.deepEqual(auditLock(lock), {
    installScripts: ["esbuild@0.28.2"],
    notRegistry: ["rang@1.0.0"],
    noIntegrity: ["rang@1.0.0"],
  });
});

Ikkinchi test — toza lock uchun uchala ro'yxat bo'sh; uni o'zingiz yozing. node --test lock-tekshir.test.mjs — ℹ tests 2, ℹ pass 2, ℹ fail 0.

2-mashqdagi loyihada:

bash
node lock-tekshir.mjs package-lock.json; echo "exit $?"
text
installScripts: core-js@3.50.0, esbuild@0.28.2
notRegistry: —
noIntegrity: —
exit 0

vazifalar da — uchala ro'yxat —, exit 0. menyu-rang kabi lokal .tgz dan o'rnatilgan paket esa notRegistry ga tushadi va exit 1 beradi: u registr imzosidan o'tmagan.

4-mashq: Vazifalar qadami — .npmrc va imzo tekshiruvi

vazifalar ga ikki narsa qo'shamiz: loyiha .npmrc i (versiyalar doim aniq, Node talabi qat'iy) va CI'da registr imzolari tekshiruvi.

  • Branch: chore/npmrc
  • Commit: chore: .npmrc (save-exact, engine-strict), CI'da npm audit signatures
  1. Ildizda .npmrc yarating: save-exact=true va engine-strict=true, har biri izoh bilan.
  2. .github/workflows/pages.yml — check job'ida npm ci dan keyin npm audit signatures qadami.
  3. Tekshiring: npm config get save-exact engine-strict, npm audit, npm audit signatures, npm install-scripts ls.

Tekshiruv: npm test, npm run build, npm run lint, npm run format:check, npm run tip — hammasi exit 0.

Yechim

.npmrc:

text
# npm sozlamalari — shu loyiha uchun (16/#16, ta'minot zanjiri)
# npm i paket → "paket": "1.2.3" (^ siz): versiyani o'zimiz tanlaymiz
save-exact=true
# package.json "engines" (Node >= 24) — mos kelmasa o'rnatish to'xtaydi
engine-strict=true

save-exact — endi -E ni unutsangiz ham, npm ^ siz yozadi. engine-strict — Node versiya menejerlari darsidagi va'da: engines talabi endi ogohlantirish emas, xato.

pages.yml (check job'i):

yaml
      - run: npm ci
      # Har paket registry imzosi bilan (soxta tarball yo'q) — 16/#16
      - run: npm audit signatures
      # format:check, lint, tip, test — package.json "check" skripti
      # (lokalda ham aynan shu buyruq: npm run check)
      - run: npm run check

npm audit ni CI'ga qo'shmadik: u kod o'zgarmasa ham, yangi e'lon bilan qizil bo'ladi va deploy'ni to'xtatadi. Uni lokalda va alohida yuritamiz.

Sinov (haqiqiy chiqish):

bash
npm config get save-exact engine-strict
text
save-exact=true
engine-strict=true
bash
npm i -D picocolors
npm pkg get devDependencies.picocolors
text
"1.1.1"

Belgisiz — .npmrc ishlayapti (bu sinov edi: git restore package.json package-lock.json bilan qaytaring). npm audit — found 0 vulnerabilities; npm audit signatures — «Registr imzosi» bo'limidagidek 102/102 va 30 attestation; npm install-scripts ls — No packages with unreviewed install scripts.

Natija: npm test — 143/143. 159 ta brauzer tekshiruvi — 159/159. Ilova xulqi o'zgarmadi.

Commit va PR:

bash
git switch -c chore/npmrc
npm test && npm run build && npm run tip
npm run lint && npm run format:check
git add .npmrc .github/workflows/pages.yml
git commit -m \
"chore: .npmrc (save-exact, engine-strict),\
 CI'da npm audit signatures"
git push -u origin chore/npmrc
gh pr create --fill
gh pr merge --merge

Commit sarlavhasi — 69 belgi. Diff: 2 fayl, +7.

10. Real ishda

  • Ish joyidagi birinchi hafta: npm audit, npm audit signatures, npm install-scripts ls — loyiha "gigiyenasini" besh daqiqada ko'rasiz.
  • Kompaniyalar Socket, Snyk, GitHub Dependabot alerts kabi xizmatlarni ishlatadi; katta tashkilotlarda o'z ichki registr oynasi (Verdaccio, Artifactory) va ruxsat etilgan paketlar ro'yxati bo'ladi.
  • Kutubxona chiqarsangiz — trusted publishing va 2FA endi deyarli majburiy; provenance belgisi foydalanuvchiga ishonch beradi.
  • Intervyu savollari: "Supply chain attack nima, misol keltiring", "npm audit nimani ko'rmaydi?", "postinstall nega xavfli?", "lock-fayl xavfsizlikka qanday yordam beradi?".

Xulosa

  • Ta'minot zanjiri hujumi siz ishonadigan paketni buzadi: o'xshash nom, o'g'irlangan hisob, o'rnatish skripti orqali.
  • npm audit — faqat e'lon qilingan zaifliklar; --force dan oldin Will install … ni o'qing; "0" — xavfsiz degani emas.
  • postinstall npm install paytida sizning huquqlaringiz bilan ishlaydi; npm 11.19 allowScripts (versiyaga bog'langan ruxsat), strict-allow-scripts va ignore-scripts bilan boshqariladi; pnpm skriptlarni sukut bo'yicha to'sadi.
  • Imzo — "registry'dan, o'zgarmagan"; provenance — "qayerda va qaysi commitdan yig'ilgan"; trusted publishing tokenni yo'q qiladi.
  • min-release-age yangi zararli versiyadan himoya qiladi, lekin tuzatishni ham kechiktiradi — vazifalar da namoyish qilindi, kanonga kirmadi.

Keyingi dars: Bog'liqliklarni yangilash strategiyasi — eskirgan paketlarni xavfsiz yangilash: changelog o'qish, MAJOR migratsiya, npm-check-updates, Renovate va Dependabot.

Manbalar

  • npm Docs (v11): npm audit, config: min-release-age, allow-scripts, strict-allow-scripts, ignore-scripts, "Generating provenance statements", "Trusted publishing for npm packages" — docs.npmjs.com
  • GitHub blog: "Our plan for a more secure npm supply chain" (2025-09-22) — github.blog/security/supply-chain-security/our-plan-for-a-more-secure-npm-supply-chain/
  • GitHub changelog: "npm classic tokens revoked, session-based auth and CLI token management now available" (2025-12-09)
  • CISA: "Widespread Supply Chain Compromise Impacting npm Ecosystem" (2025-09-23) — cisa.gov/news-events/alerts/2025/09/23/widespread-supply-chain-compromise-impacting-npm-ecosystem
  • Endor Labs / Check Point: chalk va debug hodisasi (2025-09-08); Check Point: "Shai-Hulud 2.0" (2025-11)
  • npm blog: "Details about the event-stream incident" (2018-11-27); CISA: "Malware Discovered in Popular NPM Package, ua-parser-js" (2021-10-22); CVE-2024-3094 (xz-utils, 2024-03-29); npm blog: "crossenv malware on the npm registry" (2017-08-02)
  • pnpm: minimumReleaseAge, approve-builds — pnpm.io/settings
Ulashish:Telegram'da

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!
Ta'minot zanjiri xavfsizligi: npm audit, postinstall, typosquatting va provenance — IlmHamroh