انتقل إلى المحتوى

دليل

Slopsquatting: حين يثبّت مساعد الذكاء الاصطناعي حزمة غير موجودة

يخترع مساعدو البرمجة أحيانًا أسماء حزم يستطيع المهاجمون تسجيلها. ما الذي تكشفه الأبحاث، وكيف تتحقق من اعتمادية في دقيقة واحدة.

· قراءة في 8 دقائق · بقلم فريق vetkit

روبوت يمدّ يده نحو صندوق غريب مقنّع مخبّأ بين حزم متطابقة على رفّ، بينما يوقفه مطوّر ويشير إلى الصندوق.روبوت يمدّ يده نحو صندوق غريب مقنّع مخبّأ بين حزم متطابقة على رفّ، بينما يوقفه مطوّر ويشير إلى الصندوق.

اطلب المساعدة من مساعد برمجة، وكثيرًا ما سيقترح عليك مكتبة إلى جانب الشيفرة. في معظم الأحيان تكون المكتبة حقيقية. وأحيانًا لا تكون كذلك: يُنتج النموذج اسمًا يبدو صحيحًا، ويتبع أعراف التسمية في المنظومة، لكنه ببساطة غير موجود على npm أو PyPI. وإذا شغّلت أمر التثبيت دون أن تنظر، يحدث أحد أمرين. إما أن يفشل التثبيت، وهذا مزعج لكنه غير ضار. وإما أن يكون أحدهم قد نشر بالفعل حزمة بهذا الاسم تحديدًا، فتكون قد شغّلت شيفرته للتو.

ما هو slopsquatting

Slopsquatting هو اسم الحالة الثانية: تسجيل أسماء حزم تميل نماذج الذكاء الاصطناعي إلى اختراعها، وانتظار أن يثبّتها الناس. يُنسب المصطلح عادةً إلى Seth Larson، مطوّر الأمان المقيم في Python Software Foundation، وهو تلاعب لفظي بمصطلح typosquatting، حيث يسجّل المهاجمون أسماء مكتوبة بأخطاء إملائية لحزم شائعة. والفرق هو من يرتكب الخطأ. ففي typosquatting يخطئ إنسان في الكتابة، أما في slopsquatting فيقترح نموذجٌ الاسم الخطأ بثقة، ويثق به إنسان.

والخطر ليس افتراضيًا. ففي تجربة انتشرت على نطاق واسع، لاحظ باحث أن النماذج ظلت توصي بحزمة تُدعى huggingface-cli، وليست هذه طريقة تثبيت أداة Hugging Face الحقيقية. فنشر حزمة فارغة بهذا الاسم ليرى ما سيحدث، ونُزّلت عشرات آلاف المرات. كانت الحزمة غير ضارة، ولم تكن الحزمة الخبيثة لتكون كذلك.

كم مرة تخترع النماذج حزمًا

أشمل دراسة حتى الآن هي “We Have a Package for You! A Comprehensive Analysis of Package Hallucinations by Code Generating LLMs”، التي قُدّمت في USENIX Security 2025. ولّد المؤلفون 576,000 عينة شيفرة بلغتي Python وJavaScript باستخدام 16 نموذجًا شائعًا، وفحصوا كل حزمة أشارت إليها الشيفرة. ووجدوا أن متوسط نسبة الحزم المهلوَسة بلغ 5.2% على الأقل للنماذج التجارية و21.7% للنماذج مفتوحة المصدر، وجمعوا 205,474 اسم حزمة فريدًا غير موجود.

هناك تفصيلان في الورقة أهم من الأرقام الرئيسية. الأول أن الأسماء المخترعة كثيرًا ما تتكرّر: فحين أعاد المؤلفون تشغيل الأوامر النصية التي أنتجت هلوسة عشر مرات، عاد 43% من تلك الأسماء في كل مرة دون استثناء. والأسماء التي يمكن التنبؤ بها هي بالضبط ما يحتاجه المهاجم. والثاني أن معظمها ليس أخطاءً إملائية قريبة من حزم حقيقية، لذا لن يكشفها فحص الأخطاء الإملائية. فنحو 13% فقط كانت على بُعد حرف أو حرفين من اسم موجود.

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

لماذا يسهل تنفيذ هذا الهجوم

النشر على npm أو PyPI مجاني ويستغرق دقائق. ولا يحتاج المهاجم إلى اختراق أي شيء؛ يكفيه أن يخمّن الأسماء التي تنتجها النماذج ويسجّلها أولًا. ثم تتكفّل سكربتات التثبيت بالباقي: إذ يشغّل npm سكربتات preinstall وpostinstall افتراضيًا، ويمكن لحزمة Python أن تشغّل شيفرة عند بنائها أو استيرادها. وعملية تثبيت واحدة على حاسوب مطوّر أو مشغّل CI قد تكشف مفاتيح SSH وبيانات اعتماد السحابة والرموز الموجودة في متغيرات البيئة.

والوكلاء يزيدون الأمر حدّة. فحين يستطيع المساعد تشغيل npm install أو pip install بنفسه، قد لا ينظر أي إنسان إلى اسم الحزمة على الإطلاق.

تحقّق من حزمة في دقيقة واحدة

قبل أن تضيف اعتمادية لم تخترها بنفسك، ابحث عنها في السجل:

bash
# npm: does it exist, who publishes it, when was it first released?npm view some-package name version time.created repository.url # PyPI: same questions, from the JSON APIcurl -s https://pypi.org/pypi/some-package/json | jq '.info | {name, version, home_page, project_urls}'

ثم اطرح بعض الأسئلة السريعة:

  • هل هي موجودة أصلًا؟ الخطأ 404 يعني أن الاسم مخترع. لا تنشئه، ولا تثبّت بديلًا “قريبًا بما يكفي” دون التحقق منه هو الآخر.
  • هل هي جديدة تمامًا؟ حزمة نُشرت أول مرة في الأسابيع القليلة الماضية، بإصدار واحد ودون تاريخ، تستحق نظرة ثانية، خصوصًا إذا تطابق اسمها مع ما اقترحه مساعدك.
  • هل تشير إلى مشروع حقيقي؟ مستودع مرتبط فيه commits وissues ومستخدمون آخرون علامة جيدة. أما المستودع الفارغ أو الغائب فليس كذلك.
  • هل هي الحزمة التي تطلب منك الوثائق تثبيتها؟ وثائق الأداة الحقيقية نفسها هي أفضل مصدر للاسم الصحيح. ومقارنة huggingface-cli بأمر التثبيت الموثّق مثال جيد على السبب.

لا تشغّل التثبيت لتعرف

تثبيت الحزمة هو بالضبط آلية الهجوم. تحقّق من السجل أولًا، ثم ثبّت.

عادات مفيدة

  • استخدم ملفات القفل (lockfiles) وثبّت منها في CI (npm ci، وpip install -r مع إصدارات وقيم تجزئة مثبّتة)، حتى لا يتسلّل اسم جديد أثناء البناء.
  • راجع تغييرات الاعتماديات في طلبات pull request بالعناية نفسها التي تراجع بها تغييرات الشيفرة. والفرق الذي يضيف ثلاث حزم يستحق ثلاث عمليات بحث.
  • اطلب من مساعدك أن يرفق رابط صفحة الحزمة في السجل أو وثائقها الرسمية حين يقترح شيئًا جديدًا. إنها طريقة رخيصة لكشف الاسم المختلَق.
  • إذا كان وكيلك يستطيع تشغيل عمليات التثبيت بنفسه، فأعطه قائمة سماح أو اشترط التأكيد على الاعتماديات الجديدة.
  • فكّر في تعطيل سكربتات التثبيت افتراضيًا (npm config set ignore-scripts true) وتفعيلها فقط للحزم التي تحتاجها. هذا يعطّل بعض الحزم، فاختبره أولًا.

أتمِت الجزء المملّ

البحث اليدوي يصلح لحزمة واحدة. لكنه لا يصلح لمستودع فيه مئات الاعتماديات، أو لعمليات استيراد مدفونة في شيفرة ولّدها مساعد الأسبوع الماضي. هذه مهمة مناسبة للأدوات.

تبحث مجموعة فحوص مخاطر شيفرة الذكاء الاصطناعي في vetkit عن الاعتماديات وعمليات الاستيراد الموجودة في ملفات البيان (manifests) لديك في السجلات العامة مثل npm وPyPI. وتنبّه إلى الأسماء غير الموجودة، والإصدارات التي لم تُنشر قط، والحزم التي صدرت أول مرة خلال آخر 30 يومًا. ولا تُرسل إلى السجلات إلا أسماء الحزم وإصداراتها، ولا تُرسل شيفرتك المصدرية أبدًا، ولا يُبحث عن الحزم القادمة من سجلات خاصة أو من مساحات العمل الخاصة بك. كما يوفّر خادم MCP الخاص بـ vetkit فحصًا للحزم، بحيث يستطيع المساعد التحقق من الاسم قبل أن يثبّت أي شيء.

أيًّا كانت الأداة التي تستخدمها، فالمبدأ واحد: اسم الحزمة الذي جاء من نموذج هو ادعاء، والتحقق من الادعاءات رخيص قبل تشغيلها.

طلب الوصول المبكر

حدّثنا عن فريقك والمستودعات التي تريد تدقيقها. نُتيح الوصول لفرق على دفعات صغيرة، وسنرد عليك عبر البريد الإلكتروني.

نستخدم هذه المعلومات للرد على طلبك فقط. سياسة الخصوصية