This is a valet stand that hands out master keys, but only at the buildings that actually set the desk outside
CVE-2026-5118 is an improper privilege-management bug in the WordPress Divi Form Builder plugin. In versions up to and including 5.1.2, the registration flow trusts a user-supplied role value from POST data instead of forcing the configured default registration role. If an attacker can hit the vulnerable form workflow, they can register a new administrator account and take over the site; 5.1.3 changes registration so the configured form role is always enforced.
The vendor's 9.8/CRITICAL rating is technically understandable because successful exploitation is unauthenticated and ends in full WordPress admin. But it overstates the average enterprise risk because not every plugin install is reachable: the attacker still needs a publicly exposed Divi Form Builder registration-capable workflow on an internet-facing site. That exposure gate is real and materially narrows the victim pool, so this lands as HIGH, not blanket-CRITICAL.
4 steps from start to impact.
Find a reachable Divi Form Builder site
httpx/curl/browser recon and looks for Divi Form Builder assets or forms on public pages. The important distinction is not just plugin presence, but whether the site exposes a Divi Form Builder workflow that can reach the vulnerable registration handler.- Target runs WordPress with Divi Form Builder installed
- At least one relevant Divi Form Builder page or form is reachable from the internet
- Many installs use the plugin only for contact or internal workflows
- Some enterprises do not expose self-registration at all
- Premium/niche plugin footprint is much smaller than core WordPress exposure
Harvest form metadata and nonce
fb_nonce, form_key, and form type controls. Public exploit writeups also claim the handler can be coerced through the shared endpoint at /wp-admin/admin-ajax.php?action=de_fb_ajax_submit_ajax_handler.- A public page exposes the necessary Divi Form Builder form markup or JavaScript data
- The site does not fully hide or gate the submission workflow
- Form-specific validation, CAPTCHA, or custom field requirements can break mass exploitation
- WAFs and bot controls often interfere with scripted harvesting
Submit a forged registration with role=administrator
curl, a Python PoC, or Burp Repeater to POST to the AJAX handler and inject role=administrator. On vulnerable versions, the plugin validates that the role exists, but not that it matches the form's configured safe role, so a new admin account can be created without prior authentication.- Plugin version is 5.1.2 or earlier
- The vulnerable registration code path is reachable
- Submitted data passes any required validation checks
- WAF/mod_security rules may block suspicious POSTs to
admin-ajax.php - CAPTCHA, anti-automation, or registration throttling can disrupt commodity spraying
- Some sites may not expose the exact vulnerable registration workflow despite running the plugin
admin-ajax.php with action=de_fb_ajax_submit_ajax_handler; version-only scanners will miss whether the path is actually exposed.Log in and convert admin into durable control
/wp-login.php and uses normal WordPress administration to persist. Typical follow-on actions are plugin installation, theme/plugin file edits, new API keys, new users, or data theft; on many WordPress deployments, admin is effectively one click away from code execution.- The forged account was created successfully
- The site allows standard WordPress admin logon for the new account
- Some sites disable in-dashboard file editing
- Conditional access, SSO, or step-up controls may still slow first login
- Administrator actions may be logged by WordPress audit plugins
/wp-admin/admin-ajax.php where action=de_fb_ajax_submit_ajax_handler, unless the business explicitly requires it. This is imperfect but useful containment while patching; deploy within 30 days.MFAon existing admins alone does not fix the bug; the attacker is creating a new admin account through the vulnerable workflow.- Hiding or renaming
wp-login.phpdoes not address the vulnerableadmin-ajax.phpsubmission path. - Version-only scanning is not enough for prioritization; it finds the plugin but does not tell you whether the registration-capable path is publicly exposed.
The supporting signals.
| In-the-wild status | No CISA KEV listing found during this assessment, and I did not find a primary-source vendor statement confirming active exploitation. |
|---|---|
| Public exploit code | Yes. A public GitHub PoC exists at Yucaerin/CVE-2026-5118; secondary reporting also points to Sploitus. Treat weaponization as real. |
| EPSS | 0.00037 from the prompt, which is *very low* for expected 30-day exploitation probability and argues against panic-driven fleetwide emergency handling. |
| KEV status | Not listed in the CISA Known Exploited Vulnerabilities Catalog at the time of this reassessment. |
| CVSS vector | CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H means unauthenticated network reachability and full impact *if the vulnerable workflow is exposed*. |
| Affected versions | Divi Form Builder <= 5.1.2 according to Wordfence and vendor changelog context. |
| Fixed version | 5.1.3; vendor changelog states registration forms now always assign the role chosen in form settings. |
| Exposure reality | This is not equivalent to 'all WordPress sites are remotely ownable'. The attacker needs a reachable Divi Form Builder registration-capable path; that sharply reduces the exposed population versus the raw CVSS. |
| Disclosure timeline | Use exact dates carefully: Wordfence says May 20, 2026 for public publication, while other CVE aggregators show May 21, 2026 as the CVE publish date. |
| Researcher / reporter | 0xd4rk5id3 - EnvoraSec is credited by Wordfence and thanked in the vendor's 5.1.3 security changelog entry. |
Sources.
Why this verdict
- Down from 9.8: vendor CVSS assumes reachable vulnerable functionality, but real exploitation requires a public Divi Form Builder registration-capable path rather than mere plugin installation.
- Another downgrade: this is a premium/niche WordPress plugin, not a ubiquitous platform service, so the exposed population is meaningfully smaller than a raw internet-RCE-style CVSS suggests.
- Held at HIGH: if the path is exposed, the attacker is unauthenticated and the outcome is administrator account creation, which is operationally equivalent to site takeover and often a short hop to code execution.
Why not higher?
I am not calling this CRITICAL because the attack surface is conditional, not universal. No KEV entry, very low EPSS, and no primary-source proof of mass exploitation mean the fleetwide urgency should be driven by reachability of registration workflows, not by the headline CVSS alone.
Why not lower?
I am not dropping this to MEDIUM because there is no auth barrier once the workflow is exposed. An internet attacker creating a WordPress admin account is a severe control-plane compromise with direct business impact, especially on customer-facing sites, e-commerce content, and any host where admins can install or edit code.
Crowdsourced verification payload.
Run this on the WordPress host with filesystem access to the site root or plugin directory. Invoke it as sudo bash verify-cve-2026-5118.sh /var/www/html or point it straight at the plugin dir like sudo bash verify-cve-2026-5118.sh /var/www/html/wp-content/plugins/divi-form-builder; root is not strictly required, but you need read access to the plugin files.
#!/usr/bin/env bash
# verify-cve-2026-5118.sh
# Checks Divi Form Builder version on a WordPress host.
# Output: VULNERABLE / PATCHED / UNKNOWN
# Exit codes: 0=PATCHED, 1=VULNERABLE, 2=UNKNOWN
set -euo pipefail
TARGET="${1:-}"
if [[ -z "$TARGET" ]]; then
echo "UNKNOWN"
exit 2
fi
PLUGIN_DIR=""
if [[ -d "$TARGET/wp-content/plugins/divi-form-builder" ]]; then
PLUGIN_DIR="$TARGET/wp-content/plugins/divi-form-builder"
elif [[ -d "$TARGET" && "$(basename "$TARGET")" == "divi-form-builder" ]]; then
PLUGIN_DIR="$TARGET"
else
echo "UNKNOWN"
exit 2
fi
MAIN_FILE=""
for f in "$PLUGIN_DIR"/*.php; do
[[ -e "$f" ]] || continue
if grep -qiE '^\s*Plugin Name:\s*Divi Form Builder' "$f" 2>/dev/null; then
MAIN_FILE="$f"
break
fi
done
VERSION=""
if [[ -n "$MAIN_FILE" ]]; then
VERSION="$(grep -iE '^\s*Version:\s*' "$MAIN_FILE" | head -n1 | sed -E 's/^\s*Version:\s*//I' | tr -d '\r' | xargs || true)"
fi
if [[ -z "$VERSION" && -f "$PLUGIN_DIR/readme.txt" ]]; then
VERSION="$(grep -iE '^\s*Stable tag:\s*' "$PLUGIN_DIR/readme.txt" | head -n1 | sed -E 's/^\s*Stable tag:\s*//I' | tr -d '\r' | xargs || true)"
fi
if [[ -z "$VERSION" ]]; then
echo "UNKNOWN"
exit 2
fi
verlte() {
# returns true if $1 <= $2 using sort -V
[[ "$(printf '%s\n%s\n' "$1" "$2" | sort -V | head -n1)" == "$1" ]]
}
if verlte "$VERSION" "5.1.2"; then
echo "VULNERABLE"
exit 1
else
echo "PATCHED"
exit 0
fi