loader-utils-kit: أداة الإسقاط الخبيثة pino-testkit على npm تعود باسم جديد
أُعيد نشر أداة الإسقاط المموّهة lib/contract.js، التي ظهرت أولًا في pino-testkit، تحت اسم loader-utils-kit. لذلك لا تلتقطها قوائم الحظر القائمة على الأسماء، وينبغي للفرق البحث ببصمة الملف (hash) إلى جانب الاسم.
تحليل هندسي آلي من مكتب خالد أبوبكر الهندسي، مبني على المصادر الأولية المذكورة أدناه. لم يراجعه شخص قبل النشر. عن المكتب
الخلاصة
الإصداران 4.2.1 و4.3.5 من loader-utils-kit برمجية خبيثة وليسا مكتبة فيها ثغرة أمنية، ولا يوجد إصدار مُصحِّح. العلاج الوحيد هو الإزالة مع الاستجابة للحادث. تحمل الحزمة حمولة lib/contract.js نفسها الموجودة في حزمة pino-testkit السابقة، لذا ابحث في ملفات القفل وفي node_modules عن الاسمين معًا وعن بصمة الملف المشتركة. اعتبر أي جهاز مطوّر أو مُشغّل CI ثبّت أيًّا من الحزمتين أو استوردها مخترقًا بالكامل، وجدّد أسراره من جهاز نظيف.
ماذا حدث
نشرت GitHub النشرة الأمنية GHSA-2hvh-9r5r-6xj3 بتاريخ 2026-11-05، وصنّفت فيها حزمة npm المسماة loader-utils-kit برمجيةً خبيثة بدرجة خطورة حرجة. تذكر النشرة أن الإصدارين 4.2.1 و4.3.5 متأثران، ولا تذكر أي إصدار مُصحِّح. ويندرج الضعف تحت CWE-506، أي تعليمات برمجية خبيثة مُضمَّنة.
بحسب النشرة، تتضمن loader-utils-kit ملف lib/contract.js مطابقًا بايتًا ببايت للحمولة الموجودة في pino-testkit، وهو وحدة مموّهة تفكّ ترميز تعليمات برمجية وتنفّذها عند التحميل. وتصف النشرة الحزمة بأنها اسم جديد لحملة pino-testkit القائمة (MAL-2026-16484)، وتقول إن بصمات الملفات تطابق الأدلة الواردة في ذلك السجل. أما سجل OpenSSF للحزم الخبيثة الخاص بالاسم الجديد، MAL-2026-18689، فمؤرخ في 2026-10-26 ويذكر مؤشرًا واحدًا: الملف lib/contract.js ببصمة SHA-256 هي c6a9028513792f288fec1d7c217c55d9541d96d436cb119ef0553c3fd49d6c41. ولا يذكر أي نطاقات أو عناوين IP أو روابط.
تقدّم الحزمة نفسها على أنها أداة مساعدة عادية، وتقول النشرة إن التعليمات البرمجية تُنفَّذ عند الاستيراد أو التثبيت دون علم المستخدم.
السجل السابق، المنشور في 2026-09-23، يغطي pino-testkit@10.4.5. انتحلت تلك الحزمة صفة مُسجِّل pino بنسخ وصفه واسم مؤلفه وملف README الخاص به. ويقول التحليل الوارد في ذلك السجل إن lib/contract.js يعيد بناء المُنشئ Function من سلاسل نصية مموّهة، ويضع require وmodule على الكائن العام، ثم يبني دالة ثانية مفكوكة الترميز وينفّذها. وبالتالي يمكن للتعليمات البرمجية المبنية ديناميكيًا تحميل أي وحدات إضافية.
لماذا يهم
هذا ليس خللًا ينتظر نافذة تصحيح، بل حزمة غرضها تنفيذ تعليمات برمجية يتحكم بها المهاجم على أي جهاز يحمّلها. ويصف تحليل pino-testkit هذا النمط بأنه تنفيذ تعليمات برمجية عشوائية لصالح الناشر على أي مستهلك يستدعي الحزمة أو يستخدمها. وتنفيذ تعليمات برمجية عشوائية على حاسوب مطوّر أو مُشغّل CI يضع في متناول المهاجم كل ما يحويه ذلك المضيف، مثل رموز npm وبيانات اعتماد السحابة ومفاتيح SSH والشيفرة المصدرية.
الجديد هنا هو إعادة التسمية. فالفرق التي استجابت لـ pino-testkit بحظر ذلك الاسم وحده ليست محمية من loader-utils-kit. كما يتخلى الاسم الجديد عن انتحال صفة المُسجِّل لصالح اسم أداة مساعدة عام، وهو أقل لفتًا للانتباه في مراجعة الشيفرة أو في فروقات الاعتماديات. والثابت بين الاسمين هو بصمة الملف، وهي إشارة الكشف الأكثر ديمومة.
تُظهر النشرة المهيكلة درجة CVSS تساوي 0 إلى جانب خطورة حرجة ونوع برمجية خبيثة؛ فلا تدع مُرشِّح فرز قائمًا على الدرجة يؤخر معالجتها في قائمة الأولويات.
التقييم الهندسي
تقييمنا: لكل من ثبّت أيًّا من الحزمتين أو استوردها فعلًا، هذا حادث اختراق كامل وليس ترقية اعتمادية. وهذا ما تقوله إرشادات السجل نفسه في سجل pino-testkit، والحمولة المطابقة بايتًا ببايت تجعل من المعقول تطبيق الموقف نفسه على loader-utils-kit. لا تذكر الأدلة مدى انتشار تثبيت أي من الحزمتين، لذا يجب إثبات درجة التعرض بالفحص لا بالافتراض.
ثلاث نقاط يتركها الإعلان ضمنية:
- الضوابط القائمة على الأسماء فشلت مرة بالفعل. الحملة التي غيّرت اسمها مرة قد تغيّره مجددًا. والبحث ببصمة
lib/contract.jsعبرnode_modulesوذاكرات البناء المؤقتة وصور الحاويات أمتن من إضافة اسم آخر إلى قائمة الحظر. وحتى مطابقة البصمة لا تلتقط إلا النسخ المطابقة بايتًا ببايت؛ فحمولة معدّلة تعديلًا طفيفًا ستتجاوزها. - الخيار
--ignore-scriptsليس دفاعًا كافيًا هنا. يُظهر تحليل pino-testkit أن الحمولة تُستدعى عبرrequire()عند التحميل أو الاستدعاء، لا عبر خطاف التثبيت فقط. تعطيل سكربتات دورة الحياة يقلل جزءًا من الخطر، لكن استيراد الحزمة يظل ينفّذ التعليمات البرمجية. - نافذة التعرض أطول مما يوحي به تاريخ GitHub. سجل OpenSSF مؤرخ في 2026-10-26، أي قبل نشرة GitHub بعشرة أيام. والأدوات التي تعتمد على GitHub Advisory Database وحدها ربما لم تُنبّه إلى الحزمة قبل 2026-11-05. ارجع في فحص عمليات التثبيت إلى أواخر أكتوبر على الأقل.
ما لا تدعمه الأدلة: لا يوجد وصف منشور للمرحلة الثانية في loader-utils-kit، ولا مؤشرات شبكية. لا يستطيع المكتب تحديد ما سُرّب أو نُزّل، لذا يجب أن يفترض نطاق الاستجابة للحادث أسوأ الاحتمالات لأي سرّ كان متاحًا من المضيف المتأثر.
هل يعنيك هذا؟
- أي ملف
package-lock.jsonأوnpm-shrinkwrap.jsonأوyarn.lockأوpnpm-lock.yamlفي مستودعاتك يشير إلىloader-utils-kit(4.2.1 أو 4.3.5) أو إلىpino-testkit(أي إصدار، بما في ذلك 10.4.5). - أي مجلد
node_modulesأو ذاكرة بناء مؤقتة أو صورة حاوية تحتوي علىlib/contract.jsببصمة SHA-256 هيc6a9028513792f288fec1d7c217c55d9541d96d436cb119ef0553c3fd49d6c41. - أضاف مطوّر إحدى الحزمتين مباشرة، مثلًا أثناء البحث عن أداة مساعدة للاختبار مع pino أو أداة تحميل عامة.
- ثبّتت مُشغّلات CI أو وكلاء البناء أو عمليات بناء Docker الاعتماديات من فرع تضمّن إحدى الحزمتين، بما في ذلك فروع الميزات التي لم تُدمج قط.
إذا لم ينطبق أي مما سبق، فأنت غير معرّض لهذين الاسمين بناءً على الأدلة الحالية.
ما الذي ينبغي فعله
- أجرِ الجرد الآن، عبر كل مستودع وكل صورة. فحوص مفيدة للقراءة فقط:
npm ls loader-utils-kit pino-testkit --allفي كل مشروع.grep -rE "loader-utils-kit|pino-testkit" --include=package-lock.json --include=yarn.lock --include=pnpm-lock.yaml .عبر المستودعات المسحوبة محليًا.find / -path '*/node_modules/*/lib/contract.js' -exec sha256sum {} + 2>/dev/null | grep c6a9028513792f288fec1d7c217c55d9541d96d436cb119ef0553c3fd49d6c41على أجهزة المطوّرين والمُشغّلات والصور المفكوكة.
- إذا وجدت إحدى الحزمتين مثبّتة أو محمّلة، فاتّبع إرشادات السجل المنشورة في سجل pino-testkit، التي يعدّها المكتب قابلة للتطبيق لأن الحمولة مطابقة: اعتبر الجهاز مخترقًا بالكامل؛ جدّد كل الأسرار والمفاتيح المخزّنة عليه، على أن يتم التجديد من جهاز آخر؛ أزل الحزمة مع العلم أن الإزالة وحدها لا تضمن زوال أي برمجيات خبيثة أخرى. ويُفضّل إعادة بناء المضيف أو المُشغّل من صورة معروفة السلامة.
- جدّد أسرار CI (رموز النشر على npm، مفاتيح السحابة، مفاتيح النشر، مفاتيح التوقيع) لأي خط تكامل مستمر نفّذ تثبيتًا تضمّن إحدى الحزمتين، وراجع عمليات النشر والإصدارات الأخيرة التي تمت باستخدام بيانات الاعتماد تلك.
- احظر الاسمين والبصمة في وكيل السجل أو سياسة الاعتماديات أو أداة تحليل مكونات البرمجيات لديك. ليست توصية من الجهة المورِّدة.
- تأكد من أن الفحص لديك يستخدم تغذية الحزم الخبيثة من OpenSSF/OSV إلى جانب GitHub Advisory Database، نظرًا لفارق الأيام العشرة بين السجلين لهذه الحزمة. ليست توصية من الجهة المورِّدة.
- للقادة التقنيين: اشترطوا المراجعة لأي اعتمادية جديدة تظهر في فروقات ملف القفل، واحفظوا ملفات القفل في المستودع وثبّتوا باستخدام
npm ci، وأبقوا بيانات الاعتماد طويلة الأمد بعيدًا عن أجهزة المطوّرين ووكلاء البناء قدر الإمكان. ليست توصية من الجهة المورِّدة.
لا يوجد إصدار للترقية إليه. لا تنتظر صدوره.
ما لا نعرفه بعد
- ما الذي تفعله تعليمات المرحلة الثانية في
loader-utils-kit. لا يذكر السجل أي نطاقات أو عناوين IP أو روابط، لذا فسلوك التسريب أو التنزيل غير مذكور. - ما إذا كانت أسماء حزم أخرى تحمل بصمة
lib/contract.jsنفسها. - ما إذا كانت npm قد أزالت الإصدارين 4.2.1 و4.3.5 من
loader-utils-kit، وكم عدد عمليات التثبيت التي جرت، بما في ذلك بين 2026-10-26 و2026-11-05. - ما إذا كانت إرشادات الاختراق والتجديد الواردة في سجل pino-testkit مقصودًا تطبيقها دون تغيير؛ فنشرة
loader-utils-kitنفسها لا تتضمن أي نص للمعالجة. - لماذا يختلف الطرف المنسوب إليه الاكتشاف بين السجلين (OpenSSF في نشرة GitHub، وCyberXYZ في ملف JSON الخاص بـ OpenSSF).
سيتابع المكتب سجلات OSV وGitHub بحثًا عن أسماء أو مؤشرات إضافية أو تحليل للمرحلة الثانية، وسيحدّث هذه القصة في أخبار المكتب الهندسي.
المصادر
أحدث التحليلات الهندسية
قراءة 2 دقيقة
solidity-map على npm: حمولة البرمجية الخبيثة نفسها تحت اسم حزمة ثالث
تصنّف قاعدة بيانات النشرات الأمنية في GitHub الحزمة solidity-map 2.21.0 برمجيةً خبيثة تعيد استخدام حمولة hardhat-roof وchai-foundry بايتًا ببايت. لذلك ستظل قوائم الحظر القائمة على الأسماء عاجزة عن رصد الاسم الجديد التالي.
الممارسة الهندسيةقراءة 1 دقيقة
Laravel 13.40.0: تغييرات في المعاملات والنسخ المتماثلة وRedis ينبغي اختبارها أولًا
إصدار فرعي يغيّر سلوك تطبيقات Laravel كثيفة الاعتماد على قواعد البيانات عند الأعطال، إضافةً إلى إصلاح ذي طابع أمني في Concurrency صدر دون أي نشرة أمنية.
قراءة 2 دقيقة
مكتبات SD-JWT لـ JavaScript تُسقط الإفصاحات المُعدَّلة بصمت وتُبلغ بالنجاح (CVE-2026-62374)
فجوة في المطابقة للمواصفة من جهة المُتحقِّق في مكتبات SD-JWT لـ JavaScript التابعة لـ OpenWallet Foundation تتيح لحامل بيانات الاعتماد حذف مطالبة (claim) بصمت، ولا يمنع ربط المفتاح ذلك.