CVE-2026-47409: praisonai-platform: auth bypass enables owner lockout

GHSA-w388-2392-px73 HIGH
Published May 29, 2026
CISO Take

PraisonAI Platform (praisonai-platform ≤ 0.1.2) allows any authenticated workspace member to permanently remove any other member—including the workspace owner—via a single DELETE request, because the removal endpoint never checks the caller's role and the role-hierarchy enforcement code present in the codebase is simply never invoked on this path. With CVSS 8.1 (High), network-accessible, low complexity, no user interaction required, and a trivial one-request exploit chain (enumerate owner ID via the member list endpoint, issue one DELETE), the barrier to exploitation is essentially zero for any disgruntled or compromised member-tier account; the same package carries 59 prior CVEs, a strong signal of structural security debt that makes companion-advisory chaining—role escalation plus workspace deletion—a realistic follow-on. There is no public exploit and it is not in CISA KEV, but the attack is deterministic and recoverable only via direct database-level admin intervention once the owner is locked out. Upgrade to praisonai-platform ≥ 0.1.4 immediately, audit workspace membership tables for unexpected owner removals, and alert on DELETE requests to `/workspaces/*/members/*` originating from non-owner tokens.

Sources: NVD GitHub Advisory ATLAS

What is the risk?

High risk. Network-accessible endpoint requiring only a valid member-tier credential—the lowest privilege level in the system—with no user interaction and low attack complexity. The exploit is single-request and fully deterministic, making it trivially automatable at scale across all workspaces where an attacker holds any membership token. Integrity and availability impact are both High: ownership of the workspace is irrevocably transferred to the attacker with no self-service recovery path for the victim. The 59 prior CVEs in the same package are a material indicator of systemic security posture issues, elevating the probability of compound exploitation through companion advisories covering role escalation and workspace deletion to achieve full takeover.

Attack Kill Chain

Initial Access
Attacker obtains a valid member-tier JWT for the target PraisonAI workspace via a legitimate account, compromised credential, or invited contractor access.
AML.T0012
Reconnaissance
Attacker calls GET /workspaces/{id}/members—accessible to any member under the same default-role gate—to enumerate all workspace participants and extract the owner's user_id.
AML.T0049
Privilege Exploitation
Attacker issues DELETE /workspaces/{id}/members/{owner_id}; the missing caller-role check allows the member-tier token to pass authorization and delete the owner's membership row from the database.
AML.T0049
Impact
Legitimate workspace owner is permanently locked out; attacker promotes themselves to owner via companion advisory and gains uncontested control over all AI agent configurations, tool bindings, and orchestration workflows in the workspace.
AML.T0048.003

What systems are affected?

Package Ecosystem Vulnerable Range Patched
praisonai-platform pip <= 0.1.2 0.1.4
1 dependents 86% patched ~0d to patch Full package profile →

Do you use praisonai-platform? You're affected.

Severity & Risk

CVSS 3.1
8.1 / 10
EPSS
N/A
Exploitation Status
No known exploitation
Sophistication
Trivial

Attack Surface

AV AC PR UI S C I A
AV Network
AC Low
PR Low
UI None
S Unchanged
C None
I High
A High

What should I do?

6 steps
  1. Patch immediately: upgrade praisonai-platform to ≥ 0.1.4 (the fix gates remove_member on _require_workspace_owner and adds a last-owner protection check).

  2. Audit workspace membership tables for unexpected deletions of owner-role members, particularly those not associated with an admin-initiated action or support ticket.

  3. Until patched, alert on HTTP DELETE to /workspaces/*/members/* endpoints from tokens whose decoded role is not 'owner' or 'admin'—these requests should be blocked at the WAF or API gateway level as a compensating control.

  4. Review all companion workspace-mutation endpoints (add_member, update_member_role, delete_workspace) for the same default-min-role gap described in sibling advisories.

  5. Rotate workspace API credentials and re-verify ownership for any tenant where suspicious member-removal activity is detected in audit logs.

  6. Enforce network-level access restrictions on the workspace management API to known trusted IP ranges if immediate patching is not feasible.

Classification

Compliance Impact

This CVE is relevant to:

EU AI Act
Article 9 - Risk management system
ISO 42001
A.6.2.3 - Access control for AI systems
NIST AI RMF
GOVERN 1.6 - Organizational policies for AI risk management
OWASP LLM Top 10
LLM08 - Excessive Agency

Frequently Asked Questions

What is CVE-2026-47409?

PraisonAI Platform (praisonai-platform ≤ 0.1.2) allows any authenticated workspace member to permanently remove any other member—including the workspace owner—via a single DELETE request, because the removal endpoint never checks the caller's role and the role-hierarchy enforcement code present in the codebase is simply never invoked on this path. With CVSS 8.1 (High), network-accessible, low complexity, no user interaction required, and a trivial one-request exploit chain (enumerate owner ID via the member list endpoint, issue one DELETE), the barrier to exploitation is essentially zero for any disgruntled or compromised member-tier account; the same package carries 59 prior CVEs, a strong signal of structural security debt that makes companion-advisory chaining—role escalation plus workspace deletion—a realistic follow-on. There is no public exploit and it is not in CISA KEV, but the attack is deterministic and recoverable only via direct database-level admin intervention once the owner is locked out. Upgrade to praisonai-platform ≥ 0.1.4 immediately, audit workspace membership tables for unexpected owner removals, and alert on DELETE requests to `/workspaces/*/members/*` originating from non-owner tokens.

Is CVE-2026-47409 actively exploited?

No confirmed active exploitation of CVE-2026-47409 has been reported, but organizations should still patch proactively.

How to fix CVE-2026-47409?

1. Patch immediately: upgrade praisonai-platform to ≥ 0.1.4 (the fix gates `remove_member` on `_require_workspace_owner` and adds a last-owner protection check). 2. Audit workspace membership tables for unexpected deletions of owner-role members, particularly those not associated with an admin-initiated action or support ticket. 3. Until patched, alert on HTTP DELETE to `/workspaces/*/members/*` endpoints from tokens whose decoded role is not 'owner' or 'admin'—these requests should be blocked at the WAF or API gateway level as a compensating control. 4. Review all companion workspace-mutation endpoints (add_member, update_member_role, delete_workspace) for the same default-min-role gap described in sibling advisories. 5. Rotate workspace API credentials and re-verify ownership for any tenant where suspicious member-removal activity is detected in audit logs. 6. Enforce network-level access restrictions on the workspace management API to known trusted IP ranges if immediate patching is not feasible.

What systems are affected by CVE-2026-47409?

This vulnerability affects the following AI/ML architecture patterns: agent frameworks, multi-tenant platforms, API endpoints.

What is the CVSS score for CVE-2026-47409?

CVE-2026-47409 has a CVSS v3.1 base score of 8.1 (HIGH).

AI Security Impact

Affected AI Architectures

agent frameworksmulti-tenant platformsAPI endpoints

MITRE ATLAS Techniques

AML.T0012 Valid Accounts
AML.T0048.003 User Harm
AML.T0049 Exploit Public-Facing Application
AML.T0053 AI Agent Tool Invocation

Compliance Controls Affected

EU AI Act: Article 9
ISO 42001: A.6.2.3
NIST AI RMF: GOVERN 1.6
OWASP LLM Top 10: LLM08

Technical Details

Original Advisory

## 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. ```python @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. ```python 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 True ``` **Why 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 1. Attacker is a member of workspace `W` with role "member". State: attacker holds JWT. 2. Attacker enumerates the workspace owner's `user_id` via `GET /workspaces/W/members` (list_members has the same default-member gate, separate finding). Owner UUID `O_id` is now known. State: attacker holds `O_id`. 3. Attacker sends `DELETE /workspaces/W/members/O_id` with `Authorization: Bearer <attacker_jwt>`. State: control flow enters `remove_member`. 4. `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. 5. Owner attempts `GET /workspaces/W/...` and `require_workspace_member(W, O_id)` returns 403. State: legitimate owner is now locked out of their own workspace. 6. Combined with the `update_member_role` companion advisory, the attacker first promotes themselves to owner, then removes the legitimate owner, then has uncontested control. Combined with `delete_workspace`, the attacker wipes the workspace after kicking the owner. 7. 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 ```diff --- 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.

Exploitation Scenario

An attacker with a legitimate 'member' role in a shared PraisonAI workspace—a contractor, former employee, or owner of a compromised account—calls `GET /workspaces/{id}/members` (accessible by any member under the same default-gate logic) to enumerate all workspace members and retrieve the workspace owner's `user_id`. The attacker then sends `DELETE /workspaces/{id}/members/{owner_user_id}` with their member JWT. The request passes authentication (valid token), bypasses authorization (no role check exists), and the owner's membership row is deleted. The owner immediately receives HTTP 403 on any subsequent workspace request with no in-application recourse. The attacker then invokes the companion `update_member_role` advisory to promote their account to 'owner', gaining uncontested administrative control over all AI agent configurations, tool definitions, API key bindings, and orchestration pipelines in the workspace—with the original owner unable to recover access outside of direct database-level intervention by a platform administrator.

CVSS Vector

CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:H

Timeline

Published
May 29, 2026
Last Modified
May 29, 2026
First Seen
May 30, 2026

Related Vulnerabilities