بدأت تغييرات أمان npm الكبرى في 2025 كرد فعل على سلسلة هجمات استهدفت حسابات المطورين وبيئات CI/CD وبيانات اعتماد النشر، لكنها بحلول 2026 أصبحت أوسع من مجرد حماية npm Token. الاتجاه الحالي هو كسر سلسلة الهجوم في عدة نقاط: منع سرقة بيانات الاعتماد، إضافة تحقق بشري قبل بعض عمليات النشر، تقليل التنفيذ التلقائي أثناء تثبيت الحزم، وإبطاء وصول الإصدارات الجديدة إلى المشاريع حتى تتاح فرصة لاكتشاف الإصدارات الخبيثة.
بمعنى آخر، لم تعد استراتيجية GitHub وnpm تعتمد فقط على اكتشاف الحزمة الخبيثة بعد رفعها. أصبحت الضوابط موزعة على دورة حياة الحزمة من حساب Maintainer وCI/CD إلى عملية npm publish ثم npm install لدى المستهلك.
لماذا أصبحت بيانات اعتماد النشر مشكلة مركزية؟
أحد السيناريوهات المهمة في هجمات Software Supply Chain يبدأ دون وجود ثغرة داخل npm نفسها. يكفي أن يحصل المهاجم على حساب Maintainer أو بيئة CI/CD موثوقة ثم يصل إلى Credential قادرة على نشر إصدار جديد.
يمكن تبسيط السلسلة هكذا:
- اختراق حساب Maintainer أو Workflow داخل CI/CD.
- سرقة npm Token أو Credential أخرى ذات صلاحيات نشر.
- نشر إصدار معدل أو خبيث باسم Package شرعية.
- وصول الإصدار إلى مشاريع تعتمد على الحزمة.
- تنفيذ الكود الخبيث أثناء التثبيت أو عند تشغيل التطبيق، بحسب تصميم الحزمة والهجوم.
خطورة هذا الأسلوب أن المهاجم يستفيد من الثقة الموجودة أصلًا في الحزمة واسمها وسجلها. وتوضح حوادث أخرى في منظومات الحزم الفكرة نفسها؛ فقد أظهرت حالة حزم PyPI الخبيثة التي استخدمت لنشر SilentSync RAT أن Dependency واحدة قد تتحول إلى نقطة دخول إلى جهاز المطور وبيانات الاعتماد الموجودة عليه.
هجمات 2025 دفعت npm إلى تغيير نموذج الأمان
في 22 سبتمبر 2025 نشرت GitHub خطتها لتعزيز أمان سلسلة توريد npm بعد تصاعد عمليات الاستيلاء على حسابات Maintainers وهجمات الحزم الخبيثة.
أشارت GitHub تحديدًا إلى هجوم Shai-Hulud الذي أُبلغت به في 14 سبتمبر 2025. وفق الشركة، استخدم الهجوم حسابات Maintainers مخترقة وأدرج Scripts خبيثة في حزم JavaScript، مع قدرات لسرقة عدة أنواع من Secrets ومحاولة مواصلة الانتشار. وقالت GitHub إنها أزالت أكثر من 500 حزمة متضررة ومنعت رفع حزم جديدة تحتوي على مؤشرات مرتبطة بالبرمجية الخبيثة.
المهم هنا ليس اسم الحملة وحده، بل النتيجة التي وصلت إليها GitHub: اكتشاف Malware وإزالتها بعد النشر لا يكفي إذا ظل المهاجم قادرًا على سرقة Credential موثوقة واستخدامها لنشر إصدار جديد.
ما الذي تغير فعليًا منذ خطة سبتمبر 2025؟
| التغيير | الحالة بحلول أغسطس 2026 | المشكلة التي يعالجها |
|---|---|---|
| npm Classic Tokens | أُلغيت نهائيًا | Credentials طويلة العمر وواسعة الصلاحيات |
| Trusted Publishing عبر OIDC | متاح ومدعوم لعدة منصات CI/CD | إزالة npm Token الدائمة من Pipeline |
| Staged Publishing | متاح بشكل عام | فصل بناء الحزمة عن الموافقة النهائية على نشرها |
| npm v12 Install Security | مفعّل افتراضيًا | تقليل التنفيذ التلقائي للكود أثناء Installation |
| Dependabot Cooldown | ثلاثة أيام افتراضيًا لتحديثات Versions | تقليل سرعة انتشار Release خبيثة جديدة |
| Publish-time Malware Scanning | أُضيف في يوليو 2026 | فحص الحزم قبل إتاحتها للتثبيت |
إلغاء npm Classic Tokens أصبح أمرًا واقعًا
كان إلغاء Classic Tokens أحد أبرز عناصر الخطة الأصلية. وفي 9 ديسمبر 2025 أعلنت GitHub الإلغاء الدائم لجميع npm Classic Tokens، فلم تعد قابلة للاستخدام أو الإنشاء من جديد.
وفي الاستخدام المحلي، أصبح npm login ينشئ Session Token بعمر ساعتين بدل الاعتماد على Credential محلية طويلة العمر لعمليات النشر. كما بقيت Granular Access Tokens للحالات التي تحتاج Tokens، ولكن بنموذج صلاحيات وقيود أكثر دقة.
الفكرة الأمنية بسيطة: إذا كانت Credential المسروقة تعيش لأشهر أو سنوات وتمتلك صلاحيات واسعة، يحصل المهاجم على وقت وقدرة أكبر للاستفادة منها. تقليل العمر والصلاحيات يخفض Blast Radius، لكنه لا يلغي مشكلة سرقة Tokens بالكامل.
Trusted Publishing: إزالة Secret النشر من CI/CD
الحل الأقوى عندما تسمح بيئة النشر بذلك هو Trusted Publishing في npm.
بدل إنشاء npm Token ثابت وتخزينه داخل GitHub Actions Secrets أو إعدادات CI أخرى، تستخدم npm بروتوكول OpenID Connect أو OIDC للتحقق من هوية Workflow المصرح لها بالنشر. تحصل عملية النشر على Credential قصيرة العمر مرتبطة بالسياق الحالي بدل Secret دائم قابل للنسخ وإعادة الاستخدام.
هذا يحقق فائدة مهمة جدًا لهجمات Supply Chain: إذا نفذت برمجية خبيثة داخل Pipeline وحاولت البحث عن npm Token طويلة العمر، قد لا تجد أصلًا Secret من هذا النوع لتسرقها.
بحلول 2026 يدعم Trusted Publishing في npm كلًا من GitHub Actions وGitLab CI/CD وCircleCI. لكن الميزة ليست ضمانًا لسلامة الحزمة نفسها؛ فإذا تمكن المهاجم من السيطرة على Repository أو تعديل Workflow الموثوقة أو تغيير الكود قبل Build، فقد يصبح الـPipeline المصرح لها هي نفسها التي تنشر المحتوى الخبيث.
لذلك Trusted Publishing تعالج بصورة أساسية مشكلة Credential Theft، ولا تحل كل مخاطر Software Supply Chain.
Provenance مفيدة لكنها ليست ختمًا بأن الكود آمن
إحدى فوائد Trusted Publishing في البيئات المدعومة هي إمكانية إنشاء معلومات Provenance تساعد في ربط الحزمة المنشورة بمصدر وعملية Build محددين.
لكن يجب عدم تفسير Provenance على أنها Malware Scanner أو شهادة بأن الكود خالٍ من السلوك الخبيث. هي تساعدك على الإجابة عن أسئلة مثل: من أين جاءت هذه Artifact؟ وما عملية البناء المرتبطة بها؟
إذا كان Source Repository نفسه قد تعرض للاختراق، فمن الممكن أن تكون Artifact خبيثة ومع ذلك تمتلك Provenance صحيحة لمسار البناء الذي أنتجها. ولهذا تظل حماية Repository وBranches وWorkflows والصلاحيات جزءًا أساسيًا من الدفاع.
Staged Publishing أضاف حاجزًا بشريًا قبل Release
في مايو 2026 أصبح Staged Publishing متاحًا بشكل عام في npm.
بدل أن تجعل عملية النشر الآلية الإصدار متاحًا للمستخدمين فورًا، يمكن استخدام npm stage publish لإرسال الحزمة إلى Staging Area. بعد ذلك يراجع Maintainer الحزمة ويوافق عليها باستخدام 2FA قبل أن تصبح متاحة في Registry.
هذا يفصل صلاحيتين كانتا في السابق قد تجتمعان داخل Pipeline واحدة:
- القدرة على بناء الحزمة وإرسالها إلى مرحلة Staging.
- القدرة على جعل الإصدار متاحًا فعليًا للمستخدمين.
الفرق مهم في Incident حقيقي. حتى إذا استولى المهاجم على Credential تستطيع إرسال Build إلى Staging، لا يعني ذلك تلقائيًا قدرته على تجاوز خطوة الموافقة البشرية ونشر الإصدار للعامة.
يمكن أيضًا الجمع بين Trusted Publishing وStaged Publishing: تستخدم CI/CD هوية OIDC دون Secret طويلة العمر لإرسال الحزمة إلى Staging، ثم يحتاج Release النهائي إلى موافقة Maintainer مع 2FA.
npm v12 غيّر ما يحدث أثناء تثبيت Dependencies
في 8 يوليو 2026 أصبحت npm v12 متاحة بشكل عام، وأدخلت تغييرات أمنية افتراضية في npm install.
أهمها أن Lifecycle Scripts الخاصة بالـDependencies لم تعد تُنفذ تلقائيًا كما في السابق. أصبحت Scripts مثل:
preinstallinstallpostinstall
محجوبة ما لم يسمح المشروع بها صراحة. ويشمل ذلك أيضًا عمليات node-gyp الضمنية ذات الصلة.
هذه نقطة مهمة لأن بعض Malware لا تحتاج إلى انتظار تشغيل المستخدم للمكتبة. يمكن أن تحاول تنفيذ الكود بمجرد تثبيت Dependency. تقليل Install-time execution يزيل فرصة مهمة من هذا النوع من الهجمات.
كما جعلت npm v12 Git Dependencies وDependencies القادمة من Remote URLs غير مسموح بها افتراضيًا عبر إعدادات allow-git وallow-remote ما لم يقرر المستخدم السماح بها.
هناك Trade-off واضح: بعض الحزم الشرعية تعتمد فعلًا على Install Scripts أو Native Builds، ولذلك يحتاج المشروع إلى مراجعة ما يحتاجه والسماح به بدل إعادة تشغيل التنفيذ التلقائي لكل Dependency بلا تمييز.
Dependabot لم يعد يسابق كل إصدار جديد فورًا
هناك مشكلة أخرى في Supply Chain لا تتعلق باختراق حسابك مباشرة: السرعة.
إذا نُشر إصدار خبيث من مكتبة شائعة، يمكن لأدوات التحديث الآلي إدخاله إلى عدد كبير من المشاريع قبل أن تتوفر للمجتمع فرصة كافية لتحليل الإصدار أو اكتشاف السلوك الضار.
في 14 يوليو 2026 أضاف GitHub فترة Cooldown افتراضية مدتها ثلاثة أيام لتحديثات Dependabot الخاصة بالإصدارات.
يعني ذلك أن Dependabot ينتظر حتى يكون الإصدار الجديد متاحًا في Registry لثلاثة أيام على الأقل قبل فتح Version Update Pull Request.
لكن هناك تفصيل مهم: Security Updates لا تنتظر هذه الفترة. تستمر تحديثات إصلاح الثغرات الأمنية في الوصول مباشرة حتى لا يتحول الدفاع ضد Supply Chain إلى سبب لتأخير Patch أمني مهم.
npm بدأت فحص الحزم قبل إتاحتها للتثبيت
في 28 يوليو 2026 أضافت npm طبقة أخرى عبر الفحص الآلي للحزم وقت النشر.
الحزمة الجديدة لا تصبح بالضرورة متاحة للتثبيت فور وصول عملية Publish. يتم فحصها أولًا، وبناءً على النتيجة يمكن أن:
- تُنشر بصورة طبيعية.
- تُحتجز لمراجعة إضافية.
- تُحجب إذا اكتُشف محتوى غير مسموح به.
ذكرت GitHub عند إطلاق الميزة أن الفحص يضيف عادة تأخيرًا قصيرًا يقارب خمس دقائق، وقد يستغرق وقتًا أطول في بعض الظروف. هذه نقطة تشغيلية مهمة لمن يملك Automation تفترض أن Package تصبح قابلة للتثبيت فور تنفيذ npm publish.
مع ذلك، لا ينبغي التعامل مع هذه الطبقة باعتبارها كشفًا مضمونًا لكل Malware. GitHub نفسها تصف الأمر بأنه اكتشاف للبرمجيات التي تستطيع أنظمة الفحص رصدها، مع استمرار تطوير التغطية. لذلك تبقى الضوابط السابقة مهمة حتى مع وجود Scanner قبل النشر.
GitHub وسعت أيضًا اكتشاف الحزم الخبيثة لدى المستهلك
لم تقتصر التغييرات على Maintainers. في 2026 أضاف GitHub Malware Alerts إلى Dependabot لحزم npm ثم وسع مصدر البيانات باستخدام OpenSSF malicious-packages ليشمل منظومات حزم إضافية.
هذا مهم لأن Malware Package وVulnerable Package ليستا الشيء نفسه. الحزمة قد تكون خبيثة عمدًا دون وجود CVE تقليدية تصف Vulnerability قابلة للاستغلال. فصل Malware Alerts عن تنبيهات الثغرات يسمح بالتعامل مع النوعين كفئتين أمنيتين مختلفتين.
وتوضح حادثة حزمة Postmark-MCP الخبيثة على npm لماذا لا ينبغي أن يقتصر تقييم Dependency على وجود CVE من عدمه؛ فالخطر قد يكون وظيفة خبيثة أُدرجت عمدًا داخل Package تبدو شرعية.
حماية الحسابات عالية التأثير أصبحت أشد
في يونيو 2026 أضافت npm حماية خاصة للحسابات عالية التأثير المسؤولة عن بعض الحزم واسعة الاستخدام.
عندما يغير أحد هذه الحسابات عنوان البريد الإلكتروني أو يستخدم 2FA Recovery Code، يمكن وضع الحساب في حالة Read-only لمدة 72 ساعة. خلال هذه الفترة تتوقف إجراءات حساسة مثل النشر وتغيير Tokens وبعض إعدادات الحساب.
الهدف هو كسر سيناريو Account Takeover سريع يحاول فيه المهاجم بعد السيطرة على الحساب تغيير البريد، إنشاء Credential جديدة، ثم نشر إصدار خبيث قبل أن يستطيع المالك الأصلي التدخل.
ما وضع Tokens التي تتجاوز 2FA في أغسطس 2026؟
هذه نقطة تحتاج إلى فصل ما حدث بالفعل عما هو مخطط للمستقبل.
اعتبارًا من نهاية يوليو 2026، لم تعد Granular Access Tokens المضبوطة على Bypass 2FA قادرة على تنفيذ مجموعة من العمليات الحساسة الخاصة بإدارة الحساب والحزم والمنظمات دون Interactive 2FA، مثل إدارة Tokens أو Maintainers أو إعدادات Trusted Publishing.
لكنها لم تفقد Direct Publishing بالكامل حتى تاريخ هذا التحديث. أعلنت GitHub أن الخطوة التالية المستهدفة تقريبًا في يناير 2027 هي منع 2FA-bypass Tokens من النشر المباشر أيضًا، بحيث تقتصر في هذا السياق على استخدامات مثل إرسال الحزمة إلى Staging ثم تحتاج عملية إتاحتها النهائية إلى موافقة بشرية.
ولهذا توصي GitHub بالانتقال في Automation إلى Trusted Publishing عبر OIDC أو استخدام Staged Publishing عندما تكون الموافقة البشرية مطلوبة.
لماذا لا تكفي أي ميزة واحدة؟
إذا نظرنا إلى التغييرات منفردة، سنجد أن لكل واحدة حدودًا واضحة:
- 2FA وPasskeys: تحمي الحساب، لكنها لا تمنع كودًا خبيثًا داخل Workflow مخترقة.
- Granular Tokens: تقلل الصلاحيات والعمر، لكن Token قابلة للسرقة ما دامت موجودة.
- Trusted Publishing: تزيل Secret النشر الطويلة من CI/CD، لكنها لا تضمن أن Source Code أوWorkflow نفسها سليمة.
- Staged Publishing: تضيف Approval، لكن فعاليتها تعتمد على مراجعة حقيقية للحزمة لا مجرد الضغط على Approve.
- npm v12: تقلل Install-time execution، لكنها لا تمنع Package خبيثة تعمل عند استدعاء Runtime APIs لاحقًا.
- Malware Scanning: تحاول اكتشاف المحتوى الضار، لكنها لا تستطيع ضمان كشف كل عينة أو سلوك جديد.
- Dependabot Cooldown: يشتري وقتًا لاكتشاف إصدار سيئ، لكنه لا يثبت أن الإصدار أصبح آمنًا بعد مرور ثلاثة أيام.
لهذا تصف GitHub نهجها الحالي عمليًا كدفاع متعدد الطبقات بدل البحث عن Control واحدة توقف Supply Chain Attacks بالكامل.
ما الذي يجب على Maintainer فعله الآن؟
- أزل npm Tokens الدائمة من Publishing Pipeline عندما تستطيع. استخدم Trusted Publishing عبر OIDC في البيئات المدعومة.
- راجع Granular Access Tokens الموجودة. احذف ما لم تعد تحتاج إليه وامنح الباقي أقل صلاحيات ممكنة.
- استخدم طريقة 2FA مقاومة للتصيد. تفضّل npm WebAuthn/Security Keys بدل الاعتماد على طرق يسهل تمرير رموزها عبر Phishing.
- استخدم Staged Publishing عندما تستحق الحزمة Human Approval قبل Release.
- راجع Workflows بصفتها جزءًا من Trusted Computing Base. OIDC لا يفيد إذا كان مهاجم يستطيع تعديل Workflow المصرح لها بحرية.
- طبّق Least Privilege على GitHub Actions. لا تمنح Workflow صلاحيات كتابة أو Secrets لا تحتاجها.
- بعد الانتقال إلى npm v12، راجع Install Scripts المطلوبة فعليًا. اسمح للحزم التي تثق بها بدل تعطيل الحماية الجديدة بصورة شاملة.
- راقب Publishing History والتغييرات الحساسة في الحساب. ظهور Release غير متوقعة يجب التعامل معه كإشارة Incident.
وماذا عن مطور يستهلك npm Packages فقط؟
حتى لو لم تنشر أي Package، فإن تغييرات Maintainer-side لا تلغي مخاطر Dependencies في مشروعك.
من المفيد الحفاظ على Lock File ومراجعته مع تغييرات Dependencies، وتفعيل أدوات Dependency وMalware Alerting المناسبة، والانتباه إلى أي Package جديدة أو إصدار يضيف Install Scripts أو مصادر تنزيل غير معتادة.
ولا يجب استخدام npm audit وحده كاختبار لمعرفة ما إذا كانت Dependency خبيثة؛ فـVulnerability معروفة وMalicious Package فئتان مختلفتان من المخاطر.
إذا كان المشروع يتعامل أيضًا مع نماذج AI أوMCP Servers أوPlugins، فإن Supply Chain تمتد إلى ما هو أبعد من حزم JavaScript التقليدية. ولهذا تصبح مراجعة المكونات الخارجية جزءًا من تأمين تطبيقات LLM وAI Agents نفسها، خصوصًا عندما تحصل الأداة المثبتة على Secrets أوصلاحيات تنفيذ أووصول إلى بيانات حساسة.
الخلاصة: التغيير الحقيقي هو الانتقال من الثقة إلى التحقق المرحلي
أهم ما تغير منذ هجمات npm في 2025 ليس ميزة واحدة، بل Architecture الأمان حول عملية نشر واستهلاك الحزم.
تم إلغاء Classic Tokens، ودُفع Maintainers نحو OIDC بدل Secrets طويلة العمر، وأصبح من الممكن فصل Build عن Release باستخدام Staged Publishing، ثم جاءت npm v12 لتقلل التنفيذ التلقائي أثناء Installation. وفي جانب المستهلك أضاف GitHub Cooldown لتحديثات Dependabot ووسع Malware Alerts، بينما أضافت npm فحصًا للحزم قبل إتاحتها.
هذه الضوابط لا تجعل Software Supply Chain آمنة تلقائيًا، لكنها تغير اقتصاد الهجوم: سرقة Credential واحدة لم تعد بالضرورة تمنح المهاجم الطريق الكامل من اختراق Pipeline إلى نشر Malware ثم تنفيذها فورًا لدى آلاف المستخدمين.
وهذا هو التحول الأهم في استراتيجية GitHub وnpm: بناء عدة نقاط توقف مستقلة داخل سلسلة الهجوم، بحيث يؤدي فشل طبقة واحدة إلى ترك طبقات أخرى قادرة على تقليل الانتشار أو كشفه أو منع وصوله إلى المستخدم النهائي.