Back to Blog
Insights

CVE-2026-9055: Unauthenticated Admin Takeover in the Amelia Booking Plugin

CVE-2026-9055: Unauthenticated Admin Takeover in the Amelia Booking Plugin

Amelia — the Booking for Appointments and Events Calendar plugin — runs the appointment books of tens of thousands of salons, clinics, gyms and studios: customer names, phone numbers, appointment histories, and payment-gateway credentials for Stripe, PayPal, Mollie and Square behind one admin login. Until 9.6.3, a complete stranger could become that admin without a credential.

That is CVE-2026-9055 — CVSS 9.8, no authentication, and a two-step ladder from booking customer to administrator. It is also the second time this plugin has appeared in our disclosure history: our Principal Consultant disclosed CVE-2024-1484, a reflected XSS in Amelia, in March 2024. This one is a different class of problem, and more serious.

What it is

FieldValue
CVECVE-2026-9055
CVSS v3.19.8 CriticalAV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
EPSS0.3% — low for now, but the model lags a fresh disclosure
ClassCWE-269 — improper privilege management
AuthenticationNone — reachable through customer self-service endpoints
AffectedAmelia Premium 8.0 – 9.6.2
Fixed in9.6.3 (7 July 2026) — update to 9.8.2 or later
Reported byResearcher "d.v4n_s3c", via Wordfence
RecordNVD — CVE-2026-9055 · CVE.org

Are you affected?

Read the version window carefully, because it is narrower than most CVEs and that matters for triage:

  • Premium, not Lite. The affected product is the commercial Amelia plugin. The free Lite distribution on WordPress.org is a separate product line — check which one you actually run.
  • 8.0 through 9.6.2. Unlike the usual "all versions ever shipped" range, this bug arrived with code introduced in 8.0. Sites on 7.x were never exposed to it; sites on 9.6.3+ are already fixed.

If you run Amelia Premium and cannot say which version, assume you are affected until you check — this is a paid plugin with no auto-update channel, and booking plugins are exactly the kind of thing that gets installed once and forgotten.

How the bug works

The chain is a ladder with two rungs, and both rungs are the same design mistake: Amelia lets the client tell the server who it is.

Rung one: the role flip

Amelia keeps its own cast of entities — customers, managers (providers), admins — and shadows them into WordPress users with plugin-specific roles like wpamelia-manager. Its customer-update endpoint is reachable without authentication, because booking flows have to serve anonymous visitors.

That endpoint accepts a type parameter — which entity type this record is — and trusts it. Set type to manager and externalId to 0 (no linked WordPress user yet), and the plugin dutifully provisions a real WordPress account with the wpamelia-manager role. The attacker now holds manager-level access to Amelia's endpoints.

Rung two: the provider trick

Managers may manage providers — the staff entities that bookings are assigned to. A provider can be linked to an existing WordPress user by ID, and a provider's password can be set.

So the attacker creates a provider entity with externalId pointing at a genuine administrator's WordPress user ID and sets a password. The plugin writes that password onto the linked account. The attacker now logs into /wp-admin as the site's administrator.

Anonymous request ──► customer-update endpoint
        │
        ├── type: "manager"        (attacker-chosen entity type)
        └── externalId: 0          (no linked user → provision one)
        ▼
New WP user with wpamelia-manager role
        │
        ▼
Manager endpoint ──► create provider entity
        │
        ├── externalId: <admin's WP user ID>
        └── password: <attacker-chosen>
        ▼
Plugin overwrites the administrator's password
        │
        ▼
Attacker logs in as administrator

The bug is not one bad check. It is two role systems that disagree. Amelia's internal entity model (customer/manager/admin) shadows WordPress's real role model (subscriber/editor/administrator), and the bridge between them — the externalId link — is writable from client input. A plugin-internal "manager" is not a WordPress administrator, but the password-write path never re-asks WordPress what the acting user may do.

Once an administrator account falls, the site is gone in the ways that matter: database credentials from wp-config.php, persistence that survives plugin updates, and — specific to this plugin — the stored API keys for every payment and calendar integration the business runs on.

Is it being exploited?

Not that anyone can see. CISA's SSVC assessment records exploitation: none, with automatable: yes and technical impact: total. EPSS sits at 0.3%.

Two cautions. The technique is now public and needs no authentication — the exploit is a script, not a skill. And the affected population is self-selecting for value: businesses that take bookings are businesses that hold customer PII and payment integrations. A smaller install base than a freemium plugin, but a richer one per hit.

The disclosure timeline was long, and the shape is worth noting:

DateEvent
20 May 2026Vendor notified; CVE reserved
7 July 2026Amelia 9.6.3 released — "Resolved a security vulnerability"
1 September 2026Public disclosure
2 September 2026CVE published

Forty-eight days from notification to patch. Then eight more weeks of silence before the public disclosure — time in which an unpatched site had a fixed door available and no way of knowing it mattered.

One more pattern deserves an honest mention. Scan the Amelia changelog for 2026 and count the lines that read "Resolved a security vulnerability" or "Resolved security vulnerabilities": 9.5, 9.5.1, 9.6.2, 9.6.3, 9.7, 9.8, 9.8.1, 9.8.2 — eight releases, eight security-fix entries, in under five months. Credit to the vendor for shipping fixes steadily and saying so. But that cadence is also a signal about attack surface: a booking plugin that has grown into payments, calendars, video meetings, WhatsApp, AI assistants and an API is a great deal of software wearing a plugin's clothing. If you run it, patching is not optional hygiene — it is the entire security model.

What to do today

  1. Update Amelia to 9.8.2 or later. At minimum 9.6.3 closes this bug; 9.8.2 (9 September) closes several others disclosed since.
  2. Audit your users table for plugin roles and accounts you did not create. One query catches every Amelia-provisioned account, whatever role slug it carries:
wp db query "SELECT u.ID, u.user_login, u.user_email, u.user_registered
FROM $(wp db prefix)users u
JOIN $(wp db prefix)usermeta m ON u.ID = m.user_id
WHERE m.meta_key = 'wp_capabilities' AND m.meta_value LIKE '%wpamelia%';"

wp user list --role=administrator --fields=ID,user_login,user_email,user_registered

A wpamelia-* account nobody remembers creating, or an administrator whose user_registered date does not match your history, is not noise — on an affected version it is the exploit's footprint.

  1. If you were running an affected version, rotate the secrets the panel can reach: payment-gateway API keys (Stripe, PayPal, Mollie, Square, Razorpay, Barion), Google/Outlook calendar tokens, Zoom credentials, and the SMTP credentials Amelia uses for notifications. Password-reset every administrator account.
  2. Review Amelia's provider entities against WordPress user IDs — a provider linked to an admin account you did not configure is the second rung of this exact ladder.

That response checklist, run completely and calmly, is what SOC as a service is for — the compromise to assume here is quiet, and the logs a business checks on its own rarely reach back far enough.

The broader point

WordPress plugins that create users or write to the users table are touching the most sensitive state the platform has. Done right, that is legitimate — booking and membership plugins must bridge anonymous visitors into accounts. Done carelessly, you get this: an internal role model that shadows the real one, a client-writable bridge between them, and a password path that forgets to ask WordPress for permission.

This is the same family of failure as CVE-2026-78159 in The Events Calendar — a trusted internal concept (a widget instance there, an entity type here) that unauthenticated input reaches unreviewed. Finding those paths before an attacker does is the job of an application penetration test, and it is why we attack every site we build before launch — see secure web development, or talk to us if you would rather have someone check your booking plugin before someone else does.

Get Started

Want a security-first build?

Get a free security review. We'll look at where you stand today and tell you what to fix first — no strings attached.

Talk to an Expert
CVE-2026-9055: Unauthenticated Admin Takeover in the Amelia Booking Plugin — IKZERO