CVE-2026-48088
CriticalCVSS 9.4Exploitation Probability (EPSS)
Low risk30th percentile - higher than 30% of all known CVEs
Summary
Prior to version 1.0.4, OpenReception's appointment booking software allowed unauthenticated attackers to store attacker-controlled ML-KEM-768 public keys for any tenant without authentication. The POST /api/tenants/{tenantId}/staff/{staffId}/crypto route logged a warning but still inserted the row, and a variant with omitted email field suppressed the warning entirely. This breaks the end-to-end encryption claim, as the attacker becomes an additional encryption recipient for future patient appointments.
Risk Assessment
The organization risks exposure of sensitive medical data: an unauthenticated attacker can decrypt appointment content for bookings where they were added as a key recipient. Additionally, weak key validation allows poisoning the staff directory, potentially disrupting legitimate booking flows.
Recommendation
Immediately upgrade OpenReception to version 1.0.4 or later, which patches the issue. After upgrading, audit the staff_crypto table for unauthorized entries, and consider adding unique constraints on user_id and strengthening key validation.
Other vulnerabilities in OpenReception
See all- CVE-2026-54460Critical
In OpenReception prior to 1.1.1, the POST /api/auth/passkeys endpoint accepts a request-body userId and an attacker-supplied passkey without an authenticated session, does not call WebAuthnService.verifyRegistration, and does not bind enrollment to locals.user.id. An unauthenticated attacker who knows the public tenant ID and the target staff email can inject a controlled public key, identify the matching userId, and create a STAFF session.
- CVE-2026-48087Critical
A vulnerability in OpenReception (before 1.0.2) in WebAuthn registration allows an unauthenticated attacker to associate their own credential with a victim's account by manipulating the userId parameter in the URL. The validation does not check that the userId belongs to the email in the cookie.
- CVE-2026-48086Critical
A vulnerability in OpenReception's appointment booking software allows a TENANT_ADMIN to promote themselves or another staff member to the platform-wide GLOBAL_ADMIN role via a single PUT request. There is no policy check enforcing that only an existing GLOBAL_ADMIN can grant GLOBAL_ADMIN, so schema validation acts as the authorization decision. After re-login, the tenant admin gains full access to all other tenants on the platform.
- CVE-2026-48085Critical
OpenReception's appointment booking software before version 1.0.1 allows an unauthenticated attacker to create a GLOBAL_ADMIN account by sending a POST request to `/setup/create-admin-account`, without verifying that an admin already exists. The attacker gains full administrative control over the platform, and the new account is active and does not require email confirmation.
- CVE-2026-75525Medium
In OpenReception versions 2.1.0 and prior, an unauthenticated attacker can store an arbitrary ML-KEM-768 public key under any existing user's identity in any tenant's staff-crypto recipient directory. The product's design guarantees that appointment data is end-to-end encrypted to staff members and that the staff recipient directory is not attacker-writable, so that even administrators and the operator cannot read patient data. This endpoint breaks that guarantee for an unauthenticated remote actor: it allows writing an arbitrary encryption recipient into the recipient directory of any tenant. The injected key receives the tunnel key of every appointment booked afterward in that tenant, because booking clients encrypt to all active staff keys. The attacker holds the corresponding secret key and is a persistent, unauthorized recipient of that key material. At time of publication, there are no publicly available patches.
- CVE-2026-75524Medium
In OpenReception prior to version 2.2.2, an attacker overbooks an agent, placing multiple appointments into a single time slot that the system is designed to keep exclusive. The number of overlapping appointments equals the number of concurrent requests, and one booking token is enough because the token is consumed after the insert. This results in the integrity of the booking calendar breaking and availability being denied to other clients. This issue has been patched in version 2.2.2.
- CVE-2026-65825High
In OpenReception versions 2.1.0 and prior, a returning client's six-digit booking PIN can be brute-forced online within the victim tenant. A successful guess yields the client's booking access token, granting access to that client's appointment tunnel with end-to-end-encrypted data and the ability to act as the client, e.g. adding or cancelling appointments. The bypass is cross-tenant: state owned by one tenant removes an authentication protection of a different tenant. At time of publication, there are no publicly available patches.
- CVE-2026-65824High
In OpenReception prior to version 2.2.1, an attacker who captures a pending invite token can replay it to obtain a passkey-registration credential and register their own passkey on the invited account, taking control of that account. For a staff or tenant-admin invite this yields access to the tenant context tied to that account. This issue has been patched in version 2.2.1.
- CVE-2026-58202High
In OpenReception prior to version 2.0.0, the account-confirmation link in emails is built from the request Host header with no allowlist. The unauthenticated POST /api/auth/resend-confirmation rotates a pending invitee's confirmation token and emails a link whose host comes from the request. An attacker sending one resend-confirmation with Host: attacker.example and a pending invitee's email causes that invitee to receive a confirmation email whose only link points to the attacker; if clicked, the one-time token reaches the attacker, who confirms the account on the real tenant domain and registers a passkey they control, taking over the account. All released versions through v1.1.0 are affected; no patched version exists yet. Reaching the app with a spoofed Host depends on the front proxy: the stock Caddy catch-all forwards it, while an operator with explicit per-tenant proxy blocks is not affected. This issue has been patched in version 2.0.0.
- CVE-2026-48084High
OpenReception before version 1.0.2 does not throttle failed passphrase login attempts. An attacker can submit unlimited wrong passphrase guesses against any known email address, at a rate of about 10 attempts per second. The lack of throttling in the passphrase branch, while the WebAuthn endpoint has throttling, enables brute-force and dictionary attacks on user accounts. The issue is fixed in version 1.0.2.
Original NVD description (English source)
OpenReception's appointment booking software provides an end-to-end encrypted appointment booking platform. Prior to version 1.0.4, the route `POST /api/tenants/{tenantId}/staff/{staffId}/crypto` accepts and stores attacker-controlled ML-KEM-768 public keys against any tenant on the platform without authentication. The handler logs an "Unauthorized crypto key storage attempt" warning when neither a session nor a registration cookie is present, then proceeds to insert the row regardless. The platform's E2E claim that "even administrators cannot view sensitive information" is broken: any unauthenticated network attacker can register themselves as an additional encryption recipient for any tenant's future patient appointments. A second variant of the bug suppresses the unauthorized-warning log entry. The Zod schema makes the `email` field optional. When the request body omits `email` and the request carries no registration cookie, the comparison `registrationEmail === email` becomes `undefined === undefined`, which evaluates to `true`. The handler treats the request as a legitimate registration flow, skips the warning entirely, and stores the row. Successful storage is still recorded as an `[info]` log line, but the security-relevant warning that operators are most likely to monitor or alert on is gone. The `staff_crypto` table has no unique constraint on `user_id`, so an arbitrary number of attacker rows can coexist for the same staff identifier and all return as `is_active=true`. The supplied `staffId` does not need to match any existing user or pending invite. Schema validation on `passkeyId`, `publicKey`, and `privateKeyShare` is also weak: the literal string `<placeholder-base64>` was accepted, indicating no length, format, or cryptographic-validity check beyond field presence. This weakness is independent of the auth bypass but compounds it: a poisoned directory can also be filled with malformed entries that break legitimate booking flows. The injected key is consumed by the public booking flow. After completing the unauthenticated `bootstrap-challenge` and `bootstrap-verify` ceremony as a "patient", the resulting `bookingAccessToken` is accepted by `GET /api/tenants/{id}/appointments/staff-public-keys`, which returns the attacker-controlled keys alongside any legitimate ones. A new appointment encrypts its tunnel key with ML-KEM to all listed recipients, so the attacker becomes a co-recipient of the encryption and can decapsulate the tunnel key with the matching secret. From there, all appointment payloads for that booking are decryptable. Version 1.0.4 patches the issue.
Vulnerability data from NVD (NIST) · CISA KEV · EPSS

