حزمة واحدة وكل مفاتيحك: اختراق إصدار LiteLLM
أنا أكتب PHP وNode، وهذه حادثة في عالم Python. أكتب عنها مع ذلك لأن النمط لا علاقة له باللغة: مكتبة تقف أمام كل مزوّدي الذكاء الاصطناعي تحمل كل مفاتيحهم، فإصدار مسموم واحد يصل إليهم جميعًا. بحسب متتبّع الحوادث pwn.watch، هذا ما حدث لمكتبة LiteLLM يوم 21 أكتوبر 2026.
ما يرويه المتتبّع
ما يلي ملخص المتتبّع، أي رواية جهة تجميع واحدة، والمرجع الذي تتحقق منه قبل أي خطوة هو التنبيه الرسمي للمشروع. يصنّف المتتبّع الحادثة حرجة ومُصلحة. ويقول إن المهاجمين اخترقوا خط إصدار LiteLLM ونشروا نسخة خبيثة litellm==1.107.0 على PyPI بقيت متاحة نحو ساعتين، إضافة إلى وسوم مخترقة على Docker Hub وGHCR هي v1.107.0 وlatest وmain-latest وmain-stable. وبحسب المتتبّع، تضع الحزم الملفات cook.pth وcook.py وsitecustomize.py، التي تسرق بيانات اعتماد السحابة والمطوّرين وأدوات الذكاء الاصطناعي مع كل تشغيل لـPython، وتفتح محمّلًا لتنفيذ كود عن بُعد. ويصفها المتتبّع بأنها ثاني اختراق لـLiteLLM في 2026.
الوسم latest يستحق وقفة. حاوية تسحب latest عند إعادة التشغيل لم تكن تحتاج إلى أن يرقّي أحد شيئًا كي تستقبل هذا الإصدار.
وقد لا تكون حادثة منفردة. تقول Railway في إفصاحها الخاص في اليوم نفسه إنها تعتقد أن حادثتها جزء من سلسلة هجمات على شركات المنصات هدفها الوصول إلى مزوّدي خدمات الاستدلال للذكاء الاصطناعي.
لماذا تُستهدف بوابة الذكاء الاصطناعي
معرفة عامة: مكتبة البوابة أو الوكيل موجودة لتتحدث مع مزوّدي نماذج كثيرين عبر واجهة واحدة. معنى ذلك أن العملية التي تشغّلها تحمل مفاتيح كل المزوّدين في بيئتها دفعة واحدة. اختراق اعتمادية عادية يصل إلى مفاتيح خدمة واحدة، أما هذا فيصل إلى مفاتيحها كلها، ومفاتيح الذكاء الاصطناعي رصيد إنفاق يستطيع غيرك استهلاكه.
ملفات بدء التشغيل تزيد الأمر سوءًا. وهذه أيضًا معرفة عامة وسلوك موثّق في Python: ملفات .pth داخل site-packages تُعالَج عند بدء المفسّر، والأسطر التي تبدأ فيها بكلمة import تُنفَّذ، وملف sitecustomize يعمل أيضًا عند البدء. لذلك لا تنتظر حزمة خبيثة من هذا النوع أن يستورد كودك المكتبة؛ أي عملية Python في تلك البيئة تشغّلها، حتى سكربت عابر أو تشغيل اختبارات.
ولقرّاء PHP وNode: الشكل نفسه ينطبق على أي شيء يحمل بيانات اعتماد كثيرة، مثل غلاف حول Stripe أو Twilio أو عدة حزم ذكاء اصطناعي، أو أداة نشر من سطر الأوامر تصل إلى كل البيئات.
احتواء يحدّ من الضرر
لا شيء من هذا يمنع اختراق خط الإصدار، لكنه يحدّ مما يستطيع إصدار سيئ واحد الوصول إليه.
ثبّت بالإصدار والبصمة معًا. رقم الإصدار وحده لا يمنع ملفًا أُعيد نشره أو استُبدل، أما البصمة فتمنعه. مع pip، ملف متطلبات يسرد البصمات مع الخيار --require-hashes يرفض أي شيء آخر، وملفات القفل في uv وpip-tools تؤدي الوظيفة نفسها. وثبّت صور الحاويات بالبصمة digest بدل وسم متحرك مثل latest، وانتظر بضعة أيام قبل اعتماد أي إصدار جديد تمامًا. اعزل. ثبّت البوابة وشغّلها في بيئة أو حاوية خاصة بها لا تحمل إلا المفاتيح التي تحتاجها، ولا تثبّت حزمًا جديدة على جهاز محمّل بأسرار الإنتاج. قيّد المفاتيح. أعطِ كل مزوّد مفتاحًا مستقلًا قصير العمر بسقف إنفاق، فيكون المسروق منها رخيصًا وسريع الاستبدال.
pip install --require-hashes -r requirements.txt
pip show litellm
إن ثُبِّت الإصدار 1.107.0 أو سُحبت صورته
الترتيب العام: أخرج البيئة أو الحاوية من الخدمة، وتحقق من الإصدار ووسم الصورة اللذين عملا فعلًا، وأعد البناء من إصدار سليم مثبّت، ثم دوّر كل مفتاح كانت تلك البيئة تستطيع قراءته، من جهاز نظيف. وبسبب ملفات بدء التشغيل، فأي عملية Python هناك محسوبة، لا البوابة وحدها. وتحقق من الإصدارات والوسوم المتأثرة في التنبيه الرسمي لـLiteLLM.
ملاحظات القراء