Attack ChainAIDerived
Hypothetical attack flow derived from CVE metadata – not a confirmed exploit chain
-
AccessAuthenticate to workspace as a low-privilege member
-
DeliveryEnumerate workspace members to discover owner user_id
-
ExploitSend crafted DELETE request to /workspaces/{workspace_id}/members/{owner_id}
-
ExecutionServer deletes owner membership without role check
-
ImpactOwner is permanently locked out of workspace
Vulnerability Assessment
| Weakness |
CWE
OWASP Top 10:2025
A06:2025 - Insecure Design
ASVS 5.0
V8 - Authorization Least privilege enforcement
MITRE ATT&CK
1 technique across 1 tactic: Privilege Escalation The technique list with ATT&CK links and the kill-chain view is part of the Basic plan and up. |
| Exploitation Conditions | The attacker must hold a valid authentication token for a member of the target workspace (any role). The target owner's user ID is obtainable via the unprivileged list members endpoint. No user interaction or elevated privileges are required beyond basic workspace membership. The vulnerability is exploitable over the network with low attack complexity. There is no requirement for any non-default configuration; the platform's default multi-tenant behavior exposes the flaw. |
| Impact | CVSS 3.1 score of 8.1 (AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:H) reflects a network-exploitable vulnerability with low attack complexity and only low privileges required, leading to high integrity and availability impact. However, the EPSS score is only 0.04% (13th percentile), indicating a low probability of widespread exploitation in the wild over the next 30 days. No CISA KEV listing has been made, and there is no public exploit code identified at this time, though the vulnerability is trivially exploitable given a single member token. The risk is elevated in multi-tenant deployments of the platform because any authenticated member can disrupt the workspace of any other member. Despite the high CVSS, the EPSS and lack of active exploitation reports suggest targeted rather than mass exploitation is more likely. The availability of a vendor patch reduces the priority to patching quickly. |
| Exploit ScenarioDerived | An attacker with a valid member JWT for any workspace enumerates the workspace owner's user ID via |
Get an e-mail when this CVE is exploited, patched or re-scored. Free account.
Alert meAnalysisAIv1 – Jul 27, 2026
Authorization bypass in praisonai-platform's workspace member removal endpoint allows any workspace member to delete any other member, including the owner. An attacker with a low-privilege member token can permanently lock the legitimate owner out of their workspace, leading to a complete denial of service and, when combined with other flawed endpoints, full workspace takeover. Patched in version 0.1.4.
RemediationAI
Upgrade praisonai-platform to version 0.1.4 or later, which introduces the necessary owner-role gate and last-owner protection via commit 24385d6 (https://github.com/MervinPraison/PraisonAI/commit/24385d64876577620f749957bd4814f162f4ca47). The fix also includes a PLATFORM_HOST environment variable and other security enhancements. Until an upgrade can be applied, consider restricting access to the member removal endpoint by applying a reverse proxy rule that blocks DELETE requests to /workspaces/*/members/* from non-administrative users, though this may interfere with legitimate owner operations.
Affected VersionsENISA
Affected Packages
Source: OSV (Open Source Vulnerabilities)
Affects your stack
Affects 2 packages in pypi, euvd
Checking this CVE against your own stacks and servers is part of the Basic plan and up.
Technical ContextAI · show details
The vulnerability exists in the Python FastAPI-based PraisonAI Platform due to missing role checks in the DELETE /workspaces/{workspace_id}/members/{user_id} route. The dependency require_workspace_member only validates that the caller is a member of the workspace (defaulting to min_role='member'), but the service layer MemberService.remove() performs no caller-role verification and lacks protection against removing the last owner. This is a classic improper privilege management issue (CWE-269), where the authorization guard is misapplied and the operation delegates trust entirely to the URL-supplied user ID. The affected component is the praisonai_platform Python package (CPE: pkg:pip/praisonai-platform).
Know when Python gets its next vulnerability
- Watch products and get an email when something new is published
- Check this CVE against your own stack and servers
- Exploit and PoC references, threat intelligence from 22 sources
No credit card · 7-day full trial
Severity by source
AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:H
Requires low privilege (member) but no user interaction; attack changes membership integrity and disrupts availability; no confidentiality impact.
Primary rating from Vendor (https://github.com/MervinPraison/PraisonAI).
CVSS VectorVendor: https://github.com/MervinPraison/PraisonAI
DescriptionCVE.org
Summary
Type: Authorization bypass enabling owner lockout. The DELETE /workspaces/{workspace_id}/members/{user_id} endpoint is gated only by require_workspace_member(workspace_id) (default min_role="member"). Any member can remove any other member, including the workspace owner, using a single DELETE. There is no caller-role check, no target-role check, no "cannot remove last owner" guard. File: src/praisonai-platform/praisonai_platform/api/routes/workspaces.py, lines 130-140; services/member_service.py, lines 71-78. Root cause: MemberService.remove(workspace_id, user_id) performs the deletion without any caller-permission check or owner-protection logic. The route accepts the URL-supplied user_id and dispatches it straight through. The role hierarchy (MemberService.has_role) is implemented but never invoked here. A member-tier attacker can issue DELETE .../members/<owner_user_id> and immediately lock the legitimate owner out of the workspace.
Affected Code
File 1: src/praisonai-platform/praisonai_platform/api/routes/workspaces.py, lines 130-140.
@router.delete("/{workspace_id}/members/{user_id}", status_code=status.HTTP_204_NO_CONTENT)
async def remove_member(
workspace_id: str,
user_id: str,
user: AuthIdentity = Depends(require_workspace_member),
# <-- BUG: defaults to min_role="member"
session: AsyncSession = Depends(get_db),
):
member_svc = MemberService(session)
removed = await member_svc.remove(workspace_id, user_id)
# <-- removes any member, including owner
if not removed:
raise HTTPException(status_code=404, detail="Member not found")File 2: src/praisonai-platform/praisonai_platform/services/member_service.py, lines 71-78.
async def remove(self, workspace_id: str, user_id: str) -> bool:
"""Remove a member from a workspace."""
member = await self.get(workspace_id, user_id)
if member is None:
return False
await self._session.delete(member)
# <-- BUG: no caller-role check, no last-owner protection
await self._session.flush()
return TrueWhy it's wrong: member-removal is the textbook capability that must be gated on owner role. Removing the workspace owner is a permanent denial-of-service against the legitimate owner unless another owner exists. There must be (a) a caller min-role gate of "owner" or "admin", (b) a check that prevents removing a member whose role is higher than the caller's, and (c) a check that the workspace is left with at least one owner. None of these exist.
Exploit Chain
- Attacker is a member of workspace
Wwith role "member". State: attacker holds JWT. - Attacker enumerates the workspace owner's
user_idviaGET /workspaces/W/members(list_members has the same default-member gate, separate finding). Owner UUIDO_idis now known. State: attacker holdsO_id. - Attacker sends
DELETE /workspaces/W/members/O_idwithAuthorization: Bearer <attacker_jwt>. State: control flow entersremove_member. require_workspace_member(W, attacker)passes (attacker is a member).MemberService.remove(W, O_id)deletes the owner's member row. State:Member(workspace_id=W, user_id=O_id, role="owner")is gone.- Owner attempts
GET /workspaces/W/...andrequire_workspace_member(W, O_id)returns 403. State: legitimate owner is now locked out of their own workspace. - Combined with the
update_member_rolecompanion advisory, the attacker first promotes themselves to owner, then removes the legitimate owner, then has uncontested control. Combined withdelete_workspace, the attacker wipes the workspace after kicking the owner. - Final state: with one member-level token, the attacker locks the legitimate owner out of their own workspace permanently. The owner has no recourse other than database-level admin intervention.
Security Impact
Severity: sec-high. CVSS 8.1: network attack, low complexity, low privileges, no user interaction, scope unchanged, no confidentiality, high integrity (membership table corrupted), high availability (legitimate owner cannot access their own workspace). Attacker capability: with one workspace-member token plus one DELETE request, the attacker permanently locks any other member (including the workspace owner) out of the workspace. Preconditions: praisonai-platform is deployed multi-tenant; attacker has any membership token; owner's user_id is reachable via the (unauthenticated-for-member) list_members endpoint. Differential: source-inspection-verified. The asymmetry between require_workspace_member's tunable min_role parameter and this endpoint's use of the default value confirms the gap. With the suggested fix below, member-tier tokens fail the gate, and removing the workspace's last owner triggers the additional guard.
Suggested Fix
--- a/src/praisonai-platform/praisonai_platform/api/routes/workspaces.py
+++ b/src/praisonai-platform/praisonai_platform/api/routes/workspaces.py
@@ -130,11 +130,21 @@
@router.delete("/{workspace_id}/members/{user_id}", status_code=status.HTTP_204_NO_CONTENT)
async def remove_member(
workspace_id: str,
user_id: str,
- user: AuthIdentity = Depends(require_workspace_member),
+ user: AuthIdentity = Depends(_require_workspace_owner),
session: AsyncSession = Depends(get_db),
):
member_svc = MemberService(session)
+ target = await member_svc.get(workspace_id, user_id)
+ if target is not None and target.role == "owner":
+
# Refuse to remove the last owner.
+ owners = [m for m in await member_svc.list_members(workspace_id) if m.role == "owner"]
+ if len(owners) <= 1:
+ raise HTTPException(status_code=409, detail="Cannot remove the last workspace owner")
removed = await member_svc.remove(workspace_id, user_id)
if not removed:
raise HTTPException(status_code=404, detail="Member not found")The four companion workspace-mutation endpoints exhibit the same default-min-role gap and are filed as their own advisories.
Threat Intelligence Overview
How this decision was reached
The engine reads each signal below and applies a fixed list of rules from top to bottom. The first rule that matches sets the recommended action – like a statement, every line is shown.
What every action level means
SSVC AssessmentENISA
Priority Score
Attack Technique
Privilege escalation occurs when an attacker leverages flaws in access control mechanisms to gain permissions beyond what they were originally granted.
Wazuh SIEM platform versions 4.4.0 through 4.9.0 contain an unsafe deserialization vulnerability in the DistributedAPI t
BentoML version 1.4.2 and earlier contains an unauthenticated remote code execution vulnerability through insecure deser
pgAdmin 4 contains critical remote code execution vulnerabilities in the Query Tool download and Cloud Deployment endpoi
The renderLocalView function in render/views.py in graphite-web in Graphite 0.9.5 through 0.9.10 uses the pickle Python
BentoML is a Python library for building online serving systems optimized for AI apps and model inference. Rated critica
OpenSSL before 0.9.8za, 1.0.0 before 1.0.0m, and 1.0.1 before 1.0.1h does not properly restrict processing of ChangeCiph
pyLoad download manager version prior to 0.5.0b3.dev77 exposes the Flask SECRET_KEY through an unauthenticated endpoint.
Langflow (a visual LLM pipeline builder) contains a critical unauthenticated code execution vulnerability (CVE-2026-3301
In Mercurial before 4.1.3, "hg serve --stdio" allows remote authenticated users to launch the Python debugger, and conse
Unauthenticated remote code execution affects Kestra OSS (the open-source event-driven orchestration platform) prior to
Unauthenticated remote code execution in Marimo ≤0.20.4 allows attackers to execute arbitrary system commands via the `/
pyLoad is the free and open-source Download Manager written in pure Python. Rated medium severity (CVSS 5.3), this vulne
EUVD-2026-46323
GHSA-w388-2392-px73
NVD
CVE.org
EPSS
Exploit-DB