Mundarija (33)
- Bu darsda
- 1. Nega bu kerak?
- 2. Hujum qayerdan keladi
- 2.1 Beshta eshik
- 2.2 Haqiqiy hodisalar
- 2.3 Typosquatting
- 3. npm audit: ma'lum zaifliklar
- 3.1 Hisobotni o'qish
- 3.2 Chiqish kodi va --audit-level
- 3.3 npm audit fix va --force
- 4. O'rnatish skriptlari: eng xavfli eshik
- 4.1 postinstall nima qila oladi
- 4.2 allowScripts: npm 11 dagi ruxsat ro'yxati
- 4.3 ignore-scripts: hammasini o'chirish
- 5. Imzo, provenance va trusted publishing
- 5.1 Registr imzosi
- 5.2 Provenance: paket qayerda yig'ilgan
- 5.3 Trusted publishing
- 5.4 Socket.dev va boshqa skanerlar
- 6. min-release-age: yangi versiyani kutib turish
- 6.1 G'oya
- 6.2 Narxi: tuzatish ham kutadi
- 6.3 Nega vazifalar da yo'q
- 7. Hujumchi nigohi
- 8. Ko'p uchraydigan xatolar
- 9. Mashqlar
- 1-mashq (oson): Hisobotni o'qing
- 2-mashq (o'rta): Skript siyosati
- 3-mashq (qiyin): Lock-fayl tekshiruvchisi
- 4-mashq: Vazifalar qadami — .npmrc va imzo tekshiruvi
- 10. Real ishda
- Xulosa
- Manbalar
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,allowScriptsvaignore-scripts— o'rnatish skriptlari,min-release-age— juda yangi versiyani kutish.vazifalarga bugun.npmrcva CI'da imzo tekshiruvi qo'shiladi.
Bu darsda
- Ta'minot zanjiri hujumi nima ekanini haqiqiy hodisalar (2017–2025) misolida tushuntira olasiz.
npm audithisobotini o'qiysiz vanpm audit fixqachon xavfli ekanini bilasiz.postinstallskripti nima qila olishini ko'rasiz va uniallowScripts,ignore-scriptsbilan boshqarasiz.- Imzo, provenance va trusted publishing nima ekanini,
npm audit signatureschiqishini o'qiysiz. min-release-agening 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"] -.-> BUzluksiz 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:
npm view crossenvcrossenv@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:
chalkhodisasida 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:
npm i -E nanoid@3.3.4added 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:
npm audit# 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:
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
npm audit fixup to date, audited 2 packages in 1s
# npm audit report
…
1 high severity vulnerability
To address all issues, run:
npm audit fix --forceHech 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:
npm audit fix --forcenpm 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 vulnerabilitiesBu 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 auditfaqat ma'lum va e'lon qilingan zaifliklarni biladi. 2025-yil 8-sentabrdagichalkversiyasi chiqqan zahotifound 0 vulnerabilitiesderdi: hali hech kim e'lon qilmagan edi. npm buyruqlari darsidan yana bir saboq: internetsiznpm auditham "0" deydi. "0" — "xavfsiz" degani emas.
Tekshirib ko'ring: CI'da
npm auditqadami 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:
// 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:
npm i ../menyu-rang/menyu-rang-1.0.0.tgzadded 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:
cat IZ.txtpostinstall ishladi; muhitda 130 ta o'zgaruvchiSkript 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:
npm i -D -E esbuild@0.28.2added 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:
npm install-scripts approve esbuildApproved esbuild:
added esbuild@0.28.2package.json ga yangi maydon yozildi:
{
"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:
npm install-scripts deny core-jsDenied core-js:
added core-jsEndi "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:
npm ci --strict-allow-scriptsnpm 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.
npm ci --ignore-scripts
npx esbuild --versionadded 3 packages, and audited 4 packages in 1s
found 0 vulnerabilities
0.28.2esbuild 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
allowScriptspaket nomiga emas,esbuild@0.28.2ga — 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):
npm audit signaturesaudited 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.
npm view vite@8.3.3 dist.attestations --json{
"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 loginendi 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. Buvazifalardagi 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:
npm i -D -E vite@8.3.3 --min-release-age=7npm 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:
npm i -D -E vite --min-release-age=7added 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
npm explain source-map-jssource-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 projectZaif 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:
npm audit fixup 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 fixTuzatish 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:
min-release-age=7
min-release-age-exclude=source-map-jsShu .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):
× 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=30qo'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:
- Sardorning kompyuteri. Sardor
npm i viteedeb xato yozdi. Paketningpostinstalli.envfayllarni,~/.npmrcdagi tokenni, SSH kalitlarni o'qib, tashqariga yuboradi. Qarshi:npm viewbilan tekshirish,allowScriptsning ogohlantirishini o'qish, tokenlarni loyiha papkasida saqlamaslik. - CI. GitHub Actions'da
npm install— yangi versiya kirib keladi,postinstallGITHUB_TOKENni o'g'irlaydi. Qarshi: CI'da faqatnpm ci(lock'dagi aniq versiyalar),permissions: contents: read(Actions orqali deploy darsidagidek eng kam huquq),npm audit signatures. - Foydalanuvchining brauzeri. Buzilgan kutubxona
dist/ga tushadi va saytingizda ishlaydi —chalkhodisasidagi kabifetchni "o'rab", ma'lumotni almashtiradi. Qarshi: brauzerga boradigan bog'liqliklar kam bo'lsin (vazifalarda 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 fixtuzatmadi?
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.
npm install-scripts lsnechta paketni ko'rsatadi?- esbuild'ga ruxsat bering, core-js'ni rad eting.
package.jsondagiallowScriptsqanday ko'rinadi? node_modulesni 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
- Ikkita:
esbuild@0.28.2 (postinstall: node install.js)vacore-js@3.50.0 (postinstall: node -e "try{require('./postinstall')}catch(e){}"). npm install-scripts approve esbuildvanpm install-scripts deny core-js:
{
"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.
- 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) paketlarlock.packagesobyektida: kalit —"node_modules/esbuild"kabi yo'l,""— ildiz loyiha (uni tashlang). Ichma-ich paket kaliti"node_modules/a/node_modules/b"— nom oxirginode_modules/dan keyin. - Skripti bor paketda npm
"hasInstallScript": trueyozadi. info.resolved?.startsWith(…)— optional chaining:resolvedyo'q bo'lsa ham xato bermaydi.import.meta.main— Node 24 da: fayl to'g'ridan-to'g'rinode fayl.mjsbilan ishga tushirilgandatrue, import qilingandafalse.process.exitCode = 1— dasturni to'xtatmay, chiqish kodini belgilaydi.- Funksiyani
node:testbilan sinang: kichik soxta lock obyekti yetarli.
Yechim
lock-tekshir.mjs:
// 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:
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:
node lock-tekshir.mjs package-lock.json; echo "exit $?"installScripts: core-js@3.50.0, esbuild@0.28.2
notRegistry: —
noIntegrity: —
exit 0vazifalar 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
- Ildizda
.npmrcyarating:save-exact=truevaengine-strict=true, har biri izoh bilan. .github/workflows/pages.yml—checkjob'idanpm cidan keyinnpm audit signaturesqadami.- 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:
# 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=truesave-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):
- 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 checknpm 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):
npm config get save-exact engine-strictsave-exact=true
engine-strict=truenpm i -D picocolors
npm pkg get devDependencies.picocolors"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:
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 --mergeCommit 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 auditnimani 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;--forcedan oldinWill install …ni o'qing; "0" — xavfsiz degani emas.postinstallnpm installpaytida sizning huquqlaringiz bilan ishlaydi; npm 11.19allowScripts(versiyaga bog'langan ruxsat),strict-allow-scriptsvaignore-scriptsbilan 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-ageyangi zararli versiyadan himoya qiladi, lekin tuzatishni ham kechiktiradi —vazifalarda 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:
chalkvadebughodisasi (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
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!