The shopping-cart signup form that hands out the store keys
Dokan Pro is the paid tier of the Dokan multi-vendor marketplace plugin — the plumbing behind ~15,000+ WooCommerce storefronts that let third-party sellers list products. The update_capabilities REST endpoint exists so vendors can grant their own staff limited permissions (view orders, edit inventory, etc). The permission check on that endpoint fails to constrain WHICH capabilities can be assigned — an authenticated user at vendor or staff level can POST a payload adding administrator, manage_options, or any other WordPress capability to their own account. All versions up to and including the patched release are affected; users must upgrade to the fixed Dokan Pro build (Wordfence tracks the vulnerable range against the vendor changelog).
Vendor score of 8.8 HIGH is honest. The PR:L in the CVSS vector understates reality: on a marketplace plugin, self-registration as a customer/vendor is the default configuration — the 'authentication' requirement is a checkout form, not a stolen credential. Offset against that is scope: this is a per-site compromise, not fleet-scale identity infrastructure. Net: HIGH is the correct bucket, and we're not downgrading.
4 steps from start to impact.
Register as customer or vendor
- Target site has open registration (default for Dokan marketplaces)
- Site reachable over the internet
- A minority of Dokan installs disable open vendor registration and require manual approval
- CAPTCHA on registration slows but does not block scripted signup
Authenticate and grab a nonce
/wp-login.php or the WooCommerce customer login, then requests a WordPress page to harvest a valid REST nonce (wp_rest). No special tooling required — curl plus a cookie jar is enough. Public PoCs will wrap this in a Python script.- Valid session cookie
- REST API not IP-restricted
- Sites behind Cloudflare bot management may throttle scripted logins
- 2FA plugins on the customer role are rare but block this step
POST to /wp-json/dokan/v1/... update_capabilities
{"capabilities": {"administrator": true, "manage_options": true}}. The endpoint's permission_callback only verifies the caller holds a generic vendor/staff cap — it does NOT verify that the requested capabilities are within an allowed allowlist. WordPress writes the new caps to wp_usermeta.- Vulnerable Dokan Pro version installed
- Attacker's account has vendor or staff role
- Almost none — this is the core bug. WAF rules for this specific endpoint did not exist at disclosure.
Log out, log back in as administrator
- Persistent capability grant
- wp-admin reachable
- File-integrity monitoring on wp-content/plugins catches plugin-drop webshells
- Hardened hosts disallow
DISALLOW_FILE_MODS— but few marketplaces run with it
wp_usermeta is a strong signal if the site logs usermeta writes; most do not.The supporting signals.
| In-the-wild exploitation | No confirmed campaigns at disclosure (2026-07-01). Historical pattern: Dokan/WooCommerce priv-esc CVEs are weaponized within 2–4 weeks — see Wordfence's 15,000-site campaign write-up for the 2025 Dokan Pro flaw. |
|---|---|
| PoC availability | No public PoC on GitHub at disclosure. curl-level exploitation is trivial once the endpoint route is known; expect PoC within 7 days. |
| EPSS | Not yet scored at 2026-07-01 disclosure. Comparable Dokan Pro priv-esc CVEs sit in the 0.4–2% range within 30 days and climb once PoCs land. |
| KEV | Not listed. WordPress plugin CVEs are historically under-represented in KEV despite mass exploitation. |
| CVSS 3.1 | AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H → 8.8 HIGH. PR:L understates reality because Dokan marketplaces enable customer/vendor self-registration by default. |
| Affected versions | All Dokan Pro versions up to and including the last vulnerable release referenced in the advisory. Confirm exact ceiling in the Dokan changelog. |
| Fixed version | Latest Dokan Pro release published on or after 2026-07-01. Verify against the vendor changelog before declaring patched — vendor licensing means updates must be pulled via authenticated download. |
| Exposure population | Dokan Pro is estimated at 10k–20k active paid installs, near-universally internet-facing (it is an e-commerce plugin). Wordfence's related Dokan advisory cited ~15,000 impacted sites. |
| Disclosure | 2026-07-01, tracked under CWE-269 Improper Privilege Management. |
| Reporter | Advisory pipeline via Wordfence Threat Intelligence / Patchstack (typical channel for Dokan Pro disclosures). |
noisgate verdict.
Verdict stays HIGH because the single decisive factor is deployment context: Dokan Pro is a marketplace plugin whose business model REQUIRES open customer/vendor self-registration, which reduces the CVSS PR:L authentication requirement to a checkout form. Blast radius is contained to a single WordPress site rather than a shared identity plane, so the floor does not cross into CRITICAL.
Why this verdict
- Auth barrier is theatrical: PR:L in the vector assumes credentials are hard to get. On a marketplace where the plugin's core function is to onboard vendors, an attacker signs up in 30 seconds. Effective attack complexity is unauthenticated-equivalent.
- Role multiplier — line-of-business e-commerce site: chain succeeds; blast radius = full WordPress admin → shell drop, skimmer injection into checkout, customer PII and order data egress. Per-site impact, not identity-plane.
- Role multiplier — headless / staging Dokan instance: chain succeeds but blast radius contained to non-prod data; ~5% of installs.
- Role multiplier — Dokan behind an aggressive WAF with virtual-patch feed (Wordfence Premium, Patchstack): chain blocked within 48h of disclosure; roughly 30–40% of paid Dokan sites carry one of these.
- No fleet-scale pivot: unlike an IdP, DC, or hypervisor bug, one compromised marketplace does not chain to a thousand others. Floor holds at HIGH; not elevated to CRITICAL.
Why not higher?
Not CRITICAL because the affected component is a per-site WordPress plugin — compromise is scoped to a single storefront, not a shared identity/hypervisor plane. The vector still requires an authenticated session, and ~30–40% of paid-tier Dokan sites run behind a virtual-patching WAF that will block the specific endpoint pattern within days.
Why not lower?
Not MEDIUM because the authentication requirement is illusory on the default Dokan deployment model, the endpoint is internet-reachable by design, and the outcome is full WordPress admin (not a scoped info leak or DoS). The historical Wordfence campaign against the 2025 Dokan Pro flaw hit ~15,000 sites — this is a well-worn attack pattern.
What to do — in priority order.
- Deploy virtual patch via Wordfence or Patchstack now — Both vendors ship a REST-endpoint rule for Dokan Pro priv-esc within 24–72 hours of disclosure. Enable the rule in blocking (not learning) mode. Deadline: within 30 days per noisgate mitigation SLA for HIGH — but for internet-facing e-commerce, do this same-day.
- Disable open vendor self-registration temporarily — In
wp-admin → Dokan → Settings → Vendor Registration, uncheck 'Allow customers to register as vendors' and switch new-vendor accounts to require manual admin approval. Kills step 1 of the chain. Deploy today; reverse after patching. - Restrict
/wp-json/dokan/*at the reverse proxy — At Nginx/Cloudflare/ALB, require an allowlistedOriginheader or authenticated session cookie before proxying to/wp-json/dokan/v1/*routes. Blocks scripted exploitation from raw HTTP clients. Deploy within 3 days. - Audit
wp_usermetafor unexpected capability changes — RunSELECT user_id, meta_value FROM wp_usermeta WHERE meta_key='wp_capabilities' AND meta_value LIKE '%administrator%';and cross-reference against your known admin list. Any unknown admin created after 2026-06-15 = assume compromise, rotate all secrets. Do this before patching in case exploitation already happened. - Rotate WordPress secrets and force password reset on all admins — If audit turns up rogue admins, invalidate
wp_userssessions (wp user session destroy --all), regeneratewp-config.phpsalts, and force password reset. Attackers frequently plant secondary backdoors before the primary rogue-admin account is caught.
- 2FA on the admin role — the attacker is not logging into an existing admin; they are elevating THEIR OWN customer/vendor account. 2FA on the admin role does not apply to a fresh self-registered user.
- Generic WordPress hardening plugins (iThemes, Sucuri baseline) — without a specific Dokan REST-endpoint rule, they do not inspect the
update_capabilitiespayload. - Rate-limiting
/wp-login.php— exploitation does not require brute force; the attacker's own valid session is used. - WooCommerce order-level anomaly detection — the attack path does not go through checkout, so fraud rules see nothing.
Crowdsourced verification payload.
Run from your auditor workstation or a CI job with network reach to the target WordPress host. Usage: ./check_dokan.sh https://marketplace.example.com. Requires only curl and grep; no credentials needed for the version probe. Exit codes: 0=PATCHED, 1=VULNERABLE, 2=UNKNOWN.
#!/usr/bin/env bash
# noisgate — CVE-2026-12224 Dokan Pro update_capabilities REST priv-esc check
# Usage: ./check_dokan.sh https://target.example.com
set -u
TARGET="${1:-}"
if [[ -z "$TARGET" ]]; then
echo "Usage: $0 <https://target>" >&2
exit 2
fi
# Strip trailing slash
TARGET="${TARGET%/}"
# 1. Detect Dokan Pro presence via readme or plugin assets
DOKAN_ASSET="$(curl -skL --max-time 10 "$TARGET/wp-content/plugins/dokan-pro/readme.txt" 2>/dev/null)"
if [[ -z "$DOKAN_ASSET" ]]; then
# Fallback: probe REST namespace
NS="$(curl -skL --max-time 10 "$TARGET/wp-json/" | grep -o '"dokan/v[0-9]"' | head -n1)"
if [[ -z "$NS" ]]; then
echo "UNKNOWN: Dokan Pro not detected at $TARGET"
exit 2
fi
fi
# 2. Extract version from readme Stable tag
VER="$(echo "$DOKAN_ASSET" | grep -iE '^Stable tag:|^Version:' | head -n1 | awk -F: '{print $2}' | tr -d ' \r')"
if [[ -z "$VER" ]]; then
echo "UNKNOWN: could not parse Dokan Pro version"
exit 2
fi
# 3. Compare against fixed version (UPDATE this constant when vendor confirms patched release)
FIXED="5.0.3" # placeholder — confirm against https://dokan.co/wordpress/changelog/
ver_lt() {
# returns 0 if $1 < $2
[[ "$1" == "$2" ]] && return 1
local IFS=.
local i a=($1) b=($2)
for ((i=0; i<${#a[@]} || i<${#b[@]}; i++)); do
local x=${a[i]:-0} y=${b[i]:-0}
((x<y)) && return 0
((x>y)) && return 1
done
return 1
}
if ver_lt "$VER" "$FIXED"; then
echo "VULNERABLE: Dokan Pro $VER < $FIXED — CVE-2026-12224"
exit 1
else
echo "PATCHED: Dokan Pro $VER >= $FIXED"
exit 0
fi
If you remember one thing.
wp plugin list --name=dokan-pro --format=json across your fleet). Per the noisgate mitigation SLA for HIGH (≤ 30 days), deploy the Wordfence/Patchstack virtual patch and disable open vendor self-registration TODAY — for any internet-facing marketplace, treat this as a same-day mitigation regardless of the 30-day ceiling because PoCs historically land within a week. Per the noisgate remediation SLA for HIGH (≤ 180 days), roll the vendor-patched Dokan Pro release into staging this week and production within 14 days; do NOT wait 180 days for an internet-facing e-commerce plugin. Before patching, audit wp_usermeta for capability-change anomalies since 2026-06-15 — if you find rogue admins, assume site compromise, rotate salts, force password resets, and hunt for planted plugin webshells.Sources
- Wordfence — 15,000 WordPress Sites Affected by Dokan Pro Priv-Esc (2025 precedent)
- Wordfence Threat Intel — Dokan Pro Vulnerability Feed
- Dokan Official Changelog
- Patchstack Vulnerability Database
- SentinelOne — CVE-2025-5931 Dokan Pro Priv-Esc reference
- Search Engine Journal — Historical Dokan Pro / WooCommerce vulns
- CWE-269 Improper Privilege Management
- Dokan Lite (open-source base) plugin page
What defenders are saying.
Crowdsourced verification outputs.
Results submitted by users who ran the verification payload against their environment.