Introduction
A missing authorization check in a single field of the Amelia WordPress booking plugin gives any Employee level user a direct path to full Administrator account takeover. With over 90,000 active installations and a trivial exploitation path requiring no special tooling, CVE-2026-5465 is a vulnerability that WordPress administrators running multi provider booking setups should address without delay.
The Booking for Appointments and Events Calendar, known as Amelia, is a popular WordPress plugin that provides appointment scheduling, event booking, and calendar management for service based businesses. With over 90,000 active installations, it serves a broad range of industries from salons and clinics to consulting firms. Its role based access model includes Provider (Employee) accounts, which are often assigned to staff or contractors who manage their own schedules through the WordPress backend.
Technical Information
Root Cause: Authorization Bypass via User Controlled Key (CWE-639)
The vulnerability resides in the UpdateProviderCommandHandler class, specifically in how it processes profile update requests from Provider (Employee) users. The core issue is that the handler merges all user submitted fields into the updated user object using array_merge($oldUser->toArray(), $providerData) without restricting which fields a non-admin user is permitted to modify.
Among the merged fields is externalId, which directly maps to a WordPress user ID. This field is not merely a display value; it is subsequently consumed by two critical WordPress core functions:
wp_set_password()at line 219, which sets the password for the WordPress user identified byexternalId.wp_update_user()at line 239, which updates the profile details (email, name, etc.) of the WordPress user identified byexternalId.
Because no server side check exists to prevent a non-admin user from changing their externalId to any arbitrary value, the entire chain from field submission to privileged WordPress function execution is unguarded.
Attack Flow
The exploitation path is straightforward:
- The attacker authenticates to WordPress with a Provider (Employee) account. This is the minimum privilege level required.
- The attacker initiates a profile update request through the Amelia plugin interface. This request hits the
UpdateProviderControllerat line 30, which delegates to theUpdateProviderCommandHandler. - The attacker intercepts the outgoing HTTP request (using a proxy or browser developer tools) and modifies the
externalIdparameter in the request body to the WordPress user ID of the target account. For example, user ID1is typically the site's original Administrator. - The attacker also includes their desired new password in the request payload.
- The
UpdateProviderCommandHandlermerges the submitted data with the existing provider record viaarray_merge(), accepting the attacker suppliedexternalIdwithout question. - The handler calls
wp_set_password()with the attacker's chosen password and the injectedexternalId(the Administrator's WordPress user ID), effectively resetting the Administrator's password. - The handler calls
wp_update_user()with the injectedexternalId, potentially overwriting the Administrator's email and other profile fields. - The attacker logs in as the Administrator using the newly set password.
CVSS 3.1 Breakdown
| Metric | Value | Implication |
|---|---|---|
| Attack Vector | Network | Exploitable remotely over the internet |
| Attack Complexity | Low | No advanced techniques or race conditions required |
| Privileges Required | Low | Requires only basic Employee or Provider access |
| User Interaction | None | No victim action needed |
| Confidentiality Impact | High | Full access to all site data |
| Integrity Impact | High | Complete control over site content and configuration |
| Availability Impact | High | Attacker can lock out legitimate administrators |
The overall score of 8.8 (High) accurately reflects the combination of low barrier to entry and total site compromise on success.
Patch Information
The vendor addressed CVE-2026-5465 in version 2.2 of the Amelia plugin. The fix is tracked in the WordPress plugin repository under changeset 3499608.
The patch introduces a targeted authorization guard immediately after the new user entity is constructed from the merged data. The following block was added right after the UserFactory::create($newUserData) call:
$oldExternalId = $oldUser->getExternalId() ? $oldUser->getExternalId()->getValue() : null; $newExternalId = $newUser->getExternalId() ? $newUser->getExternalId()->getValue() : null; if ($oldExternalId !== $newExternalId && (!$currentUser || $currentUser->getType() !== AbstractUser::USER_ROLE_ADMIN)) { $result->setResult(CommandResult::RESULT_ERROR); $result->setMessage('Could not update user.'); return $result; }
This code compares the externalId already stored on the existing provider record ($oldExternalId) against the externalId value present in the incoming update request ($newExternalId). If the two values differ, meaning someone attempted to switch which WordPress user this provider is linked to, and the currently logged in user is not an Administrator, the handler immediately returns an error and halts execution. This prevents the tampered externalId from ever reaching the downstream wp_set_password() or wp_update_user() calls.
The placement of this fix is notable: it acts as a final gatekeeper after all field merging has already occurred but before any privileged WordPress operations execute. Only Administrators are permitted to reassign the externalId mapping, which is the correct authorization model. Employees should never be able to re-link their Amelia provider profile to a different WordPress account.
To apply the fix, update to Amelia version 2.2 or later via the standard WordPress plugin update mechanism. After updating, verify that the active version reflects 2.2 in the WordPress plugin dashboard. The patched source can be reviewed directly in the version 2.2 tag.
Affected Systems and Versions
All versions of the Booking for Appointments and Events Calendar, Amelia plugin for WordPress from the initial release through version 2.1.3 (inclusive) are vulnerable. The fix was introduced in version 2.2.
Organizations should prioritize patching systems where third party users, contractors, or lower privileged staff hold Provider or Employee roles within the Amelia system, as these accounts possess the exact prerequisites needed to exploit the vulnerability.
References
- Wordfence Advisory: Amelia <= 2.1.3 IDOR Privilege Escalation
- Wordfence Vulnerability Detail Page
- CVE Record: CVE-2026-5465
- NVD Entry: CVE-2026-5465
- Amelia Plugin on WordPress.org
- Vulnerable UpdateProviderCommandHandler.php (v2.1.3)
- Vulnerable Code: Line 146
- Vulnerable Code: Line 219 (wp_set_password)
- Vulnerable Code: Line 239 (wp_update_user)
- UpdateProviderController.php Entry Point
- Changeset 3499608: Patch Commit
- Patched UpdateProviderCommandHandler.php (v2.2)
- Amelia v2.2 Readme
- Vulnerable Source (SVN, v2.1.3)



