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

CVE-2026-104978: Plane Project Management Auth Bypass Flaw

CVE-2026-104978 is an authentication bypass flaw in Plane open-source project management tool that allows attackers to join workspaces through invitation enumeration. This post explains its impact, affected versions, and mitigation steps.

Published:

CVE-2026-104978 Overview

Plane, an open-source project management tool, contains a broken authorization vulnerability [CWE-863] in its project invitation workflow. Prior to version 1.4.0, the project invitation join endpoint accepted an invitation based only on a submitted email address. Any authenticated user who knows the workspace slug and project ID can enumerate pending invitations through the invitation list endpoint. When a pending invitation targets an email that has not yet registered with Plane, an attacker can register an account using the invited email without mailbox verification and accept the invitation. The attacker-controlled account is then added to the target workspace and project with the invited role.

Critical Impact

Attackers can hijack pending project invitations to gain unauthorized access to private workspaces and projects, exposing sensitive project data and enabling tampering with issues, cycles, and modules.

Affected Products

  • Plane (makeplane/plane) versions prior to 1.4.0
  • Self-hosted Plane deployments exposing the project invitation endpoints
  • Plane instances where email verification is not strictly enforced during registration

Discovery Timeline

  • 2026-10-05 - CVE-2026-104978 published to the National Vulnerability Database
  • 2026-10-07 - Last updated in NVD database

Technical Details for CVE-2026-104978

Vulnerability Analysis

The flaw resides in Plane's project invitation acceptance endpoint, implemented in apps/api/plane/app/views/project/invite.py. The vulnerable post handler on the ProjectJoinEndpoint validated the invitation using only an email address supplied in the request body. The handler fetched a ProjectMemberInvite object by primary key, workspace slug, and project ID, and then compared project_invite.email against the attacker-supplied email field.

Because the invitation list endpoint is reachable by any authenticated workspace user, an attacker can enumerate pending invitations and read the target email values. The attacker then registers a new Plane account using the invited email. Plane does not require mailbox verification during registration, so the attacker never needs to control the real inbox. Submitting the harvested email to the join endpoint grants membership in the target project and workspace.

Root Cause

The root cause is missing authorization and missing proof-of-possession on the acceptance endpoint. The server treated knowledge of the invited email as sufficient authorization, instead of requiring the single-use invitation token and an authenticated session bound to the invited identity. Combined with the absence of mandatory email verification during account creation, this collapses the invitation workflow into a trivially forgeable grant.

Attack Vector

The attack requires network access to the Plane API and a low-privilege authenticated session within the target workspace. The attacker enumerates pending invitations via the project invitation list endpoint, identifies invitations whose email addresses have not yet registered, creates accounts under those emails, and posts to the acceptance endpoint to be added to the project.

python
    def post(self, request, slug, project_id, pk):
        project_invite = ProjectMemberInvite.objects.get(pk=pk, project_id=project_id, workspace__slug=slug)

-        email = request.data.get("email", "")
+        token = request.data.get("token", "")

-        if email == "" or project_invite.email != email:
+        # Validate the token to verify the user received the invitation email
+        if not token or project_invite.token != token:
            return Response(
                {"error": "You do not have permission to join the project"},
                status=status.HTTP_403_FORBIDDEN,
            )

+        # Require an authenticated session — the accepting user must be the
+        # person who was invited.  Without this check an attacker who knows the
+        # invitee email and obtains the token can hijack the project membership
+        # (GHSA-g36h-p63v-g9c7).
+        if not request.user.is_authenticated:
+            return Response(
+                {"error": "Authentication required to accept project invitation"},
+                status=status.HTTP_401_UNAUTHORIZED,
+            )
+        if request.user.email.lower() != project_invite.email.lower():
+            return Response(
+                {"error": "You do not have permission to accept this invitation"},
+                status=status.HTTP_403_FORBIDDEN,
+            )

        if project_invite.responded_at is None:

Source: GitHub Commit 14a4c22. The patch enforces token validation, requires an authenticated session, and binds acceptance to the invited email.

Detection Methods for CVE-2026-104978

Indicators of Compromise

  • Successful POST requests to the project invitation join endpoint without a corresponding mailbox-verified registration flow for the invited email
  • Account registrations whose email matches a recently created ProjectMemberInvite and that occur shortly before invitation acceptance
  • Unexpected new members added to private projects, especially where the inviting user did not initiate a follow-up
  • Repeated enumeration-style GET requests to the project invitation list endpoint from a single authenticated session

Detection Strategies

  • Correlate ProjectMemberInvite acceptance events with the registration timestamp of the accepting user to identify just-in-time account creation
  • Alert when an invitation is accepted by a session whose source IP or user agent differs from the invitation sender's organization baseline
  • Review API gateway logs for high-volume listing of invitation resources by non-administrative users

Monitoring Recommendations

  • Enable audit logging on workspace membership changes and forward events to a centralized SIEM for retention and correlation
  • Monitor Plane application logs for HTTP 200 responses on the invitation acceptance path paired with newly created accounts
  • Track changes to project membership and workspace roles against an approved change list

How to Mitigate CVE-2026-104978

Immediate Actions Required

  • Upgrade all Plane deployments to version 1.4.0 or later, which enforces token and authenticated-session validation on invitation acceptance
  • Audit existing workspace and project memberships and revoke any accounts added through unexplained invitation flows
  • Invalidate pending invitations issued before the upgrade and reissue them to the intended recipients
  • Enforce mandatory email verification for all new Plane account registrations

Patch Information

The fix is included in Plane 1.4.0. The code change is tracked in GitHub Pull Request #9308 and commit 14a4c22. Additional context is published in the GitHub Security Advisory GHSA-g36h-p63v-g9c7 and the GitHub Release v1.4.0 notes.

Workarounds

  • Restrict network access to the Plane API so that only trusted users can reach the invitation endpoints
  • Require administrator approval before new members are granted access to sensitive projects
  • Disable self-service registration or gate it behind single sign-on with verified identity providers until the patch is applied
bash
# Upgrade self-hosted Plane to the patched release
git fetch --tags
git checkout v1.4.0
docker compose pull
docker compose up -d

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

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.