npm تضيف صلاحية dist-tag إلى الـ trusted publishing فيمكن الاستغناء عن آخر token طويل العمر
أنظف pipeline للنشر على npm كان يحتفظ بمفتاح واحد طويل العمر لمهمة صغيرة، وهذا المفتاح تحديدًا هو الطريق الذي سلكته معظم هجمات npm هذا العام.
وسم
أنظف pipeline للنشر على npm كان يحتفظ بمفتاح واحد طويل العمر لمهمة صغيرة، وهذا المفتاح تحديدًا هو الطريق الذي سلكته معظم هجمات npm هذا العام.
الحماية حصرت الأسماء التي يستطيع الكود الوصول إليها، لكن المدخل الذي لم يُتوقع لا يحتاج إلى أسماء. السؤال في أي بيئة معزولة هو ما يقبله المحمّل، لا ما أُغلق.
إذا كانت التزامات المصادر المفتوحة اجتماعية لا قانونية، فإن مشاركة المستخدمين في النقاش حولها هي ما يمنحهم حق المطالبة، لا مجرد الاعتماد على كود مجاني.
النطاق الوهمي في المثال لم يعد مثالًا ميتًا؛ الـ agents تقرأ التوثيق وتنفّذه، فصار الرابط المنسي مدخلًا حقيقيًا.
حين يبقى الكود الخبيث مشفرًا ولا يُفك إلا بمدخل معيّن، تفقد مراجعة كود الحزمة قيمتها كوسيلة فحص، ويصبح الاسم الخاطئ بحرف واحد هو الثغرة الحقيقية.
token مسرّب من خط الـ CI كان كافيًا لنشر نسخة خبيثة باسم صاحب الحزمة. الخيار الجديد يضع إنسانًا بخاصية 2FA بين التسريب والنشر.
الهدف ليس سرقة حساب شخص واحد، بل نشر برمجية خبيثة باسم مطوّر موثوق، فتصل تلقائيًا إلى كل من يعتمد على مكتبته في التحديث التالي.
توكن بصلاحية قراءة فقط يُعامل عادة على أنه غير خطر، لكن الكود المصدري نفسه قد يكون الخريطة التي تشرح لمن يقرؤه كيف يدخل.
الهجوم لم يستهدف من يثبّت الحزم بل الـ registry نفسه، وكل خطوة في الـ pipeline تقرأ ملفًا من حزمة مرفوعة وتنفذه هي مساحة هجوم كاملة.
قررت npm أن تأخير الناشر الشرعي ثلاثة أيام أرخص من انتشار حزمة مسمومة لساعة واحدة، وصار لترتيب خطوات أي maintainer قبل الإصدار ثمن.
الملفات والتوقيعات قد تكون سليمة تمامًا، ومع ذلك يصل المستخدمَ كودٌ خبيث، لأن الطبقة التي تقرر أي خادم يردّ هي التي سقطت.
النشر على مرحلتين يضع بابًا بين اختطاف الـ workflow ووصول الحزمة إلى المستخدمين، ومن يستهلك الحزم فقط يستفيد دون أن يفعل شيئًا.
مفتاح النشر في أنظمة CI كان يفتح الحساب كله، فتسريبه كان يعني فقدان السيطرة على الحساب قبل نشر أي نسخة ملوثة.
القبض على المتهمين لا ينهي الخطر، لأن كود الدودة نُشر قبل ذلك على منتديات الجريمة. والـ token واسع الصلاحيات في أنظمة CI يبقى الهدف نفسه.
الفحص كان موجودًا وصحيحًا، لكن ترتيبه بعد فك الأرشيف كان يترك محتوى مرفوضًا على القرص، وكثير من مشاكل سلسلة التوريد تأتي من ترتيب الخطوات لا من كسر التشفير.
الاسم الذي يظهر على الشاشة قد لا يكون الاسم الذي يتعامل معه الجهاز، وكل قرار ثقة مبني على اسم مكتوب يحتاج إلى تنظيف ذلك الاسم قبل عرضه.
شهادات المورد والمناقصة الحكومية لم تكشف الموديول المخفي؛ فالسؤال الحاسم عن أي جهاز متصل ليس الشهادة التي يحملها، بل مع من يتواصل وعبر أي طريق.
كل حزمة تختفي من المشروع تعني سلسلة توريد أقصر وحساب مشرف أقل يمكن اختراقه، لكن الاعتماد لا يختفي، بل ينتقل من npm إلى الـ runtime نفسه.
مقارنة إصدارات الإضافات بالمستودع الرسمي لم تكن لتكشف شيئًا هنا، فسطح الهجوم لا يقتصر على التحديث الذي يُقبل بل يشمل كل بيانات تجلبها الإضافة وهي تعمل.
ملفات إعدادات المحررات وأدوات الذكاء الاصطناعي صارت سطحًا يُنفَّذ منه الكود، بينما تتعامل معها أدوات الفحص كأنها إعدادات لا تستحق القراءة.
الترقيع الأول أغلق الطريق الذي سلكه المكتشف لا السبب الذي جعله ممكنًا، وحين تُخترق أداة إدارة الأجهزة لدى مزود الخدمة تصبح أجهزة عملائه كلها مكشوفة.
توقيع provenance يثبت أين بُنيت الحزمة وكيف، لا أنها آمنة، والخلط بين السؤالين يجعل التوقيع إشارة ثقة لا يستحقها.
إغلاق سطح هجوم لا يلغي الهجوم بل ينقله، والمهاجم انتقل من وقت التثبيت إلى وقت الاستيراد، ومعه تحولت ملفات إعدادات مساعدات البرمجة إلى هدف مفضل.