npm 12: سكربتات التثبيت صارت اختيارية

في 8 يوليو 2026 وصل npm 12 إلى الإصدار العام، ومعه أكبر تغيير في سلوك npm install منذ سنين: سكربتات دورة الحياة — preinstall وinstall وpostinstall — ما عادت تشتغل تلقائيًا. صارت تحتاج موافقة صريحة، والموافقة نفسها تُحفَظ في package.json وتُراجَع في الـ Pull Request مثل أي كود ثاني.

المشكلة: npm install كان يعني «شغّل كودهم على جهازك»

منذ بداية الـ registry، أي حزمة تقدر تعرّف سكربت تثبيت ينفّذ أوامر عشوائية بصلاحيات المستخدم اللي كتب npm install. ما تحتاج تستورد الحزمة ولا تشغّلها — مجرد التثبيت كافٍ. وهذا بالضبط المسار اللي استُغل مرارًا خلال 2026 في سلسلة اختراقات لحزم منشورة على npm، منها اختراق حزم مولّد AsyncAPI الذي وثّقته Microsoft في يوليو 2026.

الأسوأ أن السطح ما يتوقف على الاعتماديات المباشرة. شجرة اعتماديات فيها 1,200 حزمة تعني 1,200 فرصة تنفيذ، أغلبها ما أحد قرأها ولا يعرف من ينشرها.

ما الذي تغيّر فعليًا

الإعدادات الافتراضية الثلاثة الجديدة في npm 12:

  • allowScripts صار معطّلًا. سكربتات دورة الحياة وبناء node-gyp الضمني ما تعمل إلا بموافقة.
  • --allow-git صار none. اعتماديات Git — مباشرة أو غير مباشرة — ما تُحَل إلا بسماح صريح.
  • --allow-remote صار none. الاعتماديات من روابط بعيدة (مثل أرشيفات https) محجوبة افتراضيًا.

أما --allow-file و--allow-directory فبقيت على حالها.

المسار العملي للترقية

الخطوة الأذكى أنك تكتشف الأثر قبل ما تتحوّل CI إلى أحمر. ابدأ من npm 11.16.0 أو أحدث، فهو ينبّه على السكربتات غير المغطّاة بينما ما زال ينفّذها:

bash
npm i -g npm@latest
npm approve-scripts --allow-scripts-pending   # يعرض الحزم المنتظرة دون تعديل شيء

ثم اعتمد ما تحتاجه فعلًا، حزمة حزمة:

bash
npm approve-scripts sharp esbuild

الموافقة تُثبَّت على النسخة المثبّتة (pkg@1.2.3) إلا إذا استخدمت --no-allow-scripts-pin. وللحجب الصريح:

bash
npm deny-scripts some-package

ولفرض سلوك الإصدار 12 مبكرًا داخل CI — بحيث يفشل البناء بدل أن يتخطّى السكربتات بصمت:

ini
# .npmrc
strict-allow-scripts=true

بعدها يصير npm ci بوابة حقيقية: أي اعتمادية جديدة تحاول تنفيذ كود عند التثبيت توقف الأنبوب وتطلب مراجعة بشرية.

تحفّظات من الواقع

الحزم الثنائية أول من يتأثر. أي حزمة تُنزّل ملفًا تنفيذيًا جاهزًا أو تبني إضافة أصلية تعتمد على postinstall. تعطيلها بلا موافقة يعني بناءً ينجح ثم يفشل وقت التشغيل برسالة مضلّلة. اعتمدها بوعي، وسجّل السبب في وصف الـ PR.

تثبيت النسخة يولّد ضجيجًا. كل ترقية اعتمادية تُبطل الموافقة المثبّتة، فتظهر مراجعات إضافية في PRs الآلية. هذا ليس عيبًا — هذه هي الفائدة: مراجعة عند كل تغيّر في الكود الذي سيُنفَّذ.

اعتماديات Git تكسر الفروع الداخلية. الفِرَق اللي تشير إلى نسخة معدّلة عبر رابط Git تحتاج تمرير --allow-git صراحةً، أو الانتقال إلى registry خاص.

موعد ثانٍ على التقويم. التغييرات الأمنية لا تقف هنا: ابتداءً من أوائل أغسطس 2026، رموز الوصول الدقيقة (GATs) المهيّأة لتجاوز المصادقة الثنائية تفقد قدرتها على العمليات الحسّاسة، وفي يناير 2027 تفقد النشر المباشر. البديل الموصى به هو trusted publishing عبر OIDC أو النشر المرحلي بموافقة بشرية.

الخلاصة

npm 12 ينقل تنفيذ الكود وقت التثبيت من «افتراضي وصامت» إلى «صريح ومُراجَع». هذا ليس تشديدًا شكليًا — إنه إغلاق لأوسع مسار استغلال في منظومة جافاسكربت، ونقل القرار إلى مكانه الصحيح: مراجعة الكود.

الفريق الذي يمرّ بهذا الانتقال اليوم على npm 11.16 مع strict-allow-scripts=true يدخل الإصدار 12 بقائمة موافقات نظيفة ومفهومة. والفريق الذي يؤجّل سيكتشفها يوم يتوقف خط الإنتاج.

للمزيد عن التعامل مع موجة التحديثات الأمنية في المنظومة، راجع إصدار Next.js الأمني في يوليو 2026.

المصدر الأساسي: npm install-time security and GAT bypass2fa deprecation — GitHub Changelog

npm 12: سكربتات التثبيت صارت اختيارية · bahashwan.dev