Skip to main content
Vulnerability Database/CVE-2026-105687

CVE-2026-105687: Penpot Privilege Escalation Vulnerability

CVE-2026-105687 is a privilege escalation flaw in Penpot that allows non-owner administrators to remove team owners from their teams. This post explains its impact, affected versions, and mitigation steps.

Published:

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Sources: National Vulnerability Database, CISA KEV, Exploit-DB

CVE-2026-105687 Overview

CVE-2026-105687 is a privilege escalation vulnerability in Penpot, an open-source design and prototyping platform. The flaw resides in the delete-team-member Remote Procedure Call (RPC), which fails to protect the team owner from removal. A non-owner administrator can delete the owner's team-profile-rel membership record and lock the legitimate owner out of the team, its projects, files, fonts, and media assets. The vulnerability is classified as Improper Privilege Management [CWE-269] and is fixed in Penpot version 2.18.0.

Critical Impact

A team administrator can forcibly remove the team owner, resulting in loss of access to all team-owned projects, files, fonts, and media.

Affected Products

  • Penpot versions prior to 2.18.0
  • Self-hosted Penpot deployments running the vulnerable teams.clj RPC handler
  • Managed Penpot instances with multi-administrator team configurations

Discovery Timeline

  • 2026-10-05 - CVE-2026-105687 published to the National Vulnerability Database (NVD)
  • 2026-10-06 - Last updated in NVD database

Technical Details for CVE-2026-105687

Vulnerability Analysis

The vulnerability lives in the delete-team-member RPC command defined in backend/src/app/rpc/commands/teams.clj. The handler verifies that the caller holds either :is-owner or :is-admin permissions, then permits the deletion of any member record other than the caller's own. The handler does not check whether the target member is the team owner. Any administrator can therefore invoke the RPC against the owner's profile identifier and remove the owner's membership relation.

Once the owner's team-profile-rel record is deleted, Penpot's authorization checks no longer resolve the removed account to the team. The owner loses visibility and control over all projects, files, fonts, and media bound to the team. The attack produces a persistent denial of access while preserving administrator control of the resources.

Root Cause

The root cause is missing authorization logic that treats the team owner as a protected principal. The RPC enforces role-based access on the caller but does not evaluate the target's role before deletion. This is a classic Improper Privilege Management flaw [CWE-269] in which the privilege model fails to assert hierarchy between administrator and owner.

Attack Vector

Exploitation requires an authenticated account with team administrator privileges. The attacker issues a delete-team-member RPC call that supplies the team identifier and the owner's member-id. The call executes within a database transaction and succeeds without triggering a validation error. No user interaction from the victim is required.

clojure
;; Patch excerpt from backend/src/app/rpc/commands/teams.clj
;; Fix: resolve the target member and reject deletion of the owner
    ::sm/params schema:delete-team-member
    ::db/transaction true}
   [{:keys [::db/conn ::mbus/msgbus] :as cfg} {:keys [::rpc/profile-id team-id member-id] :as params}]
-  (let [team  (get-team conn :profile-id profile-id :team-id team-id)
-        perms (get-permissions conn profile-id team-id)]
+  (let [team    (get-team conn :profile-id profile-id :team-id team-id)
+        perms   (get-permissions conn profile-id team-id)
+        members (get-team-members conn team-id)
+        member  (d/seek #(= member-id (:id %)) members)]
     (when-not (or (:is-owner perms)
                   (:is-admin perms))
       (ex/raise :type :validation

Source: Penpot commit 45f0153e

Detection Methods for CVE-2026-105687

Indicators of Compromise

  • Audit log entries showing delete-team-member RPC calls where the removed member-id corresponds to a user previously flagged as team owner.
  • Sudden absence of the owner account from the team_profile_rel database table while the team continues to exist.
  • Unexpected support tickets from users reporting loss of access to Penpot projects they previously owned.

Detection Strategies

  • Query the Penpot application logs for delete-team-member invocations and correlate the target profile against historical owner assignments.
  • Compare point-in-time snapshots of team_profile_rel to detect owner records that disappear without a corresponding ownership transfer event.
  • Alert on administrator accounts that remove multiple members within a short time window, which may indicate abuse of the vulnerable RPC.

Monitoring Recommendations

  • Forward Penpot backend logs to a central log store and build detections on RPC command patterns targeting team membership tables.
  • Monitor database write activity against team_profile_rel for deletions that remove the :is-owner relation.
  • Track administrator role assignments across teams and review any new administrator granted shortly before a membership change.

How to Mitigate CVE-2026-105687

Immediate Actions Required

  • Upgrade all Penpot instances to version 2.18.0 or later, which includes the authorization check against owner removal.
  • Audit existing teams to verify the correct owner is still assigned and restore ownership where it has been altered.
  • Review the roster of accounts holding team administrator privileges and remove unnecessary grants.

Patch Information

The fix is delivered in Penpot 2.18.0. The patch resolves the target member from get-team-members and rejects the delete operation when the target holds the owner role. See the Penpot 2.18.0 release and the GHSA-j83r-hph3-xpxc security advisory for full details.

Workarounds

  • Restrict the team administrator role to trusted operators until the upgrade to 2.18.0 is deployed.
  • Take regular backups of the Penpot database so that an owner's team-profile-rel row can be restored if deleted.
  • Place the Penpot API behind authentication-aware logging so administrator RPC calls are reviewable in near real time.
bash
# Upgrade a self-hosted Penpot deployment to the patched release
docker compose pull
docker compose down
docker compose up -d --remove-orphans
# Confirm the backend reports version 2.18.0 or later
curl -s https://penpot.example.com/api/rpc/command/get-profile | grep -i version

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Sources: National Vulnerability Database, CISA KEV, Exploit-DB

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.