Executive brief
Semaphore UI is an automation and project management platform that uses role-based access control to restrict what project members can do. A project manager can create a custom role with the same name as the built-in manager role and grant it owner-level permissions, allowing them to escalate to full project ownership in a single API request. An attacker can then modify project settings, manage members, delete the project, or remove the legitimate owner—actions normally restricted to project owners only.
Technical details
The vulnerability is a privilege escalation resulting from multiple validation gaps in Semaphore UI's custom role system. When a project member's effective permissions are resolved, the system looks up a role by slug (a unique identifier), and if a custom role exists with the same slug as the member's assigned role, it overwrites the member's permission bitmask with the custom role's permissions. The role-creation endpoint (`POST /api/project/{id}/roles`) is gated by the `CanManageProjectResources` permission, which the built-in `manager` role already holds. However, the role validator does not prevent creating a custom role with a reserved slug name (like `manager`, `owner`, `task_runner`, `guest`), nor does it cap the permission bits an attacker can assign. Additionally, the permission lookup ignores project scope, accepting any matching slug across projects. An authenticated manager creates a custom role with slug `manager` and all permission bits set (bitmask `15`), including the owner-only bits `CanUpdateProject` and `CanManageProjectUsers`. On the next request, the permission lookup returns the custom role row, granting the manager full owner privileges without requiring authentication changes or owner approval. Exploitation requires prior assignment to the project with manager role and is available only in the PRO build with custom project roles enabled (the default in official Docker images).
Affected products
- semaphoreui semaphore < 0.0.0-20260705182501-bb2a4e1f08c8 (v2.18.12 confirmed; PRO build with custom roles)
Timeline
- 2026-09-03: disclosed: GitHub Advisory published
- 2026-07-05: patched: Patch released in version 0.0.0-20260705182501-bb2a4e1f08c8
- 2026-08-12: advisory: NVD published CVE-2026-73293