
هجوم PolinRider تهديد يستهدف سلسلة توريد npm ويستخدم حزماً خبيثة ومُحمّلات JavaScript مخفية لإيصال برمجيات وصول عن بُعد. يشرح هذا الدليل كيف يعمل PolinRider، وكيفية اكتشافه داخل مشاريع npm وسجل Git، وإزالته بأمان، وتحديد بيانات الاعتماد التي يجب تدويرها، وتطبيق الضوابط التي تمنع عودته.
npm audit وحده؛ فقد لا تظهر الشيفرة المحقونة في المستودع ضمن شجرة الاعتماديات.يستخدم باحثو الأمن اسم PolinRider لوصف حملة ينشر فيها المهاجمون حزم npm خبيثة أو يستولون على حزم قائمة، ثم يستخدمون مُحمّلات JavaScript لجلب برمجيات ضارة في مراحل لاحقة. يشرح تحليل Socket عملية واسعة للحزم الخبيثة، بينما يوثق تقرير Sonatype محاولة حزمة مخترقة إيصال برمجية وصول عن بُعد مرتبطة بـ PolinRider.
ولا يقتصر الخطر على اسم حزمة بعينها. فبمجرد وصول الشيفرة الخبيثة إلى محطة عمل أو مستودع، يمكن وضعها داخل ملف تتوقع أدوات المطور تشغيله أصلاً، مثل إعدادات ESLint أو PostCSS أو Vite أو أدوات الاختبار والبناء. عندها يتغير سؤال التحقيق من «أي اعتماد يحتوي على ثغرة؟» إلى «ما الشيفرة التي نُفذت، وأين بقيت، وإلى ماذا استطاعت الوصول؟»
استخدمت العينات التي حققنا فيها ملفات إعداد .mjs عادية كغطاء. ظهر إعداد صحيح صغير في بداية الملف، ثم ظهرت شيفرة مُبهمة بعد مساحة بيضاء كبيرة يصعب ملاحظتها في المراجعة السريعة. أجرت الشيفرة استكشافاً للشبكة، وفكّت حمولة مشفرة، وقيّمتها ديناميكياً، ثم شغّلت عملية Node.js منفصلة.
ينتج عن هذا النمط عدد من مؤشرات التحذير:
child_process أو الشبكة أو تحميل الوحدات الديناميكي دون مبرر.eval أو Function أو حلقات XOR أو مصفوفات بايت مشفرة أو تشغيل عمليات منفصلة..env في .gitignore خلال الفترة نفسها.قد يكون لكل مؤشر تفسير سليم منفرداً، لكن اجتماع عدة مؤشرات يتطلب احتواءً فورياً.
ابدأ بفحوصات للقراءة فقط. لا تشغّل المشروع أو تثبّت اعتمادياته أو تنفّذ ملفات إعداد غير مألوفة قبل اكتمال المراجعة الأولية.
تحقق مما إذا كانت ملفات الإعداد القابلة للتنفيذ كبيرة بصورة غير متوقعة:
ابحث في الشيفرة عن سلوكيات نادراً ما تكون مبررة داخل إعدادات lint أو CSS أو البناء:
راجع السجل الكامل للملفات عالية المخاطر بدلاً من الاكتفاء بمحتواها الحالي:
وفي النهاية، احصر جميع الفروع والوسوم، وقارن المراجع البعيدة، وافحص النسخ القديمة وذاكرة CI المؤقتة. تثبت نسخة العمل النظيفة أن الملفات المفتوحة نظيفة فقط؛ لكنها لا تثبت سلامة المستودع أو الجهاز.
وجدنا خلال المراجعة مُحمّلات مدمجة مباشرة داخل ملفي إعداد JavaScript في مستودعين. اختبأ أحدهما في إعداد PostCSS والآخر في إعداد ESLint. وظلت فروع متعددة ووسوم إصدارات تشير إلى الكائنات الخبيثة حتى بعد تصحيح نسخة العمل الظاهرة.
كما وجدنا أكثر من جيل واحد للمُحمّل في السجل. وهذا مهم لأن تنظيف العينة الأحدث فقط كان سيُبقي إصداراً أقدم قابلاً للوصول. ولم تتضمن ملفات تعريف الاعتماديات وملفات القفل أسماء حزم PolinRider المعروفة التي فحصناها، وهو ما يؤكد أن تقرير ثغرات الحزم المعتاد لا يستطيع وصف الحادث بالكامل.
npm audit اكتشاف PolinRider؟يقارن npm audit شجرة الاعتماديات المثبتة بإرشادات الثغرات المعروفة. وهي أداة مفيدة، لكنها تجيب عن سؤال أضيق من السؤال الذي يحتاجه فريق الاستجابة للحوادث.
| الفحص الأمني | ما يستطيع اكتشافه | ما قد يفوته |
| ---------------------------------- | ---------------------------------------- | ----------------------------------------------- |
| npm audit | ثغرات معروفة في الحزم المثبتة | شيفرة خبيثة أضيفت مباشرة إلى المستودع |
| مراجعة ملف القفل | الاعتماديات والمصادر الجديدة أو المتغيرة | حمولات مخفية داخل ملفات إعداد يملكها المشروع |
| فحص الحزم المخصص للبرمجيات الخبيثة | حزم خبيثة معروفة وسلوك تثبيت مشبوه | كائنات Git التاريخية والأجهزة المخترقة سابقاً |
| فحص الشيفرة والسجل | الإبهام والمُحمّلات والبقاء عبر المراجع | الأسرار التي نُسخت أو الأوامر التي نُفذت بالفعل |
| مراقبة الأجهزة والشبكة | سلوك العمليات والاتصالات الصادرة | شيفرة خاملة لم تُشغّل بعد |
يجمع التقييم السليم بين هذه الزوايا الخمس.
1. الاحتواء قبل التعديل. أوقفنا تشغيل المشاريع المتأثرة وتعاملنا مع بيئات المطورين والأتمتة باعتبارها ربما تعرضت للخطر. حفظ نسخة من الأدلة قبل التنظيف مهم لفهم النطاق ودعم التحقيق اللاحق.
2. تحديد خط أساس موثوق. قارنا سجل الملفات وأحجامها وبصماتها والالتزامات لتحديد آخر إصدار سليم. وفحصنا قاعدة كائنات Git كاملة بدلاً من الثقة بالنسخة المفتوحة فقط.
3. استعادة الملفات النشطة. استبدلنا الإعداد المحقون بأقل إعداد صحيح، وأعدنا الضوابط التي تمنع دخول ملفات البيئة المحلية إلى Git.
4. فحص كل مرجع. فحصنا الفروع المحلية والبعيدة والوسوم وسجلات reflog والكائنات غير القابلة للوصول بحثاً عن نسختي المُحمّل المعروفتين وعن المؤشرات السلوكية. وكشف ذلك وسوم إصدارات متأثرة كان فحص الفرع الرئيسي وحده سيفوّتها.
5. إعادة كتابة السجل المتأثر. أعدنا بناء كل فرع ووسم متأثر انطلاقاً من الأصل الموثوق، مع الحفاظ على العمل الصحيح اللاحق واستبعاد التغييرات المحقونة. ثم أنهينا صلاحية المراجع القديمة وحذفنا الكائنات الخبيثة محلياً.
6. تحديث المستودع البعيد بأمان. لأن الالتزامات المعاد بناؤها تحمل معرفات جديدة، احتاجت المراجع المتأثرة إلى تحديثات قسرية منسقة. استخدمنا عمليات دفع محمية بـ --force-with-lease وتحققنا من المراجع البعيدة الناتجة بدلاً من استخدام دفع قسري غير مقيد.
7. تدوير بيانات الاعتماد. لا يستطيع تنظيف المصدر التراجع عن سرقة بيانات الاعتماد. ألغينا واستبدلنا الأسرار التي كانت متاحة لجلسات المطورين أو المشغلات المتأثرة، ومنها رموز التحكم بالمصدر وبيانات السحابة ومفاتيح النشر ورموز npm وأسرار التطبيقات ومفاتيح SSH ذات الصلة. كما راجعنا سجلات المصادقة والتدقيق بحثاً عن نشاط غير متوقع.
8. إعادة بناء بيئات التنفيذ. يمكن لحمولة منفصلة أن تستمر بعد حذف الملف الذي أطلقها. أعدنا بناء محطات العمل ومشغلات CI المتأثرة من صور موثوقة، ومسحنا الذاكرة المؤقتة، وثبتنا الاعتماديات من ملف قفل تمت مراجعته، ثم أعدنا فحص النتيجة النظيفة.
| الإجراء | الفرع الحالي | الفروع والوسوم الأخرى | بيانات الاعتماد والأجهزة | استجابة كافية | | ---------------------------------------- | -----------: | --------------------: | -----------------------: | ------------- | | حذف الأسطر المشبوهة | نظيف | ما زالت مكشوفة | لم تُعالج | لا | | عكس الالتزام الخبيث | نظيف | قد تبقى مكشوفة | لم تُعالج | لا | | إعادة كتابة جميع مراجع Git المتأثرة | نظيف | نظيفة بعد التحقق | لم تُعالج | غير مكتملة | | إعادة الكتابة والتدوير والبناء والمراقبة | نظيف | نظيفة بعد التحقق | تمت معالجتها | نعم |
لا توجد أداة واحدة تمنع جميع هجمات سلسلة التوريد. الدفاع الأقوى هو مجموعة ضوابط صغيرة تجعل إدخال التغييرات المشبوهة صعباً واكتشافها سريعاً.
CODEOWNERS للملفات عالية المخاطر وامنع الدفع المباشر إلى الفروع المحمية.قبل إعلان اكتمال الاستعادة، تأكد من الآتي:
.env جديدة.يذكّرنا PolinRider بأن حادث اعتماد برمجي يمكن أن يتحول في خطوة واحدة إلى حادث يمس المستودع والهوية والأجهزة والبنية التحتية. الشيفرة الخبيثة الظاهرة دليل على وجود فرصة للتنفيذ، وليست الحد الكامل للاختراق.
لذلك تتجاوز الاستجابة الموثوقة إزالة الحزمة: احتواء الحادث، وحفظ الأدلة، واستعادة الشيفرة الموثوقة، وتنظيف كل مراجع Git، وتدوير بيانات الاعتماد، وإعادة بناء البيئات المتأثرة، والتحقق من نسخة جديدة. هذا هو الفرق بين إخفاء التحذير واستعادة الثقة فعلياً في سلسلة تسليم البرمجيات.