تأثير مرتفعالأمنلا يوجد تصحيح بعد

solidity-map على npm: حمولة البرمجية الخبيثة نفسها تحت اسم حزمة ثالث

تصنّف قاعدة بيانات النشرات الأمنية في GitHub الحزمة solidity-map 2.21.0 برمجيةً خبيثة تعيد استخدام حمولة hardhat-roof وchai-foundry بايتًا ببايت. لذلك ستظل قوائم الحظر القائمة على الأسماء عاجزة عن رصد الاسم الجديد التالي.

مكتب خالد أبوبكر الهندسينُشر

تحليل هندسي آلي من مكتب خالد أبوبكر الهندسي، مبني على المصادر الأولية المذكورة أدناه. لم يراجعه شخص قبل النشر. عن المكتب

الخلاصة

الحزمة solidity-map 2.21.0 على npm برمجية خبيثة (GHSA-95qc-c4xp-j95w). لا يوجد إصدار مُصحِّح، والعلاج الوحيد هو الإزالة. وهي تعيد استخدام حمولة hardhat-roof وchai-foundry بايتًا ببايت. ابحث في ملفات القفل وفي node_modules عن الأسماء الثلاثة وعن بصمات ملفات الحمولة، واعتبر أي جهاز ثبّت الحزمة أو استوردها جهازًا مخترقًا.

ماذا حدث

تدرج قاعدة بيانات النشرات الأمنية في GitHub الحزمة solidity-map على npm بوصفها تعليمات برمجية خبيثة تحت المعرّف GHSA-95qc-c4xp-j95w. الإصدار المتأثر هو 2.21.0 وحده، ولا يُذكر أي إصدار مُصحِّح. وتنص GitHub على أن الحزمة برمجية خبيثة، ولذلك لا توجد لها إصدارات مُصحِّحة.

تصف النشرة solidity-map بأنها اسم جديد لحملة قائمة، وتستشهد بسجلين سابقين لبرمجيات خبيثة: hardhat-roof (MAL-2026-17509) وchai-foundry (MAL-2026-13356). والملفان index.js وlib/config.js في الحزمة مطابقان بايتًا ببايت لحمولتي هاتين الحزمتين. وتذكر النشرة أن بصمات الملفات الواردة في سجل OSV الخاص بـ solidity-map تطابق الأدلة الواردة في سجل hardhat-roof.

وتقول النشرة إن الحزمة تقدّم نفسها أداةً مساعدة عادية، وإن تعليماتها البرمجية تُنفَّذ عند الاستيراد أو التثبيت دون علم المستخدم.

وكان تحليل Amazon Inspector السابق لـ hardhat-roof قد وجد أن الحزمة نسخت ملفات التوثيق والترخيص الخاصة بأداة التسجيل pino للتمويه. ففي تلك الحزمة يستدعي index.js التعليمة require('./lib/config') في أعلى الملف، فيُحمَّل الملف lib/config.js، وهو ملف حجمه 4,373,384 بايت ومُعمّى بأسلوب مصفوفة السلاسل النصية المعروف في obfuscator.io. ومن ثمّ فإن أي import أو require للحزمة يشغّل التعليمات المُعمّاة لحظة التحميل.

لماذا يهم

لا تصف هذه النشرة خللًا في اعتمادية مشروعة يمكن الترقية منها إلى إصدار أحدث، بل تصف تعليمات برمجية عدائية. فإذا ثبّت مشروعٌ ما solidity-map أو استوردها، فالسؤال ليس هل نطبّق تصحيحًا، بل ماذا فعلت تلك التعليمات على الجهاز الذي شغّلها. والأدلة لا تجيب عن ذلك.

الإشارة الأكثر فائدة هي النمط. فقد نُشرت حمولة واحدة، ببصمات الملفات نفسها، تحت ثلاثة أسماء على الأقل حتى الآن؛ وتحمل solidity-map وhardhat-roof كلتاهما الإصدار 2.21.0 (أما إصدار chai-foundry فلا يرد في الأدلة):

  • hardhat-roof
  • chai-foundry
  • solidity-map

تشير الأسماء إلى أدوات مطوري Ethereum وSolidity، وإن كانت الأدلة لا تحدد الجهات المستهدفة. والفرق التي تقوم دفاعاتها على قوائم بأسماء الحزم الضارة المعروفة تبقى دائمًا متأخرة بخطوة عن كل تغيير في الاسم.

وينبغي وضع ما لم يثبت في حجمه الطبيعي. فالأدلة لا تقدّم أعداد تنزيلات، ولا حزمًا معتمدة عليها، ولا ضحايا مؤكدين، ولا مؤشرات اختراق: قوائم النطاقات وعناوين IP وعناوين URL في السجل فارغة. وهذا لا يسوّغ الحديث عن اختراق واسع النطاق، لكنه يسوّغ فحصًا قصيرًا وموجّهًا، لا سيما للفرق التي تبني أدوات العقود الذكية.

التقييم الهندسي

تقييمنا: بالنسبة إلى أي فريق سحب هذه الحزمة، فإن درجة التعرض خطيرة، لأن التنفيذ هو السلوك الافتراضي. يُظهر تحليل hardhat-roof استدعاء require في المستوى الأعلى يقود إلى كتلة مُعمّاة بحجم عدة ميغابايت. لا حاجة إلى أي إعداد غير مألوف: مجرد استيراد الحزمة يكفي. أما هل تُنفَّذ تعليمات برمجية وقت التثبيت أيضًا عبر سكربتات دورة الحياة، فأمر غير ثابت. تقول النشرة «عند الاستيراد أو التثبيت»، لكن التحليل الداعم لا يصف إلا مسار التنفيذ وقت التحميل. ولذلك قد لا تحمي الإعدادات التي تعطّل سكربتات التثبيت مشروعًا يستورد الحزمة فعلًا.

أما بالنسبة إلى الآخرين، فالخطر الواقعي منخفض، لكن الدرس ملموس. فإعادة الاستخدام المطابقة بايتًا ببايت تجعل الكشف القائم على المحتوى رخيص الكلفة ومستدامًا. إذ تظهر بصمة SHA-256 للملف lib/config.js (7e4c6d76f1d845f752e37876a2d3f773996719f33c2d1c282e0a84b04444efeb) في سجلي hardhat-roof وsolidity-map كليهما. وثمة أيضًا مؤشر بنيوي يصمد عبر تغييرات الأسماء والمتغيرات المعدّلة تعديلًا طفيفًا: حزمة شبيهة بـ pino تحتوي ملف lib/config.js متضخمًا ومبهمًا لا تتضمنه pino الحقيقية. قائمة حظر من ثلاثة أسماء لا تلتقط أي جديد، أما فحص البصمة والحجم على محتويات الاعتماديات فيلتقط الاسم الجديد التالي ما دامت الحمولة دون تغيير.

التحفظ هنا أن مطابقة البصمات تفشل بمجرد أن يغيّر المهاجم بايتًا واحدًا. تعامل مع البصمات بوصفها جرس إنذار سريعًا، لا ضابطًا أمنيًا. وتظل الضوابط المستدامة هي مراجعة الاعتماديات عند إضافة أي جديد منها، ومراجعة فروقات ملفات القفل ضمن مراجعة الشيفرة، واستخدام قائمة سماح أو سجل وسيط (proxy registry) لأنظمة البناء التي تصل إلى بيانات اعتماد بيئة الإنتاج.

وبعد هذه النشرة تزداد قوة الحجة لمراجعة الاعتماديات المباشرة الجديدة بحسب محتواها ومصدرها، لا بحسب اسمها وملف README الخاص بها، لأن ملف README في hardhat-roof كان منسوخًا من pino، ونشرة solidity-map تصف النسخ نفسه من pino.

هل يعنيك هذا؟

  • أي ملف قفل (package-lock.json أو yarn.lock أو pnpm-lock.yaml) يشير إلى solidity-map أو hardhat-roof أو chai-foundry، على أي مستوى من العمق.
  • شجرة node_modules على حاسوب مطوّر أو مشغّل CI أو صورة حاوية تحتوي solidity-map أو hardhat-roof (الإصدار 2.21.0 في السجلات)، أو chai-foundry بأي إصدار.
  • أي ملف lib/config.js في أشجار اعتمادياتك بصمته SHA-256 هي 7e4c6d76f1d845f752e37876a2d3f773996719f33c2d1c282e0a84b04444efeb، أو ملف index.js بصمته 4e6c4e61a7019ab0affe9c2d20e36701b330ec357be205930355bac1464f9316.
  • اعتمادية تبدو مثل pino تحتوي ملف lib/config.js يُقاس حجمه بالميغابايت.
  • يعمل فريقك على أدوات Solidity أو Hardhat أو Ethereum ويضيف حزمًا مساعدة صغيرة دون مراجعة. هذا سياق أعلى خطورة، لا دليل على التعرض.

إذا لم ينطبق أي من ذلك، فهذه النشرة لا تعنيك؛ ومع ذلك فإن فحوص البصمة والحجم المذكورة أعلاه ستلتقط أي أسماء جديدة أخرى للحمولة.

ما الذي ينبغي فعله

  1. أجرِ الجرد الآن. شغّل ما يلي على المستودعات وذاكرات CI المؤقتة وصور البناء:

    • npm ls solidity-map hardhat-roof chai-foundry
    • grep -rE 'solidity-map|hardhat-roof|chai-foundry' --include='*lock*' .
  2. اكشف بحسب المحتوى. ابحث عن ملفات الإعداد متضخمة الحجم:

    • find . -path '*node_modules*' -path '*/lib/config.js' -size +1M -exec sha256sum {} +

    قارن المخرجات بالبصمات المذكورة أعلاه.

  3. إن وجدت الحزمة فأزلها، ولا تبحث عن ترقية، إذ لا توجد أي ترقية. أزلها من package.json، وأعد توليد ملف القفل، وامسح ذاكرات CI المؤقتة وأي صور بُنيت أثناء وجود الحزمة.

  4. اعتبر أي مضيف ثبّتها أو استوردها مخترقًا. لا توجد في الأدلة إرشادات معالجة رسمية، لذا فما يلي ليس إرشادًا من المورّد:

    • دوّر الأسرار التي يمكن الوصول إليها من ذلك المضيف أو من خط التكامل المستمر، بما فيها رموز npm ومفاتيح السحابة ومفاتيح SSH ومفاتيح المحافظ أو مفاتيح النشر.
    • أعد بناء المضيف بدلًا من تنظيفه.
    • راجع سجلات حركة الشبكة الصادرة خلال الفترة التي كانت الحزمة موجودة فيها.
  5. أضف إلى CI فحوصًا قائمة على الحمولة. ضمن قواعد فحص الاعتماديات، علّم بصمات الحمولة المعروفة والملفات المُعمّاة الكبيرة على نحو غير معتاد في الاعتماديات الجديدة. ليس إرشادًا من المورّد.

  6. للقادة التقنيين: اشترط مراجعة كل اعتمادية مباشرة جديدة، وفكّر في وسيط سجل داخلي مع قائمة سماح لخطوط التكامل المستمر التي تحمل بيانات اعتماد الإنتاج أو التوقيع. ليس إرشادًا من المورّد.

للمزيد من التغطية حول سلسلة التوريد، راجع صفحة أخبار مكتب الهندسة.

ما لا نعرفه بعد

  • ما الذي تفعله أداة الإسقاط (dropper) بعد تحميلها. تنزيل مرحلة ثانية، وسرقة بيانات الاعتماد أو المحافظ، والبقاء الدائم على النظام كلها احتمالات واردة، لكن النشرة لا تقدّم أي وصف للسلوك ولا أي مؤشرات شبكية.
  • هل تُنفَّذ تعليمات برمجية وقت التثبيت عبر سكربتات دورة الحياة، أم عند الاستيراد فقط.
  • هل أُزيلت الحزمة من سجل npm، وكم بلغ عدد تنزيلاتها أو الحزم المعتمدة عليها.
  • كم من الوقت ظلت متاحة للتثبيت قبل صدور النشرة. سجل OSV مؤرخ في 2026-10-26، ونُشرت نشرة GitHub في 2026-11-05.
  • هل الإصدار المتأثر من chai-foundry هو 2.21.0 أيضًا، وما الأسماء الأخرى التي استخدمتها الحملة. لم يكن سجل chai-foundry ضمن الأدلة.
  • هل تأثر أي مشروع حقيقي أو وقع أي ضحية فعلية. الأدلة لا تذكر شيئًا عن أي منهما.

سيتابع المكتب صدور أي تحليل سلوكي للحمولة، وحالة إزالة الحزمة من السجل، وأي أسماء جديدة تحمل البصمات نفسها.

المصادر

أحدث التحليلات الهندسية

قراءة 2 دقيقة

loader-utils-kit: أداة الإسقاط الخبيثة pino-testkit على npm تعود باسم جديد

أُعيد نشر أداة الإسقاط المموّهة lib/contract.js، التي ظهرت أولًا في pino-testkit، تحت اسم loader-utils-kit. لذلك لا تلتقطها قوائم الحظر القائمة على الأسماء، وينبغي للفرق البحث ببصمة الملف (hash) إلى جانب الاسم.

قراءة 2 دقيقة

مكتبات SD-JWT لـ JavaScript تُسقط الإفصاحات المُعدَّلة بصمت وتُبلغ بالنجاح (CVE-2026-62374)

فجوة في المطابقة للمواصفة من جهة المُتحقِّق في مكتبات SD-JWT لـ JavaScript التابعة لـ OpenWallet Foundation تتيح لحامل بيانات الاعتماد حذف مطالبة (claim) بصمت، ولا يمنع ربط المفتاح ذلك.