ZeroPath at Black Hat USA 2026

Brief Summary: CVE-2026-9851 Privilege Escalation in WordPress Booking Package Plugin via Account Takeover

A short review of CVE-2026-9851, a high severity privilege escalation vulnerability in the WordPress Booking Package plugin that allows Editor level users to take over Administrator accounts through a missing capability check on an AJAX endpoint.

CVE Analysis

7 min read

ZeroPath CVE Analysis
ZeroPath CVE Analysis

2026-06-05

Brief Summary: CVE-2026-9851 Privilege Escalation in WordPress Booking Package Plugin via Account Takeover
Experimental AI-Generated Content

This CVE analysis is an experimental publication that is completely AI-generated. The content may contain errors or inaccuracies and is subject to change as more information becomes available. We are continuously refining our process.

If you have feedback, questions, or notice any errors, please reach out to us.

[email protected]

Introduction

A missing capability check in the WordPress Booking Package plugin allows any Editor level user to hijack Administrator accounts with a single AJAX request, converting a common content management role into full site control. With over 10,000 active installations, this vulnerability affects a meaningful slice of small to medium business WordPress deployments that rely on the plugin for appointment booking, room rental, and event scheduling.

The Booking Package plugin, developed by SAASPROJECT (masaakitanaka on WordPress.org), provides online reservation and scheduling functionality directly within WordPress. It has been available since February 2018 and positions itself as a free solution with premium features, serving businesses that need booking capabilities without custom development.

Technical Information

CVE-2026-9851 is classified under CWE-639 (Authorization Bypass Through User-Controlled Key) and carries a CVSS v3.1 score of 7.2 with the vector CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:H. The vulnerability affects versions up to and including 1.7.16 of the Booking Package plugin.

Root Cause: Three Layers of Missing Authorization

The vulnerability is the result of three interconnected failures in the plugin's authorization architecture. Each layer trusts the layer above it without performing independent validation, creating a complete defense in depth failure.

Layer 1: AJAX Entry Point (index.php, line 4416)

The package_app_action AJAX endpoint is registered for authenticated WordPress users. When a request arrives, the handler instantiates a booking_package_schedule object and reads the $_POST['action'] parameter to determine which method to invoke. At this stage, the handler validates only a WordPress nonce. It performs no capability check to verify whether the requesting user has the edit_users capability or any other privilege beyond basic authentication.

Layer 2: Unsafe Dynamic Dispatch (index.php, line 4477)

The dispatcher at line 4477 executes a dynamic method call using the client controlled $_POST['action'] value. When action=updateUser is supplied, the request routes directly to Schedule::updateUser(). There is no whitelist of permitted actions, no role verification, and no call to current_user_can() before this dispatch occurs. Any authenticated user who can reach the AJAX endpoint can invoke any method the dispatcher supports.

Layer 3: Hard Coded Authorization Bypass (Schedule.php, line 868)

The Schedule::updateUser() function accepts a $data array (containing the target user ID, email, password, and role) along with an $administrator boolean parameter. This $administrator parameter is the sole authorization gate inside the function: when it evaluates to true, the function bypasses its owner restriction check and passes all supplied fields, including role, directly to wp_update_user().

The critical flaw is that the dispatcher hard codes $administrator to 1 when calling this function. This means the authorization gate is always open, regardless of the actual privileges of the requesting user. The target user is determined entirely by attacker supplied input.

Attack Flow

An authenticated attacker with Editor level access exploits this vulnerability through the following sequence:

  1. The attacker authenticates to WordPress with an Editor account and obtains a valid nonce for the package_app_action AJAX endpoint.
  2. The attacker identifies the target Administrator's user ID (often user ID 1 on default WordPress installations, or discoverable through author archives and the REST API).
  3. The attacker sends a single POST request to wp-admin/admin-ajax.php with the following parameters:
FieldValuePurpose
action (WordPress routing)package_app_actionRoutes to the plugin's AJAX handler
action (plugin routing)updateUserRoutes to Schedule::updateUser()
user_idTarget Administrator's IDSelects the victim account
user_emailAttacker controlled emailOverwrites the victim's email
user_passAttacker chosen passwordOverwrites the victim's password
  1. The dispatcher invokes Schedule::updateUser() with $administrator = 1, bypassing the owner restriction check.
  2. The function calls wp_update_user() with the attacker supplied data, changing the Administrator's email and password.
  3. The attacker logs in as the Administrator using the new credentials.

From this point, the attacker has full control of the WordPress installation: they can install plugins, modify themes, create additional accounts, access the database through plugins like WP DB Manager, or pivot to the hosting environment.

Why the Nonce Check Is Insufficient

A common misconception is that WordPress nonce verification provides authorization. It does not. Nonces in WordPress verify intent and protect against CSRF attacks, but they do not verify that the user has the capability to perform the requested action. An Editor level user will have a valid nonce for AJAX endpoints registered via wp_ajax_* hooks, which is sufficient to pass the nonce check in this handler. The missing piece is a current_user_can() check, which is what the patch in version 1.7.17 adds.

Affected Systems and Versions

Version RangeStatus
All versions up to and including 1.7.16Vulnerable
Version 1.7.17Patched

The vulnerability affects any WordPress installation running the Booking Package plugin at version 1.7.16 or earlier where at least one user has Editor level access or above. The plugin is compatible with WordPress 3.5 and higher, tested up to WordPress 7.0.

Vendor Security History

The Booking Package plugin has a documented pattern of security vulnerabilities:

CVEAffected VersionsPatched VersionTypeCVSS
CVE-2024-30516<= 1.6.271.6.29Price Manipulation7.5
CVE-2026-9851<= 1.7.161.7.17Privilege Escalation (CWE-639)7.2

The price manipulation vulnerability (CVE-2024-30516) was reported by researcher Abdi Pranata through Patchstack and published in March 2024. Both vulnerabilities involve insufficient authorization and input validation, suggesting that the plugin's development process does not include systematic security review of its AJAX surface and authorization patterns. Organizations relying on this plugin should weigh this track record when making risk decisions.

References

Detect & fix
what others miss

Works with
  • GitHub
  • GitLab
  • Bitbucket
  • Azure DevOps Services
  • Jira
  • Linear
  • Slack
  • Security Compass
Security magnifying glass visualization