دروبال 11.4.8 - عالي - عن بُعد - رفع - رفع صور CKEditor 5 لا يزال يتخطى FileIsImage
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · drupal-ckeditor-fileisimage
الفئة: رفع غير مقيّد / XSS مخزّن الوصول: عن بُعد
Drupal core 11.4.8 (61044508) - Drupal
SA-CORE-2026-009 أضاف FileIsImage على حقول الصور في JSON:API و REST. لا يزال CKEditor5ImageController::getImageUploadValidators يُرجع FileExtension و FileSizeLimit و FileImageDimensions فقط. يُرجع FileImageDimensions دون أي مخالفة عندما لا يكون الملف صورة صالحة. امتداد اسم الملف هو الفحص المتبقي.
يمكن لمستخدم صيغة نصية مع رفع صور CKEditor 5 أن يرسل بايتات غير صورة باسم x.png إلى /ckeditor5/upload-image/{editor} ويحصل على 201 بالإضافة إلى رابط ملفات عام.
| المعرّف | لا يوجد CVE بعد |
| الفئة | رفع غير مقيّد / XSS مخزّن إذا تم استنشاقه |
| الوصول | عن بُعد (مستخدم صيغة موثّق) |
| CWE | CWE-434، CWE-79 |
| CVSS | متوسط: 5.4 CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:L/I:L/A:N |
| المنتج | Drupal core |
| المتأثر | 11.4.8 (61044508071749629aaf3380aa85971e94df9e84) |
| المصادقة | مستخدم موثّق لصيغة نصية مع رفع صور CKEditor 5 (basic_html / full_html على Standard) |
| الترخيص | GNU Affero GPL v3.0 |
| المختبر | 127.0.0.1 فقط |
يحتاج إلى حساب يمكنه استخدام صيغة مُحرّرها يمتلك image_upload.status بقيمة true. على Standard هما basic_html و full_html. لا يمكن لشخص غريب تمامًا بدون حساب الوصول إلى هذا المسار (_entity_access: editor.use بالإضافة إلى CSRF).
| الصلاحية | الطريقة / نقطة الوصول | النوع | مُثبت مختبريًا أو مُستنتج |
|---|---|---|---|
كتابة بايتات غير صورة إلى ملف .png عام تحت sites/default/files/inline-images/ | POST /ckeditor5/upload-image/{editor} متعدد الأجزاء upload | السلامة | مُثبت مختبريًا. أعاد x.png الرمز 201 و url=/sites/default/files/inline-images/x.png |
| قراءة تلك البايتات مرة أخرى من رابط الملفات العام | GET لـ JSON url | استطلاع | مُثبت مختبريًا. 200، 49 بايت، احتوى الجسم على DRUPAL-CKEDITOR-FILEISIMAGE-WITNESS |
| XSS مخزّن في زائر إذا استنشق خادم الويب أو المتصفح الملف كـ HTML/JS | نفس الرابط العام، Content-Type ليس صورة | السلامة (أصل الزائر) | مُستنتج. لم يغيّر هذا المختبر MIME في Apache. خزّن Drupal البايتات. |
| رفع صورة حقيقية عبر نفس المسار | التحكم control.png 1x1 PNG | مقصود | مُثبت مختبريًا. 201 |
مغلق على هذه البقايا: PHP/RCE عبر .php (مُثبت مختبريًا 422 FileExtension)؛ رفع غير موثّق؛ JSON:API/REST ImageItem (تلك المسارات تضيف FileIsImage بالفعل)؛ LPE؛ shell على قائمة امتدادات الصور الافتراضية المسموح بها.
ثبّتت Drupal 11.4.8 بعد موجة SA-CORE لعام 2026. يضيف JSON:API بالفعل القيد المفقود:
if (\is_a($field_definition->getItemDefinition()->getClass(), ImageItem::class, TRUE) && !array_key_exists('FileIsImage', $validators)) {
$validators['FileIsImage'] = [];
}
يفعل REST FileUploadResource.php الشيء نفسه. تُرك CKEditor 5 على اسم الملف + الحجم + الأبعاد:
return [
'FileExtension' => [
'extensions' => implode(' ', $allowed_extensions),
],
'FileSizeLimit' => [
'fileLimit' => $max_filesize,
],
'FileImageDimensions' => [
'maxDimensions' => $max_dimensions,
],
];
يُرجع FileImageDimensionsConstraintValidator دون أي مخالفة عندما لا يكون الملف صورة صالحة. انتقل Hub drupal:11.4 إلى 11.4.9؛ هذا التثبيت هو composer-exact drupal/recommended-project:11.4.8. أسقط 11.4.0 المقالة من Standard، لذا تُطبّق الصورة core/recipes/article_content_type بعد التثبيت حتى يُحمّل /node/add/article محرر CKEditor 5.
المنعطفات الخاطئة المسجّلة بالفعل: التعامل مع FileImageDimensions كفحص MIME (إنه أبعاد على صورة صالحة، ولا يفعل شيئًا بخلاف ذلك)؛ الادعاء بوجود shell PHP على القائمة الافتراضية المسموح بها (.php يعطي 422)؛ استخدام وسم hub العائم ومشاهدة 11.4.9 يظهر. مسرحية: reverse shell. الدليل هو 201 على x.png المزيف بالإضافة إلى 422 على نفس البايتات باسم x.php.
بقايا نفس التثبيت: oEmbed second-hop SSRF.
python3 drupal-ckeditor-fileisimage-Abraxas-Labs.py
أو
cd lab
./run.sh
استهدف فقط http://127.0.0.1:19500. Drupal 11.4.8 Standard مباشر على php:8.4-apache-trixie، SQLite.
SUCCESS drupal-ckeditor-fileisimage png-http=201 php-http=422 control-png-http=201 editor=basic_html stored-http=200 stored-has-witness=yes url=/sites/default/files/inline-images/x.png DRUPAL-CKEDITOR-FILEISIMAGE-WITNESS
أضف 'FileIsImage' => [] إلى CKEditor5ImageController::getImageUploadValidators. أبقِ FileExtension حتى يبقى .php على 422. يجب أن تستخدم أنواع وسائط الصور في Media Library ImageItem بدلًا من FileItem العام حتى ترث نفس القيد.
61044508071749629aaf3380aa85971e94df9e84)CKEditor5ImageController.phpGNU Affero GPL v3.0. انظر LICENSE. مختبر loopback فقط. لا ضمان.