Automated Threat Modeling

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

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

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 lets any Editor level user hijack Administrator accounts with a single AJAX request, turning a common content management role into full site control. With over 10,000 active installations, the flaw reaches a meaningful slice of small and medium business WordPress deployments that use 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 inside WordPress. It has been available since February 2018 and is marketed as a free solution with premium features, aimed at businesses that need booking 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. It affects versions up to and including 1.7.16 of the Booking Package plugin.

Root Cause: Three Layers of Missing Authorization

The vulnerability comes from three connected failures in the plugin's authorization architecture. Each layer trusts the one above it without doing its own validation, which leaves defense in depth broken all the way down.

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 creates a booking_package_schedule object and reads the $_POST['action'] parameter to decide which method to call. At this point the handler checks only a WordPress nonce. It never checks whether the requesting user has the edit_users capability or any privilege beyond basic authentication.

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

The dispatcher at line 4477 runs a dynamic method call using the client controlled $_POST['action'] value. When action=updateUser is supplied, the request routes straight to Schedule::updateUser(). There is no whitelist of permitted actions, no role verification, and no call to current_user_can() before the dispatch happens. 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 takes a $data array (containing the target user ID, email, password, and role) along with an $administrator boolean parameter. That $administrator parameter is the only authorization gate inside the function: when it is true, the function skips its owner restriction check and passes every supplied field, including role, straight to wp_update_user().

The critical flaw is that the dispatcher hard codes $administrator to 1 when it calls this function. The authorization gate is therefore always open, no matter what privileges the requesting user actually holds. The target user is chosen entirely from attacker supplied input.

Attack Flow

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

  1. The attacker authenticates to WordPress with an Editor account and gets a valid nonce for the package_app_action AJAX endpoint.
  2. The attacker finds 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 these 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 calls Schedule::updateUser() with $administrator = 1, skipping 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 here the attacker has full control of the WordPress installation. They can install plugins, modify themes, create more accounts, reach the database through plugins like WP DB Manager, or pivot to the hosting environment.

Why the Nonce Check Is Insufficient

It is a common mistake to think WordPress nonce verification provides authorization. It does not. Nonces verify intent and protect against CSRF attacks, but they do not verify that the user can perform the requested action. An Editor level user holds a valid nonce for AJAX endpoints registered via wp_ajax_* hooks, which is enough 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 flaw 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 flaw (CVE-2024-30516) was reported by researcher Abdi Pranata through Patchstack and published in March 2024. Both bugs involve weak authorization and input validation, which suggests the plugin's development process does not include systematic security review of its AJAX surface and authorization patterns. Organizations that rely on this plugin should weigh that track record when they make risk decisions.

References

Detect & fix
what others miss

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