Introduction
A missing authorization check on a single field in the Amelia WordPress booking plugin gives any Employee-level user a direct path to full Administrator account takeover. The plugin has over 90,000 active installations, and exploitation is trivial, with no special tooling required. WordPress administrators running multi-provider booking setups should address CVE-2026-5465 without delay.
The Booking for Appointments and Events Calendar, known as Amelia, is a popular WordPress plugin that handles appointment scheduling, event booking, and calendar management for service-based businesses. Its users span a broad range of industries, including salons, clinics, and consulting firms. The 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 is in the UpdateProviderCommandHandler class, in the way it processes profile update requests from Provider (Employee) users. The handler merges every user-submitted field into the updated user object with array_merge($oldUser->toArray(), $providerData) and never restricts which fields a non-admin user may modify.
One of the merged fields is externalId, which maps directly to a WordPress user ID. It is used for more than display. The handler later passes it to 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.
No server-side check stops a non-admin user from changing their externalId to an arbitrary value, so the entire chain, from field submission to execution of privileged WordPress functions, 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 starts a profile update request through the Amelia plugin interface. The request hits the
UpdateProviderControllerat line 30, which delegates to theUpdateProviderCommandHandler. - The attacker intercepts the outgoing HTTP request (with a proxy or browser developer tools) and changes 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 puts their chosen new password in the request payload.
- The
UpdateProviderCommandHandlermerges the submitted data with the existing provider record viaarray_merge()and accepts the attacker-suppliedexternalIdwithout question. - The handler calls
wp_set_password()with the attacker's password and the injectedexternalId(the Administrator's WordPress user ID), which resets the Administrator's password. - The handler calls
wp_update_user()with the injectedexternalId, which may also overwrite the Administrator's email and other profile fields. - The attacker logs in as the Administrator with the new 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) is accurate for a flaw with a low barrier to entry that ends in total site compromise when the attack succeeds.
Patch information
The vendor fixed 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 adds a targeted authorization guard right after the UserFactory::create($newUserData) call, which builds the new user entity from the merged data:
$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; }
The guard compares the externalId already stored on the existing provider record ($oldExternalId) with the externalId in the incoming update request ($newExternalId). A mismatch means someone tried to change which WordPress user the provider is linked to. If that happens and the logged-in user is not an Administrator, the handler returns an error and stops, so a tampered externalId never reaches the downstream wp_set_password() or wp_update_user() calls.
The check sits after all field merging has happened but before any privileged WordPress operation runs, which makes it a final gate. With the patch, only Administrators can reassign the externalId mapping, and that 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 through the standard WordPress plugin update mechanism. After updating, confirm in the WordPress plugin dashboard that the active version shows 2.2. You can review the patched source in the version 2.2 tag.
Affected systems and versions
Every version of the Booking for Appointments and Events Calendar, Amelia plugin for WordPress, from the initial release through version 2.1.3 (inclusive), is vulnerable. Version 2.2 contains the fix.
Organizations should patch first wherever third-party users, contractors, or lower-privileged staff hold Provider or Employee roles in Amelia. Those accounts have exactly the access the exploit requires.
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)



