npm 12 اومد — سه تغییری که ممکنه build رو خراب کنه
اگه توی تیمت کسی هست که هنوز از git+https://github.com/... توی package.json استفاده میکنه، یا یه package داری که موقع install یه native build میزنه، این مقاله برای اون آدمه. npm 12 توی جولای ۲۰۲۶ منتشر میشه — pre-release از ۱۹ ژوئن بیرون اومده — و سه breaking change داره که هر سهشون میتونن یه CI pipeline رو بیسروصدا خاموش کنن.
زمینهی این تغییرات مهمه: یه سال حملهی supply chain. سپتامبر ۲۰۲۵، اتکرها ۱۸ package معروف از جمله debug و chalk رو hijack کردن — packageهایی که هفتهای ۲.۶ میلیارد بار دانلود میشن. مارس ۲۰۲۶، کتابخونهی Axios از طریق credential دزدیدهشده compromise شد. ژوئن ۲۰۲۶، یه کِرم به اسم Miasma 57 package رو توی دو ساعت آلوده کرد. همهی این حملهها از یه مکانیزم استفاده کردن که npm از ده سال پیش داشت: هر package میتونست موقع install کد دلخواه اجرا کنه، بدون هیچ اجازهی صریحی.
npm 12 این رو عوض میکنه.
تغییر اول: install scripts دیگه خودکار اجرا نمیشن
این مهمترین و شکنندهترین تغییره. تا الان وقتی npm install میزدی، هر package ای میتونست preinstall، install، و postinstall اجرا کنه — بدون اینکه بدانی. از npm 12، این scriptها بهطور پیشفرض block میشن مگه اینکه صریح approveشون کرده باشی.
چیزی که خیلیها نمیدونن: این شامل native addon ها هم میشه. اگه یه package یه فایل binding.gyp داشته باشه، npm قبلاً بهطور خودکار node-gyp rebuild رو میزد — حتی بدون هیچ install script صریحی. این همون مکانیزمی بود که Phantom Gyp attack ازش سوءاستفاده کرد: یه binding.gyp صد و پنجاهوهفت بایتی داخل یه package آلوده، و npm خودش کد مخرب رو compile و اجرا میکرد. npm 12 این رو هم block میکنه.
برای دیدن اینکه الان کدوم packageها script دارن:
npm approve-scripts --allow-scripts-pending
این دستور لیست میده بدون اینکه چیزی رو approve کنه. بعد از اینکه تیکرهایی که بهشون اعتماد داری رو approve کردی:
npm approve-scripts <package-name>
این approve به package.json commit میشه — یعنی میتونی توی PR review کنی و ببینی چه packageای اجرای script گرفته.
یه edge case مهم: npm rebuild هم subject to این block هست. اگه یه package توی allowlist نباشه، npm rebuild <package> بیسروصدا skip میکنه. راهحل:
npm approve-scripts <package>
npm rebuild <package>
تغییر دوم: Git dependency ها block میشن
اگه توی package.json ات چنین چیزی داری:
"some-lib": "git+https://github.com/org/repo.git"
از npm 12 این کار نمیکنه مگه اینکه --allow-git استفاده کنی.
این تغییر از فوریه ۲۰۲۶ اعلام شده بود. دلیلش اینه که یه Git dependency میتونه یه .npmrc داخل خودش داشته باشه که مسیر اجرایی git رو override کنه — حتی وقتی --ignore-scripts هم گذاشته باشی. خیلی از تیمها فکر میکردن --ignore-scripts محافظشون میکنه، ولی این attack vector کاملاً جدا بود.
اگه از Git dependency برای یه package داخلی استفاده میکنی، بهترین راه اینه که به یه registry مایگریت کنی — GitHub Packages، Nexus، یا Artifactory. اضافه کردن --allow-git به هر CI script، مشکل رو حل نمیکنه، فقط جابهجاش میکنه.
تغییر سوم: remote URL ها block میشن
مشابه Git، اگه package ای داری که از یه URL مستقیم نصب میشه:
"internal-tool": "https://cdn.internal.com/packages/tool-1.2.3.tgz"
از npm 12 بدون --allow-remote کار نمیکنه.
remote URL ها unverifiable ان — npm نمیتونه تضمین کنه که اون tarball دستکاری نشده. حل درست اینه که به یه registry بری که integrity check داره.
چطور الان آماده بشی
npm 11.16.0 آخرین نسخهی stable از 11.x هست. اگه upgrade کنی، همهی این blocking ها بهصورت warning نشون داده میشن — نه error. یعنی میتونی قبل از اینکه npm 12 بیاد ببینی چی میشکنه:
npm install -g npm@11.16.0
npm install # warnings نشون میده ولی نمیشکنه
npm approve-scripts --allow-scripts-pending # لیست میده
بعد از اینکه لیست گرفتی، packageهایی رو که بهشون اعتماد داری approve کن و package.json رو commit کن. یه چیزی که نباید بکنی: همه رو با یه flag blanket approve کنی فقط برای اینکه warningها ساکت بشن — این کل هدف تغییر رو از بین میبره.
کدوم پروژهها بیشترین ریسک رو دارن
پروژههایی که به احتمال بالا مشکل پیدا میکنن:
هر پروژهای که native addon دارد — یعنی packageهایی مثل bcrypt، sharp، canvas، node-sass، یا هر چیزی که به C/C++ compile وابستهست. این packageها برای کار کردن به script اجرا شدن نیاز دارن.
هر پروژهای که Git dependency دارد — معمولاً برای fork های داخلی یا patched نسخهها.
هر پروژهای که از HTTPS tarball برای package های داخلی استفاده میکنه.
اگه از هیچکدوم از اینا استفاده نمیکنی، احتمالاً npm 12 برات transparent باشه.
یه نکته دربارهی پکیج نویسها
اگه خودت package نگهداری میکنی که native build داره، بهترین راه اینه که prebuilt binary بشیپ کنی — با ابزارهایی مثل prebuild، prebuildify، یا node-pre-gyp. packageای که install-time compilation نداره، نمیتونه از این attack vector استفاده بشه. این یه بهبود بلندمدت هست که ارزش وقت گذاشتن داره.
این بزرگترین تغییر امنیتی npm در شانزده سال گذشتهست. ولی فقط یه تغییر configuration نیست — یه تغییر مدل اعتماده. ده سال بود که هر npm install بهمعنای دادن حق اجرای کد دلخواه به همهی چیزی بود که توی dependency tree ات بود. این پیشفرض داشت تغییر میکرد — فقط کمی طول کشید.