OpenReception's appointment booking software provides an end-to-end encrypted appointment booking platform. Prior to version 1.0.2, a TENANTADMIN promotes themselves to platform-wide GLOBALADMIN through a single PUT request. The role-update handler accepts the GLOBALADMIN enum value from any tenant admin updating their own tenant's staff. No policy check enforces that "only an existing GLOBALADMIN may grant GLOBALADMIN", so the schema validation IS the authorization decision. After re-login, the JWT contains the new role and the formerly-tenant-scoped admin reaches every other tenant on the platform. On the hosted OpenReception service this is a scope-changed escalation: a single customer-side tenant administrator gains full platform-wide administrative control over all other tenants' configuration, users, staff records, operational metadata, and tenant lifecycle. Plaintext appointment contents remain subject to the E2E model unless chained with the staff-crypto poisoning issue (V-4) or with staff-passkey hijacking (V-1). On a single-tenant self-hosted deployment it is still a privilege escalation because TENANTADMIN should not be able to create new tenants, modify global configuration, or manage other administrators. The same handler also accepts updates targeted at any colleague within the tenant. A tenant admin can promote a separate collaborator account instead of themselves, leaving their own audit trail clean while the platform-wide breach happens through a separate identity. Version 1.0.2 fixes the issue.
OpenReception's appointment booking software provides an end-to-end encrypted appointment booking platform. Prior to version 1.0.6, the bootstrap challenge endpoint at /api/tenants/{id}/appointments/bootstrap-challenge issues a SHA-256 proof-of-work with difficulty=4 hex zeros, equivalent to 16 bits of work. Modern hardware solves this in under 200 milliseconds, providing essentially no friction against automated abuse of the patient booking flow. Proof-of-work is used in the booking flow as a rate-limiter for unauthenticated clients establishing tunnels and submitting appointments. At 16 bits of difficulty, the construct is decorative rather than effective. An attacker can solve PoW challenges as fast as the server can issue them, defeating the rate-limiting purpose. The handler also calls challengeThrottleService.checkThrottle(binding, "passkey"), but the binding includes attacker-controlled values (tunnelId, clientPublicKey, and optional emailHash). For each fresh attempt, the attacker can supply new values, producing a new throttle key and bypassing the per-binding accumulation. Practical abuse friction is therefore the PoW difficulty itself, not a stable per-IP or per-email server-side throttle. Version 1.0.6 fixes the issue.