Yucaerin/CVE-2026-5118

GitHub: Yucaerin/CVE-2026-5118

Stars: 0 | Forks: 1

# CVE-2026-5118 — Divi Form Builder <= 5.1.2 — Unauthenticated Privilege Escalation via Role Injection 🔥 **Vulnerability Summary** The vulnerability stems from the `create_user()` function in `FormSubmissionHandler.php`, which accepts the `role` parameter directly from user-submitted POST data without proper authorization or allowlist validation. The plugin only checks whether the submitted role **exists** in the system (e.g., `administrator` is a valid WordPress role) — it never checks whether the role is **safe** for public registration. **Breakthrough Discovery:** The `fb_nonce` used by Divi Form Builder is a **global shared nonce** (`wp_create_nonce('security')`) — identical across all forms on the site. Furthermore, `form_type=register` can be **overridden via POST** to the shared AJAX handler. This means any DFB form (contact, quote, feedback, etc.) can be weaponized to trigger user registration with arbitrary role assignment. 🔍 **Affected Plugin** - **Plugin Name:** Divi Form Builder - **Affected Version:** <= 5.1.2 - **Vulnerability Type:** Unauthenticated Privilege Escalation via Role Injection - **CVE ID:** CVE-2026-5118 - **CVSS Score:** 9.8 (Critical) - **CWE:** CWE-266 — Incorrect Privilege Assignment - **Impact:** Full Site Takeover — Admin Account Creation 🧨 **What Attackers Can Do** | Capability | Impact | |---|---| | 🔑 Create admin account without login | **Full Site Takeover** | | 📦 Access WooCommerce customer data | **Data Breach** | | 💉 Edit plugin/theme PHP files | **Remote Code Execution** | | 🕳️ Install hidden backdoors | **Persistent Access** | | 👥 View all user data | **Privacy Violation** | 🧪 **Exploit Features** - 🔓 **No authentication required** - 📝 **Works through ANY DFB form** — contact, quote, newsletter, feedback, etc. - 🎯 **Targets the AJAX endpoint** `/wp-admin/admin-ajax.php?action=de_fb_ajax_submit_ajax_handler` - 🧠 **Role injection** — submits `role=administrator` alongside normal form fields - 🌐 **Mass scanning support** — threaded multi-target scanner with auto-discovery - 📄 **Results saved to** `result.txt` 🧠 **Vulnerable Code** // includes/shared/handlers/FormSubmissionHandler.php ~ line 2250 $role = isset($form_data['role']) ? sanitize_text_field($form_data['role']) : 'subscriber'; // ~ line 2278 — ONLY checks if role EXISTS, not if it is SAFE $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'; // ← "administrator" EXISTS, so this check PASSES } // ~ line 2301 — Directly applies the injected role $user = new WP_User($user_id); $user->set_role($role); // ← PRIVILEGE ESCALATION! 🚀 **Usage** ### Single Target python3 exploit.py -t http://target.com python3 exploit.py -t https://target.com -u hacker -p Pass123! -e hack@proton.me ### Mass Scan (List without http/https) Create `targets.txt`: target1.com target2.com:8080 192.168.1.50 subdomain.target.com python3 exploit.py -l targets.txt -T 20 ### Options | Flag | Description | |---|---| | `-t, --target` | Single target URL | | `-l, --list` | File with target list (one per line, http/https optional) | | `-T, --threads` | Threads for mass scan (default: 10) | | `-o, --output` | Output file for results (default: `result.txt`) | | `-u, --username` | Custom username for new account | | `-p, --password` | Custom password for new account | | `-e, --email` | Custom email for new account | | `-v, --verbose` | Verbose debug output | | `--no-confirm` | Skip permission confirmation prompt | 🛠 **Fix Recommendations** // SECURE: Allowlist only safe roles for public registration $allowed_registration_roles = array('subscriber', 'contributor'); if (!in_array($role, $allowed_registration_roles, true)) { $role = 'subscriber'; // ← Reject ALL dangerous roles } - Remove the `role` hidden input from frontend forms entirely - Add `current_user_can('create_users')` capability checks for privileged roles - Implement strict nonce verification scoped per-form instead of global - Add rate limiting on the registration AJAX endpoint 🧠 **Researcher** - Credit: [0xd4rk5id3](https://www.wordfence.com/threat-intel/vulnerabilities/researchers/0xd4rk5id3) 📚 **References** - [Wordfence Advisory](https://www.wordfence.com/threat-intel/vulnerabilities/wordpress-plugins/divi-form-builder/divi-form-builder-512-unauthenticated-privilege-escalation-via-role) - [Original CVE Repository](https://github.com/zycoder0day/CVE-2026-5118) 🔒 **Disclaimer:** This information is provided for **educational** and **authorized penetration testing** purposes only. Unauthorized exploitation of computer systems is illegal and unethical. Always obtain explicit written permission before testing any target you do not own.