
إعادة إنتاج لمشكلة أمنية عالية الخطورة تتيح هجمات XXE (XML eXternal Entity) على تسلسل XML في Ktor.
CVE-2023-45612 هي مشكلة أمنية عالية الخطورة تسمح بهجمات XXE (XML eXternal Entity) على تسلسل XML في Ktor، وقد تم إصلاحها في عام 2023.
فيما يلي وصف تفصيلي لكيفية إعادة إنتاج المشكلة.
أولاً، نحتاج إلى خادم سيعالج ملفات XML. ننشئ مشروع Kotlin من IntelliJ IDEA ونعدّل ملف build.gradle.kts لاستخدام تبعيات Ktor التي نحتاجها ومكوّن التسلسل (serialization plugin).
التبعية المعنية هي io.ktor:ktor-serialization-kotlinx-xml. الإصدار 2.3.4 هو الإصدار القابل للاستغلال، بينما الإصدار 2.3.5 هو الإصدار المُصحَّح.
بعد ذلك، نضيف في جذر المشروع ملفًا باسم sensitive_infos.txt يُقصَد أن يكون خاصًا وغير قابل للوصول من خارج الخادم. محتوى هذا الملف هو "يجب أن تكون هذه المعلومات سرية وغير قابلة للوصول عن طريق إرسال ملف .xmf.".
ثم ننفّذ الخادم في ملف Main.kt. وهو مصمم لمعالجة XML المُرسَل من العميل عن طريق تسلسله إلى String (name) من الصنف Person. بعد ذلك يرد الخادم بتأكيد الاسم الذي أرسله العميل للتو. بعد تشغيل الخادم، يمكننا تجربة الاستخدام العادي والاستخدام الخبيث:
يرسل العميل ملف XML يحتوي على اسمه ويستلم تأكيدًا بالاسم الذي أرسله للتو. يمكننا اختبار ذلك باستخدام ملف XML التالي:
<?xml version="1.0" encoding="UTF-8"?>
<manifest xmlns="http://example.com/">
<name>Clément</name>
</manifest>
والأمر:
curl -X POST http://localhost:8080/process -H "Content-Type: application/xml" -d @data.xml
يُعرّف العميل كيانًا (entity) بتوفير String بديل على شكل URI ويرسل ملف XML الخبيث، ثم يتلقى محتوى ملف سري يمكن للخادم الوصول إليه. أعرض أدناه مثالًا بملف (sensitive_infos.txt) يقع في جذر الخادم، لكن لاحظ أنه قد تتمكن أيضًا من الوصول إلى ملفات أخرى (إذا كان محلل XML يستطيع الوصول إلى محتواها) باستخدام على سبيل المثال file:/// إذا كان الخادم يعمل على Linux.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE test [
<!ENTITY exploit SYSTEM "sensitive_infos.txt">
]>
<manifest xmlns="http://example.com/">
<name>&exploit;</name>
</manifest>
والأمر:
curl -X POST http://localhost:8080/process -H "Content-Type: application/xml" -d @xxe.xml
يرد الخادم بـ "الاسم المُرسل: يجب أن تكون هذه المعلومات سرية وغير قابلة للوصول عن طريق إرسال ملف .xmf."، وهذا يثبت أننا وصلنا بالفعل إلى المعلومات السرية وبالتالي توجد ثغرة أمنية.
بالمناسبة، تغيير الإصدار من 2.3.4 إلى 2.3.5 في ملف build.gradle.kts يحل المشكلة، حيث يرد الخادم فقط بـ "الاسم المُرسل" عند الإدخال الخبيث، مع الحفاظ على رد طبيعي للإدخال العادي، مما يؤكد لنا أن المشكلة الأمنية قد حُلّت في الإصدار 2.3.5.
لا تثق أبدًا بالمستخدم! يمكن لمحلل Ktor تنقية المدخلات مثلًا بتجاهل جميع ملفات XML التي تحتوي على كيان.
وهذا أقل تقييدًا للمستخدم؛ إذ يمكن لـ Ktor تعطيل الكيانات الخارجية افتراضيًا عن طريق ضبط ميزتَي external-general-entities وexternal-parameter-entities على false، بحيث لا يزال بإمكان المستخدم تعريف كيان في ملف XML الخاص به، لكن لا يمكن لهذا الكيان الوصول إلى أي مورد خارجي بعد الآن.
أضِف اختبارات هجمات XXE في نظام CI/CD الخاص بـ Ktor للتأكد من أن الكود غير معرّض لهذه الهجمات.