Back to Intelligence

CVE-2026-15369: Critical Privilege Escalation in Custom User Registration Fields for WooCommerce — Detection and Remediation Guide

SA
Security Arsenal Team
August 29, 2026
10 min read

On March 2026, NVD published CVE-2026-15369, a CVSS 9.8 (CRITICAL) vulnerability in the Custom User Registration Fields for WooCommerce WordPress plugin, affecting all versions up to and including 2.2.3. This is a fully unauthenticated, network-exploitable privilege escalation: any remote attacker who can reach your storefront's WooCommerce Store API can assign themselves an arbitrary WordPress role — including administrator — during checkout.

For defenders, this is the worst-case pattern for a WordPress vulnerability. No credentials required, no user interaction required, and the exploitation pathway runs through a core e-commerce endpoint (/wc/store/v1/checkout) that must remain internet-facing for the business to function. A successful exploit hands the attacker full administrative control of the WordPress instance — which in practice means webshell upload via theme/plugin editors, credential harvesting from the wp_users table, lateral movement into the hosting environment, and a launchpad for skimming payment data from your customers.

If you run WooCommerce with this plugin, treat this as an incident-response-priority patching event, not a routine update.

Technical Analysis

Affected Products and Versions

ComponentDetail
PluginCustom User Registration Fields for WooCommerce (WordPress plugin)
Affected versions2.2.3
CVECVE-2026-15369
CVSS v3.19.8 (CRITICAL) — Vector: Network / Low complexity / No privileges / No user interaction
PlatformWordPress sites running WooCommerce with the Store API (block-based checkout) enabled
Referencehttps://nvd.nist.gov/vuln/detail/CVE-2026-15369

Root Cause and Attack Chain

This is a textbook improper authorization / mass-assignment-style flaw chained across two plugin functions:

  1. Tainted input ingestion. The plugin's af_reg_checkout_data_to_order_meta_data_block() function reads the afreg_select_user_role parameter from the unauthenticated WooCommerce Store API checkout request (POST /wp-json/wc/store/v1/checkout). This parameter is attacker-controlled and is persisted into order metadata without any allowlist validation against the roles the site administrator actually configured for customer self-selection.

  2. Unsafe privilege application. Later, af_reg_custom_order_processing_function() — hooked to the woocommerce_thankyou action — retrieves that stored order meta value and passes it directly to WP_User::add_role(). Because WordPress's role API performs no validation of who requested a role assignment, the attacker-supplied string (e.g., administrator) is applied verbatim to the newly registered account.

Exploitation requirements are trivially met:

  • The site runs WooCommerce with the block-based checkout (Store API) — the default in current WooCommerce releases.
  • The plugin is installed and active at version ≤ 2.2.3.
  • Customer registration at checkout is enabled (common default for stores wanting account creation).
  • The attacker places a low-cost or zero-cost order (or triggers the thankyou hook flow) with a crafted afreg_select_user_role: administrator field in the checkout payload.

The result: a fresh account with the administrator role, a known password the attacker chose at registration, and a valid session on your admin panel.

Exploitation Status

At the time of writing, NVD has published the CVE with full technical detail, which materially lowers the bar for weaponization — the vulnerable functions and hook names are public. WordPress plugin vulnerabilities of this class (unauthenticated privilege escalation in WooCommerce ecosystem plugins) historically move from disclosure to mass scanning and in-the-wild exploitation within days, driven by botnets that enumerate plugin slugs via readme.txt and wp-content paths. Defenders should operate on the assumption that exploitation attempts are imminent or already occurring, even if CISA KEV inclusion has not yet been confirmed. Monitor the KEV catalog and your WAF telemetry accordingly.

Detection & Response

Detection strategy centers on three observables: (1) HTTP requests to the Store API checkout endpoint carrying the malicious parameter, (2) unexpected role assignments / new administrator accounts in WordPress, and (3) post-exploitation artifacts on the web server (webshells in wp-content, modified plugin/theme files).

SIGMA Rules

YAML
---
title: WooCommerce Store API Checkout Role Injection Attempt (CVE-2026-15369)
id: 3f8c1a92-7b4e-4d21-9f6a-2c5e8b1d9047
status: experimental
description: Detects HTTP requests to the WooCommerce Store API checkout endpoint containing the afreg_select_user_role parameter, indicative of exploitation of CVE-2026-15369 unauthenticated privilege escalation in Custom User Registration Fields for WooCommerce <= 2.2.3. Requires request body or query logging via WAF, ModSecurity, or reverse proxy.
references:
  - https://nvd.nist.gov/vuln/detail/CVE-2026-15369
author: Security Arsenal
date: 2026/03/10
tags:
  - attack.privilege_escalation
  - attack.t1068
  - attack.initial_access
  - attack.t1190
logsource:
  category: webserver
detection:
  selection_param:
    cs-uri-query|contains: 'afreg_select_user_role'
  selection_body:
    RequestBody|contains: 'afreg_select_user_role'
  selection_waf:
    MatchedData|contains: 'afreg_select_user_role'
  condition: 1 of selection_*
falsepositives:
  - Legitimate customer role selection where the site administrator has intentionally configured selectable registration roles (verify role values are restricted to non-privileged roles such as customer/subscriber)
level: high
---
title: High-Volume Checkout Requests to WooCommerce Store API Endpoint
id: 8a2d5f47-1c93-4b68-ae25-7f3d9c0b6158
status: experimental
description: Detects POST requests to the unauthenticated WooCommerce Store API checkout endpoint, the exploitation pathway for CVE-2026-15369. Intended as a hunting rule where request body logging is unavailable; a single source IP issuing repeated checkout POSTs warrants investigation for role-injection probing.
references:
  - https://nvd.nist.gov/vuln/detail/CVE-2026-15369
author: Security Arsenal
date: 2026/03/10
tags:
  - attack.initial_access
  - attack.t1190
logsource:
  category: webserver
detection:
  selection:
    cs-method: 'POST'
    cs-uri|contains:
      - '/wp-json/wc/store/v1/checkout'
      - '/?rest_route=/wc/store/v1/checkout'
falsepositives:
  - Normal customer checkout activity - this rule is intended for threat hunting and correlation with new administrator account creation, not standalone alerting
level: low
---
title: WordPress Plugin or Theme File Modification in wp-content
id: c61e7b34-5d28-4f90-b834-1a6c2e9d5370
status: experimental
description: Detects creation or modification of PHP files within the WordPress wp-content directory by web server processes, a common post-exploitation behavior following administrator-level compromise via CVE-2026-15369 (webshell deployment through theme/plugin editors).
references:
  - https://nvd.nist.gov/vuln/detail/CVE-2026-15369
  - https://attack.mitre.org/techniques/T1505/003/
author: Security Arsenal
date: 2026/03/10
tags:
  - attack.persistence
  - attack.t1505.003
logsource:
  category: file_event
  product: linux
detection:
  selection:
    TargetFilename|contains:
      - '/wp-content/themes/'
      - '/wp-content/plugins/'
      - '/wp-content/uploads/'
    TargetFilename|endswith: '.php'
falsepositives:
  - Legitimate plugin/theme updates and deployments - correlate with change windows and administrator account creation events
level: medium

KQL (Microsoft Sentinel / Defender)

This query hunts web access logs ingested into Sentinel (via CEF/Syslog from your WAF, reverse proxy, or web server) for POSTs to the vulnerable checkout endpoint, then correlates with any evidence of the injected role parameter. Run it over at least the last 30 days — and retroactively across any window where plugin version ≤ 2.2.3 was installed.

KQL — Microsoft Sentinel / Defender
// Hunt for CVE-2026-15369 exploitation attempts against WooCommerce Store API
let lookback = 30d;
let CheckoutPosts =
    CommonSecurityLog
    | where TimeGenerated > ago(lookback)
    | where RequestMethod =~ "POST"
    | where RequestURL has_any ("/wp-json/wc/store/v1/checkout", "rest_route=/wc/store/v1/checkout")
    | project TimeGenerated, SourceIP, RequestURL, RequestMethod, DeviceAction, SourceUserAgent;
CheckoutPosts
| summarize CheckoutAttempts = count(), DistinctDays = dcount(startofday(TimeGenerated)), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated) by SourceIP, SourceUserAgent
| where CheckoutAttempts > 5 or DistinctDays > 1
| sort by CheckoutAttempts desc;
// Follow-up: any request (query or body, if logged by WAF) containing the role-injection parameter
union isfuzzy=true
    (CommonSecurityLog
    | where TimeGenerated > ago(lookback)
    | where RequestURL has "afreg_select_user_role" or AdditionalExtensions has "afreg_select_user_role"
    | project TimeGenerated, SourceIP, RequestURL, RequestMethod, AdditionalExtensions),
    (Syslog
    | where TimeGenerated > ago(lookback)
    | where SyslogMessage has "afreg_select_user_role"
    | project TimeGenerated, HostIP, SyslogMessage)
| sort by TimeGenerated desc

Velociraptor VQL

Use this artifact on the web server to (a) identify the installed plugin version from its readme.txt, and (b) sweep wp-content for recently modified PHP files — a strong post-exploitation indicator after an admin-level compromise.

VQL — Velociraptor
-- CVE-2026-15369: Identify vulnerable plugin version and recently modified wp-content PHP files
LET plugin_readme <= SELECT FullPath, Mtime
FROM glob(globs='/**/wp-content/plugins/custom-user-registration-fields-for-woocommerce/readme.txt')

SELECT 'PLUGIN_VERSION_CHECK' AS Check,
       FullPath,
       Mtime,
       read_file(filename=FullPath, length=2000) AS ReadmeHead
FROM plugin_readme

UNION ALL

SELECT 'RECENT_PHP_MODIFICATION' AS Check,
       FullPath,
       Mtime,
       NULL AS ReadmeHead
FROM glob(globs='/**/wp-content/**/*.php')
WHERE Mtime > timestamp(epoch=atoi(string=now()) - 604800)
ORDER BY Mtime DESC

Note: the plugin directory slug may vary by installation source — adjust the glob if your deployment uses a different folder name, and confirm the actual role assignment by reviewing the wp_usermeta table for wp_capabilities entries containing administrator that do not correspond to known admin accounts.

Remediation / Verification Script

Run the following Bash script on your WordPress hosting server (adjust WP_PATH for your docroot). It checks the installed plugin version, enumerates administrator accounts via WP-CLI, and greps web access logs for exploitation indicators.

Bash / Shell
#!/bin/bash
# CVE-2026-15369 verification and triage script
WP_PATH="/var/www/html"
PLUGIN_DIR="$WP_PATH/wp-content/plugins/custom-user-registration-fields-for-woocommerce"

# 1. Check installed plugin version from readme.txt
if [ -f "$PLUGIN_DIR/readme.txt" ]; then
  echo "[+] Plugin readme found. Stable tag:"
  grep -i "Stable tag" "$PLUGIN_DIR/readme.txt"
else
  echo "[-] Plugin not found at expected path (verify slug: ls $WP_PATH/wp-content/plugins/)"
fi

# 2. Enumerate all administrator accounts via WP-CLI (run as web user if needed)
echo "[+] Current administrator accounts:"
wp --path="$WP_PATH" user list --role=administrator --fields=ID,user_login,user_email,user_registered --allow-root

# 3. Search web access logs for exploitation indicators (last 14 days of logs)
echo "[+] Searching access logs for afreg_select_user_role parameter..."
grep -h "afreg_select_user_role" /var/log/nginx/access.log* /var/log/apache2/access.log* 2>/dev/null | tail -50

echo "[+] Searching access logs for checkout endpoint POSTs..."
grep -hE "POST .*wc/store/v1/checkout" /var/log/nginx/access.log* /var/log/apache2/access.log* 2>/dev/null | awk '{print $1}' | sort | uniq -c | sort -rn | head -20

# 4. Find PHP files in wp-content modified in the last 7 days (post-exploitation sweep)
echo "[+] Recently modified PHP files under wp-content (7 days):"
find "$WP_PATH/wp-content" -name "*.php" -mtime -7 -printf '%T+ %p\n' 2>/dev/null | sort -r | head -30

If the script returns administrator accounts you cannot attribute, or log hits containing afreg_select_user_role with privileged role values (administrator, editor, shop_manager), treat the host as compromised: isolate it, preserve logs and the database for forensics, rotate all credentials (WordPress salts, wp-config.php DB credentials, API keys), and rebuild from a known-clean backup.

Remediation

  1. Update the plugin immediately. Upgrade Custom User Registration Fields for WooCommerce to a version newer than 2.2.3 as soon as the vendor patch is available. Verify the update via WordPress Admin → Plugins or wp plugin update <slug>. Confirm the fixed version number against the vendor's changelog and the WordPress.org plugin page before deploying.

  2. If no patched version is available yet, deactivate the plugin. Given CVSS 9.8 and unauthenticated exploitation with no viable configuration workaround — the vulnerable code path executes on a core checkout hook — deactivation is the only reliable mitigation short of patching. If the registration-fields functionality is business-critical, place a WAF rule in front of the site that blocks any request to /wp-json/wc/store/v1/checkout (and the ?rest_route= equivalent) containing the string afreg_select_user_role, and alert on every match.

  3. Audit for compromise — do not assume patching erases the damage. Patching stops future exploitation; it does nothing about administrator accounts already created. Audit:

    • wp_usermeta for wp_capabilities meta values granting administrator, editor, or shop_manager to unexpected users
    • WooCommerce order meta for stored afreg_select_user_role values outside your configured registration roles
    • Web access logs (retroactively, across the full period the vulnerable version was live) for the indicators in the script above
    • wp-content for unauthorized PHP modifications and webshells
  4. Rotate secrets after any confirmed or suspected exploitation. WordPress authentication salts/keys in wp-config.php (invalidates all sessions), database credentials, admin passwords, WooCommerce/Stripe/PayPal API keys, and any SMTP credentials stored in the database.

  5. Harden the WordPress attack surface going forward. Disable the theme/plugin file editor (define('DISALLOW_FILE_EDIT', true);), enforce MFA on all administrator accounts, restrict /wp-admin by IP where operationally feasible, and subscribe to plugin vulnerability feeds (Patchstack, Wordfence Intelligence, WPScan) so the next plugin CVE reaches you before the scanners do.

  6. Monitor CISA KEV. Track https://www.cisa.gov/known-exploited-vulnerabilities-catalog for CVE-2026-15369 inclusion, which would trigger binding remediation deadlines for federal agencies and should serve as an escalation trigger for everyone else.

WordPress plugin privilege escalations of this severity are exactly the vulnerabilities that automated exploit botnets operationalize first. The window between public disclosure and mass exploitation is measured in days. Patch or deactivate today, hunt retroactively, and validate that your administrator roster is exactly who you think it is.

Related Resources

Security Arsenal Penetration Testing Services AlertMonitor Platform Book a SOC Assessment vulnerability-management Intel Hub

Is your security operations ready?

Get a free SOC assessment or see how AlertMonitor cuts through alert noise with automated triage.