لو عندك موقع، أو موقع عميل، شغّال بإضافة Visual Composer Website Builder، سيب اللي في إيدك دقيقتين. فيه ثغرة درجتها 9.8 من 10، ومش محتاجة المهاجم يسجّل دخول أصلاً، طلب واحد بس كفاية.
تحت هتلاقي إزاي تعرف إذا كنت متأثر، وتعمل إيه دلوقتي، وليه الغلطة دي درس لأي حد بيكتب إضافة (ووردبريس لتضيف له ميزة جديدة، مثل متجر أو نموذج تواصل أو تحسين للسيو، دون كتابة كود. اختر الإضافات الموثوقة المحدّثة، ولا…">Plugin) لووردبريس.
الخلاصة السريعة
| البند | التفاصيل |
|---|---|
| رقم الثغرة | CVE-2026-12227 |
| — | — |
| درجة الخطورة (CVSS 3.1) | 9.8 — حرجة |
| النوع | السيرفر بمسار يتحكم فيه المهاجم، فيُنفَّذ كود لم يقصده المطوّر، وقد تنتهي بالسيطرة على الموقع إذا وُجد على السيرفر…">تضمين الملفات المحلية (Local File Inclusion) — CWE-98 |
| الإصدارات المصابة | Visual Composer Website Builder حتى 45.16.0 |
| الإصدار المُصلح | 45.16.1 |
| يحتاج تسجيل دخول؟ | لا |
| الملف المصاب | visualcomposer/Modules/Editors/Settings/PageTemplatesController.php |
ماذا تفعل الآن؟
CVE-2026-12227
خمس خطوات لحماية موقعك
افحص الإصدار
هل Visual Composer Website Builder مثبت وإصداره 45.16.0 أو أقدم؟
حدّث إلى 45.16.1
من لوحة التحكم أو بأمر wp plugin update visualcomposer.
احذف غير المستخدم
منشئ صفحات قديم لا تحتاجه؟ احذفه بدل تعطيله.
راجع السجلات
طلبات تحمل vcv-template، وملفات PHP غريبة داخل uploads.
حدّث مواقع العملاء اليوم
الثغرات الحرجة تُستغل خلال ساعات من إعلانها.
- افحص الإصدار: من لوحة التحكم افتح الإضافات وابحث عن Visual Composer Website Builder. أو عبر WP-CLI:
wp plugin list --name=visualcomposer --fields=name,status,version
- حدّث فوراً إلى 45.16.1 أو أحدث:
wp plugin update visualcomposer
- إذا لم تكن تستخدمها فاحذفها: إضافة معطّلة أقل خطراً، لكن الحذف أنظف. كثير من المواقع القديمة تحمل منشئ صفحات لم يعد مستخدماً.
- راجع سجلات السيرفر: ابحث عن طلبات تحتوي على الباراميتر
vcv-templateمن عناوين غريبة قبل تاريخ التحديث، وافحص مجلدuploadsبحثاً عن ملفات.phpلا ينبغي أن تكون هناك. - إذا كنت تدير مواقع عملاء: حدّث الكل اليوم، ولا تنتظر دورة الصيانة الشهرية. الثغرات الحرجة المعلنة تُستغل عادة خلال ساعات لا أيام.
أين المشكلة بالضبط؟
تربط الإضافة دالة اسمها viewPageTemplate() على فلتر template_include في ووردبريس، وهو فلتر يعمل مع كل طلب للواجهة الأمامية، سواء كان الزائر مسجلاً أم لا:
// somewhere in PageTemplatesController.php
add_filter('template_include', [$this, 'viewPageTemplate'], 11);
لا يوجد أي فحص صلاحيات مثل current_user_can()، فكل طلب من أي زائر يمر مباشرة إلى هذه الدالة. وحسب إعادة البناء المنشورة في المقال الأصلي، يبدو منطق الدالة تقريباً هكذا:
public function viewPageTemplate($originalTemplate)
{
// ① Read vcv-template / vcv-template-type from the request
$current = $this->getCurrentTemplateLayout();
// ② Validation — runs against the RAW string
if (empty($current) || validate_file($current['value']) !== 0) {
return $originalTemplate;
}
// ③ Mutation — happens AFTER validation already passed
if ($current['type'] === 'vc-custom-layout'
&& strpos($current['value'], 'theme:') !== false) {
$current['value'] = str_replace('theme:', '', $current['value']);
}
// ④ Sink — the mutated value is used to locate and include a file
$result = locate_template($current['value']);
return $result ?: $originalTemplate;
}
تحقّق ثم عدّل: الترتيب الذي كسر كل شيء
الدالة تقرأ القيمة من رابط الطلب، ثم تمررها إلى validate_file()، وهي دالة من نواة ووردبريس ترفض أي مسار يحتوي على .. أو يبدأ بـ /. حتى هنا كل شيء سليم.
المشكلة في الخطوة الثالثة: بعد نجاح التحقق، تحذف الدالة كل تكرار لكلمة theme: من القيمة. المهاجم يستغل ذلك بتوزيع هذه الكلمة بين النقاط، فلا يرى التحقق أي .. متصلة، ثم يأتي الحذف فيلصق النقاط ببعضها ويصنع تسلسل اجتياز مجلدات (Directory Traversal) جديداً لم يفحصه أحد.
بعدها تأخذ locate_template() المسار الناتج كما هو وتضمّن الملف. إذا كان ملف PHP فسيُنفّذ كوده فوراً، وإذا كان المهاجم قد رفع قبلها ملفاً خبيثاً متنكراً في صورة، تتحول الثغرة إلى تنفيذ كود عن بُعد.
باختصار: دالة التحقق لم تخطئ، لكنها فحصت قيمة لم تعد موجودة لحظة الاستخدام. التحقق يعمل على النص قبل التعديل، والتضمين يعمل على النص بعده.
الدرس لمطوري الإضافات
إذا كنت تكتب إضافة أو كوداً في functions.php يقرأ مسار ملف من الطلب، فاتبع هذه القواعد:
- عدّل أولاً ثم تحقّق: نفّذ كل عمليات التنظيف والاستبدال، ثم شغّل التحقق على القيمة النهائية التي ستُستخدم فعلاً.
- استخدم قائمة مسموحات بدل التنظيف: إذا كانت القوالب المتاحة معروفة، قارن القيمة بقائمة ثابتة ولا تبنِ مساراً من مدخلات الزائر أصلاً.
- افحص الصلاحيات: أي كود على فلتر يعمل لكل الزوار يجب أن يفترض أن المدخلات عدائية.
مثال على الترتيب الصحيح:
$value = sanitize_text_field( wp_unslash( $_GET['tpl'] ?? '' ) );
$value = str_replace( 'theme:', '', $value ); // normalize first
$allowed = [ 'layouts/full-width.php', 'layouts/blank.php' ];
if ( ! in_array( $value, $allowed, true ) ) { // validate the final value
return $template;
}
return locate_template( $value ) ?: $template;
في القالب كاملًا والنماذج والنوافذ المنبثقة.">Elementor وJetEngine: قوالب Theme Builder (منشئ قوالب الموقع) والـ Listings تُحفظ كمنشورات في قاعدة البيانات وتُختار بشروط العرض Display Conditions، لا بمسار ملف يرسله الزائر، فهذا النمط تحديداً لا ينطبق عليها. لكن القاعدة نفسها تنطبق على أي كود مخصص تضيفه للموقع، وعلى أي إضافة تتعامل مع ملفات.
اقرأ أيضًا
الأسئلة الشائعة
س: كيف أعرف إذا كان موقعي يستخدم Visual Composer؟
ج: افتح صفحة الإضافات وابحث عن Visual Composer Website Builder، أو شغّل wp plugin list وابحث عن visualcomposer. لاحظ أنها إضافة مختلفة عن WPBakery Page Builder الذي كان اسمه سابقاً Visual Composer.
س: هل تكفي إضافة جدار حماية مثل Wordfence بدل التحديث؟
ج: جدار الحماية قد يصد الطلبات المعروفة، لكنه ليس بديلاً عن التحديث. الإصلاح الحقيقي في الإصدار 45.16.1.
س: ماذا أفعل إذا اكتشفت أن موقعي اختُرق؟
ج: خذ نسخة احتياطية (Backup) للحالة الحالية كدليل، ثم حدّث الإضافة، وغيّر كلمات المرور ومفاتيح wp-config.php، وافحص الملفات المعدلة حديثاً، أو استعد نسخة نظيفة سابقة للاختراق.
س: هل الثغرة تؤثر على المواقع التي عطّلت الإضافة؟
ج: الإضافة المعطّلة لا تربط كودها على الفلتر، فلا تُستغل بهذه الطريقة، لكن احذفها إذا لم تكن بحاجة إليها.
الخلاصة
ثغرة حرجة، بدون تسجيل دخول، وإصلاحها تحديث واحد إلى 45.16.1. وللمطورين: فحص القيمة قبل تعديلها هو نفسه عدم فحصها.
يلا افتح لوحة التحكم دلوقتي وحدّث، ولو بتدير مواقع عملاء ابعتلهم المقال ده. وابن موقعك قطعة قطعة، بس اتأكد إن كل قطعة متحدّثة.
مرجع المقال (بالإنجليزية): CVE-2026-12227 — How a Validate-Then-Mutate Bug Turns Into Unauthenticated LFI in Visual Composer
المقال ده مش ترجمة حرفية: متكيّف للقارئ العربي ومضاف عليه سياق ووردبريس وElementor وJetEngine.



