📚 محتوى دفاعي بحت للمطوّرين.
المشكلة: أنت تثق بكود لم تكتبه
مشروع حديث متوسّط الحجم يعتمد عادة على مئات الحزم غير المباشرة (اعتماديات اعتمادياتك). كل واحدة منها كود ينفَّذ بصلاحيات مشروعك الكاملة وقت التثبيت أو التشغيل — سلسلة التوريد البرمجية هي كل هذه الحلقات، وأي حلقة ضعيفة فيها تعرّض المشروع كاملًا.
مثال معروف كأثر واسع: اختراق SolarWinds (2020) حيث زُرع كود خبيث داخل عملية بناء (build) موثوقة، فوصل تلقائيًّا لأكثر من 18 ألف مؤسّسة عبر تحديث "رسمي" بالكامل.
أشهر أنماط الهجوم
1) Typosquatting (تقليد الاسم)
نشر حزمة باسم قريب جدًّا من حزمة شهيرة (خطأ إملائي شائع)، فيثبّتها مطوّر بالغلط بدل الحزمة الحقيقية:
npm install expres ← خطأ إملائي بسيط بدل express
الحزمة المزيّفة قد تحتوي كود سرقة أسرار أو باب خلفي، وتعمل بصلاحيات المشروع كاملة فور تثبيتها.
2) Dependency Confusion (خلط الاعتماديات)
عندما تستخدم مؤسّسة حزمة داخلية خاصة بنفس اسمها في السجلّ العام (npm)، يمكن لمهاجم نشر حزمة عامة بنفس الاسم ورقم إصدار أعلى — فتُفضّلها أنظمة البناء المُعدَّة بشكل خاطئ تلقائيًّا على النسخة الداخلية الآمنة.
3) اختراق حساب الصيانة (Maintainer Account Compromise)
مهاجم يستولي على حساب صاحب حزمة شهيرة موثوقة أصلًا (عبر تسريب كلمة مرور أو هندسة اجتماعية)، وينشر إصدارًا خبيثًا تحت اسم الحزمة الحقيقية نفسها — لا حاجة لخداع أحد بالاسم، الثقة موجودة مسبقًا.
4) دودة ذاتية الانتشار (Self-Propagating Worm)
النمط الأخطر: كود خبيث لا يكتفي بإصابة حزمة واحدة، بل يسرق بيانات اعتماد النشر (publish credentials) من جهاز المطوّر المصاب، ثم يستخدمها تلقائيًّا لنشر نسخة خبيثة من كل حزمة أخرى يملكها ذلك المطوّر — فينتشر من حزمة لحزمة دون أي تدخّل بشري إضافي، بسرعة تفوق أي استجابة يدوية.
مثال واقعي موثّق: هجوم Shai-Hulud على سجلّ npm (موجتان، سبتمبر ثم نوفمبر 2025) — أصاب مئات ثم قرابة 800 حزمة عبر هذا الأسلوب بالضبط، وسرّب بيانات اعتماد سُرقت من أجهزة المطوّرين إلى مستودعات عامة على GitHub. حذّرت منه جهات رسمية مثل CISA الأمريكية لخطورته وسرعة انتشاره.
⚠️ الدرس المستفاد: أي دفاع يعتمد فقط على "ثقة" اسم الناشر أو الحزمة غير كافٍ — دودة كهذه تنشر من حساب ناشر حقيقي وموثوق أصلًا، فالدفاع الفعلي في القيود التقنية (ملفّات القفل، تعطيل سكربتات التثبيت التلقائية، الفحص الآلي) لا في الثقة وحدها.
الدفاع
ملفّات القفل (Lock Files)
package-lock.json / pnpm-lock.yaml / yarn.lock تثبّت رقم الإصدار الدقيق ومصدره لكل اعتمادية، بدل مدى مرن (^1.2.0). دون ملفّ قفل مُلتزَم به بالمستودع، كل تثبيت قد يجلب إصدارًا مختلفًا دون أن تلاحظ.
✅ التزم بملفّ القفل في Git — لا تضفه لـ .gitignore
✅ ثبّت الحزم دائمًا بأمر يحترم القفل (npm ci بدل npm install في CI)
الفحص الآلي للثغرات
npm audit # فحص الاعتماديات مقابل قاعدة ثغرات معروفة
npm audit fix # ترقية تلقائية للإصلاحات المتوافقة
💡 أضِف
npm audit(أو ما يعادله بأداة الحزم لديك) كخطوة إلزامية بخط CI — فشل الفحص يوقف الدمج بدل الاكتشاف بعد النشر.
تقليل السطح المهاجَم
- عطّل تشغيل سكربتات ما بعد التثبيت (
postinstall) تلقائيًّا لحزم غير موثوقة إن أمكن — أشهر طريق لتنفيذ كود خبيث فورnpm install. - راجع الاعتماديات الجديدة قبل إضافتها: تاريخ آخر تحديث، عدد الصيانين، الشعبية الفعلية — لا الاسم فقط.
- استخدم أداة مراجعة اعتماديات ضمن الـ Pull Request (تُظهر أي ثغرة يدخلها تغيير الإصدارات قبل الدمج).
- لأسماء داخلية: احجز النطاق (scope) نفسه بالسجلّ العام، أو اضبط أنظمة البناء لتفضّل المصدر الداخلي دائمًا صراحة — لا تعتمد على "الرقم الأعلى يفوز" الافتراضي.
قائمة تحقّق سريعة
- ملفّ قفل مُلتزَم بالمستودع، وتثبيت بأمر يحترمه في CI.
- فحص ثغرات آلي بكل عملية دمج، لا يدويًّا بين حين وآخر.
- تحقّق من اسم أي حزمة جديدة حرفيًّا قبل تثبيتها — خطأ إملائي واحد كافٍ.
- تحديث الاعتماديات باستمرار بدل تجميد المشروع على إصدارات قديمة تراكمت ثغراتها.
- افترض أن حتى حساب ناشر موثوق قد يُخترق — القيود التقنية (لا الثقة) هي خط الدفاع الأخير.
🎯 التالي: التعامل الآمن مع الأخطاء والاستثناءات.