CWE-269
DiscouragedImproper Privilege Management
Abstraction: Class · Status: Draft
The product does not properly assign, modify, track, or check privileges for an actor, creating an unintended sphere of control for that actor.
5655 vulnerabilities reference this CWE, most recent first.
GHSA-8F2R-X3FM-9QM9
Vulnerability from github – Published: 2022-05-24 17:08 – Updated: 2022-05-24 17:08An elevation of privilege vulnerability exists in the way that the Connected Devices Platform Service handles objects in memory, aka 'Connected Devices Platform Service Elevation of Privilege Vulnerability'. This CVE ID is unique from CVE-2020-0740, CVE-2020-0741, CVE-2020-0742, CVE-2020-0743, CVE-2020-0750.
{
"affected": [],
"aliases": [
"CVE-2020-0749"
],
"database_specific": {
"cwe_ids": [
"CWE-269"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2020-02-11T22:15:00Z",
"severity": "MODERATE"
},
"details": "An elevation of privilege vulnerability exists in the way that the Connected Devices Platform Service handles objects in memory, aka \u0027Connected Devices Platform Service Elevation of Privilege Vulnerability\u0027. This CVE ID is unique from CVE-2020-0740, CVE-2020-0741, CVE-2020-0742, CVE-2020-0743, CVE-2020-0750.",
"id": "GHSA-8f2r-x3fm-9qm9",
"modified": "2022-05-24T17:08:34Z",
"published": "2022-05-24T17:08:34Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2020-0749"
},
{
"type": "WEB",
"url": "https://portal.msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2020-0749"
}
],
"schema_version": "1.4.0",
"severity": []
}
GHSA-8F4F-MPWV-CR26
Vulnerability from github – Published: 2022-05-24 17:39 – Updated: 2022-05-24 17:39A vulnerability in the upgrade component of Cisco AnyConnect Secure Mobility Client could allow an authenticated, local attacker with low privileges to read arbitrary files on the underlying operating system (OS) of an affected device. The vulnerability is due to insufficient file permission restrictions. An attacker could exploit this vulnerability by sending a crafted command from the local CLI to the application. A successful exploit could allow the attacker to read arbitrary files on the underlying OS of the affected device. The attacker would need to have valid user credentials to exploit this vulnerability.
{
"affected": [],
"aliases": [
"CVE-2021-1258"
],
"database_specific": {
"cwe_ids": [
"CWE-269"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2021-01-13T22:15:00Z",
"severity": "MODERATE"
},
"details": "A vulnerability in the upgrade component of Cisco AnyConnect Secure Mobility Client could allow an authenticated, local attacker with low privileges to read arbitrary files on the underlying operating system (OS) of an affected device. The vulnerability is due to insufficient file permission restrictions. An attacker could exploit this vulnerability by sending a crafted command from the local CLI to the application. A successful exploit could allow the attacker to read arbitrary files on the underlying OS of the affected device. The attacker would need to have valid user credentials to exploit this vulnerability.",
"id": "GHSA-8f4f-mpwv-cr26",
"modified": "2022-05-24T17:39:11Z",
"published": "2022-05-24T17:39:11Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2021-1258"
},
{
"type": "WEB",
"url": "https://kc.mcafee.com/corporate/index?page=content\u0026id=SB10382"
},
{
"type": "WEB",
"url": "https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-anyconnect-fileread-PbHbgHMj"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N",
"type": "CVSS_V3"
}
]
}
GHSA-8F6F-8JCG-WCXV
Vulnerability from github – Published: 2022-05-24 19:07 – Updated: 2022-06-29 00:00VMware Thinapp version 5.x prior to 5.2.10 contain a DLL hijacking vulnerability due to insecure loading of DLLs. A malicious actor with non-administrative privileges may exploit this vulnerability to elevate privileges to administrator level on the Windows operating system having VMware ThinApp installed on it.
{
"affected": [],
"aliases": [
"CVE-2021-22000"
],
"database_specific": {
"cwe_ids": [
"CWE-269"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2021-07-13T19:15:00Z",
"severity": "HIGH"
},
"details": "VMware Thinapp version 5.x prior to 5.2.10 contain a DLL hijacking vulnerability due to insecure loading of DLLs. A malicious actor with non-administrative privileges may exploit this vulnerability to elevate privileges to administrator level on the Windows operating system having VMware ThinApp installed on it.",
"id": "GHSA-8f6f-8jcg-wcxv",
"modified": "2022-06-29T00:00:44Z",
"published": "2022-05-24T19:07:33Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2021-22000"
},
{
"type": "WEB",
"url": "https://www.vmware.com/security/advisories/VMSA-2021-0015.html"
},
{
"type": "WEB",
"url": "http://packetstormsecurity.com/files/163521/VMware-ThinApp-DLL-Hijacking.html"
},
{
"type": "WEB",
"url": "http://seclists.org/fulldisclosure/2021/Jul/35"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H",
"type": "CVSS_V3"
}
]
}
GHSA-8F7X-36QV-2PRX
Vulnerability from github – Published: 2022-07-20 00:00 – Updated: 2022-07-30 00:00A privilege escalation vulnerability was identified in the CLI command of Zyxel USG FLEX 100(W) firmware versions 4.50 through 5.30, USG FLEX 200 firmware versions 4.50 through 5.30, USG FLEX 500 firmware versions 4.50 through 5.30, USG FLEX 700 firmware versions 4.50 through 5.30, USG FLEX 50(W) firmware versions 4.16 through 5.30, USG20(W)-VPN firmware versions 4.16 through 5.30, ATP series firmware versions 4.32 through 5.30, VPN series firmware versions 4.30 through 5.30, USG/ZyWALL series firmware versions 4.09 through 4.72, which could allow a local attacker to execute some OS commands with root privileges in some directories on a vulnerable device.
{
"affected": [],
"aliases": [
"CVE-2022-30526"
],
"database_specific": {
"cwe_ids": [
"CWE-269"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2022-07-19T06:15:00Z",
"severity": "HIGH"
},
"details": "A privilege escalation vulnerability was identified in the CLI command of Zyxel USG FLEX 100(W) firmware versions 4.50 through 5.30, USG FLEX 200 firmware versions 4.50 through 5.30, USG FLEX 500 firmware versions 4.50 through 5.30, USG FLEX 700 firmware versions 4.50 through 5.30, USG FLEX 50(W) firmware versions 4.16 through 5.30, USG20(W)-VPN firmware versions 4.16 through 5.30, ATP series firmware versions 4.32 through 5.30, VPN series firmware versions 4.30 through 5.30, USG/ZyWALL series firmware versions 4.09 through 4.72, which could allow a local attacker to execute some OS commands with root privileges in some directories on a vulnerable device.",
"id": "GHSA-8f7x-36qv-2prx",
"modified": "2022-07-30T00:00:16Z",
"published": "2022-07-20T00:00:25Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2022-30526"
},
{
"type": "WEB",
"url": "https://www.zyxel.com/support/Zyxel-security-advisory-authenticated-directory-traversal-vulnerabilities-of-firewalls.shtml"
},
{
"type": "WEB",
"url": "http://packetstormsecurity.com/files/168202/Zyxel-Firewall-SUID-Binary-Privilege-Escalation.html"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H",
"type": "CVSS_V3"
}
]
}
GHSA-8FC2-FHH6-F6M5
Vulnerability from github – Published: 2025-02-13 00:33 – Updated: 2025-02-24 19:03An issue in Alex Tselegidis EasyAppointments v.1.5.0 allows a remote attacker to escalate privileges via the index.php file.
{
"affected": [
{
"package": {
"ecosystem": "Packagist",
"name": "alextselegidis/easyappointments"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"last_affected": "1.5.0"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2024-57602"
],
"database_specific": {
"cwe_ids": [
"CWE-269",
"CWE-307"
],
"github_reviewed": true,
"github_reviewed_at": "2025-02-24T19:03:38Z",
"nvd_published_at": "2025-02-12T22:15:40Z",
"severity": "CRITICAL"
},
"details": "An issue in Alex Tselegidis EasyAppointments v.1.5.0 allows a remote attacker to escalate privileges via the index.php file.",
"id": "GHSA-8fc2-fhh6-f6m5",
"modified": "2025-02-24T19:03:38Z",
"published": "2025-02-13T00:33:07Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2024-57602"
},
{
"type": "PACKAGE",
"url": "https://github.com/alextselegidis/easyappointments"
},
{
"type": "WEB",
"url": "https://hkohi.ca/vulnerability/12"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H",
"type": "CVSS_V3"
}
],
"summary": "Easy!Appointments Improper Restriction of Excessive Authentication Attempts "
}
GHSA-8FQH-PM2Q-8H5V
Vulnerability from github – Published: 2025-07-08 18:31 – Updated: 2026-01-20 15:31A potential security vulnerability has been identified in the HP Support Assistant, which allows a local attacker to escalate privileges via an arbitrary file deletion.
{
"affected": [],
"aliases": [
"CVE-2025-43019"
],
"database_specific": {
"cwe_ids": [
"CWE-269"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2025-07-08T16:15:57Z",
"severity": "MODERATE"
},
"details": "A potential security vulnerability has been identified in the HP Support Assistant, which allows a local attacker to escalate privileges via an arbitrary file deletion.",
"id": "GHSA-8fqh-pm2q-8h5v",
"modified": "2026-01-20T15:31:20Z",
"published": "2025-07-08T18:31:43Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2025-43019"
},
{
"type": "WEB",
"url": "https://support.hp.com/us-en/document/ish_12715930-12715980-16/hpsbgn04031"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H",
"type": "CVSS_V3"
},
{
"score": "CVSS:4.0/AV:L/AC:L/AT:P/PR:L/UI:N/VC:L/VI:L/VA:H/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X",
"type": "CVSS_V4"
}
]
}
GHSA-8FV5-24P8-44H5
Vulnerability from github – Published: 2026-07-09 21:31 – Updated: 2026-07-16 15:32A privilege escalation vulnerability in Palo Alto Networks Cortex® XDR Broker VM enables a locally authenticated user to perform actions as the root user.
{
"affected": [],
"aliases": [
"CVE-2026-0276"
],
"database_specific": {
"cwe_ids": [
"CWE-269"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2026-07-09T20:16:24Z",
"severity": "LOW"
},
"details": "A privilege escalation vulnerability in Palo Alto Networks Cortex\u00ae XDR Broker VM enables a locally authenticated user to perform actions as the root user.",
"id": "GHSA-8fv5-24p8-44h5",
"modified": "2026-07-16T15:32:57Z",
"published": "2026-07-09T21:31:21Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-0276"
},
{
"type": "WEB",
"url": "https://security.paloaltonetworks.com/CVE-2026-0276"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H",
"type": "CVSS_V3"
},
{
"score": "CVSS:4.0/AV:L/AC:L/AT:N/PR:L/UI:N/VC:L/VI:L/VA:L/SC:N/SI:N/SA:N/E:U/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:N/R:U/V:D/RE:M/U:Amber",
"type": "CVSS_V4"
}
]
}
GHSA-8FWW-MPG6-C4WQ
Vulnerability from github – Published: 2022-03-11 00:02 – Updated: 2022-03-18 00:01In vpu, there is a possible escalation of privilege due to a missing permission check. This could lead to local escalation of privilege with System execution privileges needed. User interaction is not needed for exploitation. Patch ID: ALPS05954679; Issue ID: ALPS05954679.
{
"affected": [],
"aliases": [
"CVE-2022-20049"
],
"database_specific": {
"cwe_ids": [
"CWE-269"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2022-03-10T17:45:00Z",
"severity": "MODERATE"
},
"details": "In vpu, there is a possible escalation of privilege due to a missing permission check. This could lead to local escalation of privilege with System execution privileges needed. User interaction is not needed for exploitation. Patch ID: ALPS05954679; Issue ID: ALPS05954679.",
"id": "GHSA-8fww-mpg6-c4wq",
"modified": "2022-03-18T00:01:23Z",
"published": "2022-03-11T00:02:22Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2022-20049"
},
{
"type": "WEB",
"url": "https://corp.mediatek.com/product-security-bulletin/March-2022"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:L/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:H",
"type": "CVSS_V3"
}
]
}
GHSA-8FXC-WRXG-769W
Vulnerability from github – Published: 2026-07-28 12:31 – Updated: 2026-07-28 12:31The Eazy Plugin Manager – Powerful Plugin Management Solution for WordPress plugin for WordPress is vulnerable to Privilege Escalation in all versions up to, and including, 4.4.1. This is due to insufficient authorization on the wp_ajax_pos_get_option AJAX handler, which verifies only a nonce that is localized to every logged-in admin-area user via admin_enqueue_scripts — without any capability check — before returning the value of any arbitrary WordPress option via get_option(), combined with the admin_login_endpoint_handler REST endpoint (GET /wp-json/epm/v1/admin/login) being registered as publicly accessible and authenticating callers solely by a whirlpool hash of values stored in those same options. This makes it possible for authenticated attackers, with Subscriber-level access and above, to read the site_url, connection_key, and remote_user_id values stored in the eazywp_connecting_info and eazywp_connection options, compute the required auth_key, call the admin/login REST endpoint to obtain Administrator authentication cookies, and fully take over the site. Exploitation requires the plugin's remote connection feature to have been configured, as the eazywp_connecting_info and eazywp_connection options must be populated with valid credentials.
{
"affected": [],
"aliases": [
"CVE-2026-14328"
],
"database_specific": {
"cwe_ids": [
"CWE-269"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2026-07-28T10:16:48Z",
"severity": "HIGH"
},
"details": "The Eazy Plugin Manager \u2013 Powerful Plugin Management Solution for WordPress plugin for WordPress is vulnerable to Privilege Escalation in all versions up to, and including, 4.4.1. This is due to insufficient authorization on the `wp_ajax_pos_get_option` AJAX handler, which verifies only a nonce that is localized to every logged-in admin-area user via `admin_enqueue_scripts` \u2014 without any capability check \u2014 before returning the value of any arbitrary WordPress option via `get_option()`, combined with the `admin_login_endpoint_handler` REST endpoint (`GET /wp-json/epm/v1/admin/login`) being registered as publicly accessible and authenticating callers solely by a whirlpool hash of values stored in those same options. This makes it possible for authenticated attackers, with Subscriber-level access and above, to read the `site_url`, `connection_key`, and `remote_user_id` values stored in the `eazywp_connecting_info` and `eazywp_connection` options, compute the required `auth_key`, call the `admin/login` REST endpoint to obtain Administrator authentication cookies, and fully take over the site. Exploitation requires the plugin\u0027s remote connection feature to have been configured, as the `eazywp_connecting_info` and `eazywp_connection` options must be populated with valid credentials.",
"id": "GHSA-8fxc-wrxg-769w",
"modified": "2026-07-28T12:31:19Z",
"published": "2026-07-28T12:31:19Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-14328"
},
{
"type": "WEB",
"url": "https://plugins.trac.wordpress.org/browser/plugins-on-steroids/tags/4.4.1/libs/class.rest_api.php#L1478"
},
{
"type": "WEB",
"url": "https://plugins.trac.wordpress.org/browser/plugins-on-steroids/tags/4.4.1/libs/class.rest_api.php#L263"
},
{
"type": "WEB",
"url": "https://plugins.trac.wordpress.org/browser/plugins-on-steroids/tags/4.4.1/libs/class.rest_api.php#L46"
},
{
"type": "WEB",
"url": "https://plugins.trac.wordpress.org/browser/plugins-on-steroids/tags/4.4.1/plugins-on-steroids.php#L1153"
},
{
"type": "WEB",
"url": "https://plugins.trac.wordpress.org/browser/plugins-on-steroids/tags/4.4.1/plugins-on-steroids.php#L1221"
},
{
"type": "WEB",
"url": "https://plugins.trac.wordpress.org/browser/plugins-on-steroids/tags/4.4.1/plugins-on-steroids.php#L446"
},
{
"type": "WEB",
"url": "https://www.wordfence.com/threat-intel/vulnerabilities/id/23a73680-ed13-4250-95e8-2933403f54e6?source=cve"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H",
"type": "CVSS_V3"
}
]
}
GHSA-8G2P-PQM3-FCFH
Vulnerability from github – Published: 2026-06-01 14:23 – Updated: 2026-06-01 14:23Summary
Type: Privilege escalation / cross-tenant member injection. The POST /workspaces/{workspace_id}/members endpoint is gated only by require_workspace_member(workspace_id) (default min_role="member") and forwards the request body's user_id and role straight into MemberService.add(workspace_id, user_id, role), which has no caller-permission check. A user with the lowest workspace privilege can add any user (including a new attacker-controlled second account, or an existing account they want to grief) as owner of the workspace.
File: src/praisonai-platform/praisonai_platform/api/routes/workspaces.py, lines 92-101; services/member_service.py, lines 26-38.
Root cause: MemberService.add validates only that role is in VALID_ROLES = {"owner", "admin", "member"} — the value, not the caller's right to assign it. The route's Depends(require_workspace_member) resolves to the default min_role="member". So a member-level token plus one POST gives the attacker an alternate identity with owner role inside the same workspace, bypassing every owner-only operation that would otherwise gate them.
Affected Code
File 1: src/praisonai-platform/praisonai_platform/api/routes/workspaces.py, lines 92-101.
@router.post("/{workspace_id}/members", response_model=MemberResponse, status_code=status.HTTP_201_CREATED)
async def add_member(
workspace_id: str,
body: MemberAdd,
user: AuthIdentity = Depends(require_workspace_member), # <-- BUG: defaults to min_role="member"
session: AsyncSession = Depends(get_db),
):
member_svc = MemberService(session)
member = await member_svc.add(workspace_id, body.user_id, body.role) # <-- writes any (user, role)
return MemberResponse.model_validate(member)
File 2: src/praisonai-platform/praisonai_platform/services/member_service.py, lines 26-38.
async def add(
self,
workspace_id: str,
user_id: str,
role: str = "member",
) -> Member:
"""Add a user to a workspace."""
if role not in VALID_ROLES: # only validates the value
raise ValueError(f"Invalid role: {role}. Must be one of {VALID_ROLES}")
member = Member(workspace_id=workspace_id, user_id=user_id, role=role)
self._session.add(member) # <-- BUG: no caller-permission check
await self._session.flush()
return member
Why it's wrong: workspace member management is the textbook capability that must be gated on owner role. The role hierarchy is implemented (MemberService.has_role, member_service.py:80-96), the dependency-tunable min_role parameter exists (require_workspace_member(min_role), deps.py:58), but the POST .../members route uses neither. The VALID_ROLES enum check is purely cosmetic — it accepts "owner" from any caller because the route never asked whether the caller has the right to assign that role.
Exploit Chain
- Attacker registers two accounts (or recruits a member account on the target workspace
W). Account A is an existing member ofW; Account B is a fresh signup the attacker controls (any account on the platform —auth/registeris open by default). State: attacker holds tokens for both A and B. - Attacker authenticates as Account A and POSTs
Authorization: Bearer <A_jwt>toPOST /workspaces/W/memberswith body{"user_id": "<B_user_id>", "role": "owner"}. State: control flow entersadd_member. require_workspace_member(W, A)passes (A is a member).MemberService.add(W, B, "owner")writes a new rowMember(workspace_id=W, user_id=B, role="owner"). State: Account B is now a workspace-W owner.- Attacker switches to Account B and acts as workspace owner — change settings, add/remove members, delete the workspace, or pivot to the companion advisories' primitives. State: attacker holds owner of any workspace they had member access to, via a fresh attacker-controlled identity that the original workspace's audit logs cannot easily attribute to A.
- Final state: with one member-level token plus one POST, the attacker plants an owner-role identity on any workspace they can reach. The same primitive lets the attacker invite a competitor or external-vendor account into the workspace as owner, exfiltrating the workspace's content under that competitor's name.
Security Impact
Severity: sec-critical. CVSS 9.1: network attack, low complexity, low privileges (member tier), no user interaction, scope changed (the new owner is a different security principal), high confidentiality and integrity, no availability claim.
Attacker capability: with one workspace-member token plus one POST request, the attacker grants owner-tier access to any user_id on the platform. From there, full workspace control via the Account B token, plus indirect attribution: the original workspace's audit logs see "user A added user B as owner" but the audit trail cannot tell that B is attacker-controlled.
Preconditions: praisonai-platform is deployed multi-tenant; the attacker has any membership token in the target workspace; the attacker can register or knows any other user_id on the platform.
Differential: source-inspection-verified. The asymmetry between MemberService.has_role (clearly tiered) and add_member's default min_role="member" confirms the gap. With the suggested fix below, the gate refuses the member-tier token, the elevated POST returns 403, and the second-identity owner is never created.
Suggested Fix
--- a/src/praisonai-platform/praisonai_platform/api/routes/workspaces.py
+++ b/src/praisonai-platform/praisonai_platform/api/routes/workspaces.py
@@ -90,11 +90,15 @@
+def _require_workspace_owner(workspace_id: str, user, session):
+ return require_workspace_member(workspace_id, user, session, min_role="owner")
+
@router.post("/{workspace_id}/members", response_model=MemberResponse, status_code=status.HTTP_201_CREATED)
async def add_member(
workspace_id: str,
body: MemberAdd,
- user: AuthIdentity = Depends(require_workspace_member),
+ user: AuthIdentity = Depends(_require_workspace_owner),
session: AsyncSession = Depends(get_db),
):
member_svc = MemberService(session)
+ if body.role == "owner" and not await member_svc.has_role(workspace_id, user.id, "owner"):
+ raise HTTPException(status_code=403, detail="Only owners can add other owners")
member = await member_svc.add(workspace_id, body.user_id, body.role)
The four other workspace mutation endpoints (update_workspace, delete_workspace, update_member_role, remove_member) exhibit the same default-min-role gap and are filed as their own advisories.
{
"affected": [
{
"package": {
"ecosystem": "PyPI",
"name": "praisonai-platform"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "0.1.4"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-47413"
],
"database_specific": {
"cwe_ids": [
"CWE-269",
"CWE-862"
],
"github_reviewed": true,
"github_reviewed_at": "2026-06-01T14:23:39Z",
"nvd_published_at": null,
"severity": "CRITICAL"
},
"details": "## Summary\n\n**Type:** Privilege escalation / cross-tenant member injection. The `POST /workspaces/{workspace_id}/members` endpoint is gated only by `require_workspace_member(workspace_id)` (default `min_role=\"member\"`) and forwards the request body\u0027s `user_id` and `role` straight into `MemberService.add(workspace_id, user_id, role)`, which has no caller-permission check. A user with the lowest workspace privilege can add any user (including a new attacker-controlled second account, or an existing account they want to grief) as owner of the workspace.\n**File:** `src/praisonai-platform/praisonai_platform/api/routes/workspaces.py`, lines 92-101; `services/member_service.py`, lines 26-38.\n**Root cause:** `MemberService.add` validates only that `role` is in `VALID_ROLES = {\"owner\", \"admin\", \"member\"}` \u2014 the value, not the caller\u0027s right to assign it. The route\u0027s `Depends(require_workspace_member)` resolves to the default `min_role=\"member\"`. So a member-level token plus one POST gives the attacker an alternate identity with owner role inside the same workspace, bypassing every owner-only operation that *would* otherwise gate them.\n\n## Affected Code\n\n**File 1:** `src/praisonai-platform/praisonai_platform/api/routes/workspaces.py`, lines 92-101.\n\n```python\n@router.post(\"/{workspace_id}/members\", response_model=MemberResponse, status_code=status.HTTP_201_CREATED)\nasync def add_member(\n workspace_id: str,\n body: MemberAdd,\n user: AuthIdentity = Depends(require_workspace_member), # \u003c-- BUG: defaults to min_role=\"member\"\n session: AsyncSession = Depends(get_db),\n):\n member_svc = MemberService(session)\n member = await member_svc.add(workspace_id, body.user_id, body.role) # \u003c-- writes any (user, role)\n return MemberResponse.model_validate(member)\n```\n\n**File 2:** `src/praisonai-platform/praisonai_platform/services/member_service.py`, lines 26-38.\n\n```python\nasync def add(\n self,\n workspace_id: str,\n user_id: str,\n role: str = \"member\",\n) -\u003e Member:\n \"\"\"Add a user to a workspace.\"\"\"\n if role not in VALID_ROLES: # only validates the value\n raise ValueError(f\"Invalid role: {role}. Must be one of {VALID_ROLES}\")\n member = Member(workspace_id=workspace_id, user_id=user_id, role=role)\n self._session.add(member) # \u003c-- BUG: no caller-permission check\n await self._session.flush()\n return member\n```\n\n**Why it\u0027s wrong:** workspace member management is the textbook capability that must be gated on owner role. The role hierarchy is implemented (`MemberService.has_role`, member_service.py:80-96), the dependency-tunable `min_role` parameter exists (`require_workspace_member(min_role)`, deps.py:58), but the `POST .../members` route uses neither. The `VALID_ROLES` enum check is purely cosmetic \u2014 it accepts `\"owner\"` from any caller because the route never asked whether the caller has the right to assign that role.\n\n## Exploit Chain\n\n1. Attacker registers two accounts (or recruits a member account on the target workspace `W`). Account A is an existing member of `W`; Account B is a fresh signup the attacker controls (any account on the platform \u2014 `auth/register` is open by default). State: attacker holds tokens for both A and B.\n2. Attacker authenticates as Account A and POSTs `Authorization: Bearer \u003cA_jwt\u003e` to `POST /workspaces/W/members` with body `{\"user_id\": \"\u003cB_user_id\u003e\", \"role\": \"owner\"}`. State: control flow enters `add_member`.\n3. `require_workspace_member(W, A)` passes (A is a member). `MemberService.add(W, B, \"owner\")` writes a new row `Member(workspace_id=W, user_id=B, role=\"owner\")`. State: Account B is now a workspace-W owner.\n4. Attacker switches to Account B and acts as workspace owner \u2014 change settings, add/remove members, delete the workspace, or pivot to the companion advisories\u0027 primitives. State: attacker holds owner of any workspace they had member access to, via a fresh attacker-controlled identity that the original workspace\u0027s audit logs cannot easily attribute to A.\n5. Final state: with one member-level token plus one POST, the attacker plants an owner-role identity on any workspace they can reach. The same primitive lets the attacker invite a competitor or external-vendor account into the workspace as owner, exfiltrating the workspace\u0027s content under that competitor\u0027s name.\n\n## Security Impact\n\n**Severity:** sec-critical. CVSS 9.1: network attack, low complexity, low privileges (member tier), no user interaction, scope changed (the new owner is a different security principal), high confidentiality and integrity, no availability claim.\n**Attacker capability:** with one workspace-member token plus one POST request, the attacker grants owner-tier access to any user_id on the platform. From there, full workspace control via the Account B token, plus indirect attribution: the original workspace\u0027s audit logs see \"user A added user B as owner\" but the audit trail cannot tell that B is attacker-controlled.\n**Preconditions:** `praisonai-platform` is deployed multi-tenant; the attacker has any membership token in the target workspace; the attacker can register or knows any other user_id on the platform.\n**Differential:** source-inspection-verified. The asymmetry between `MemberService.has_role` (clearly tiered) and `add_member`\u0027s default `min_role=\"member\"` confirms the gap. With the suggested fix below, the gate refuses the member-tier token, the elevated POST returns 403, and the second-identity owner is never created.\n\n## Suggested Fix\n\n```diff\n--- a/src/praisonai-platform/praisonai_platform/api/routes/workspaces.py\n+++ b/src/praisonai-platform/praisonai_platform/api/routes/workspaces.py\n@@ -90,11 +90,15 @@\n+def _require_workspace_owner(workspace_id: str, user, session):\n+ return require_workspace_member(workspace_id, user, session, min_role=\"owner\")\n+\n @router.post(\"/{workspace_id}/members\", response_model=MemberResponse, status_code=status.HTTP_201_CREATED)\n async def add_member(\n workspace_id: str,\n body: MemberAdd,\n- user: AuthIdentity = Depends(require_workspace_member),\n+ user: AuthIdentity = Depends(_require_workspace_owner),\n session: AsyncSession = Depends(get_db),\n ):\n member_svc = MemberService(session)\n+ if body.role == \"owner\" and not await member_svc.has_role(workspace_id, user.id, \"owner\"):\n+ raise HTTPException(status_code=403, detail=\"Only owners can add other owners\")\n member = await member_svc.add(workspace_id, body.user_id, body.role)\n```\n\nThe four other workspace mutation endpoints (`update_workspace`, `delete_workspace`, `update_member_role`, `remove_member`) exhibit the same default-min-role gap and are filed as their own advisories.",
"id": "GHSA-8g2p-pqm3-fcfh",
"modified": "2026-06-01T14:23:39Z",
"published": "2026-06-01T14:23:39Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/MervinPraison/PraisonAI/security/advisories/GHSA-8g2p-pqm3-fcfh"
},
{
"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:C/C:H/I:H/A:N",
"type": "CVSS_V3"
}
],
"summary": "praisonai-platform: Any workspace member can add arbitrary user as owner via POST /workspaces/{id}/members"
}
Mitigation MIT-1
Very carefully manage the setting, management, and handling of privileges. Explicitly manage trust zones in the software.
Mitigation MIT-48
Strategy: Separation of Privilege
Follow the principle of least privilege when assigning access rights to entities in a software system.
Mitigation MIT-49
Strategy: Separation of Privilege
Consider following the principle of separation of privilege. Require multiple conditions to be met before permitting access to a system resource.
CAPEC-122: Privilege Abuse
An adversary is able to exploit features of the target that should be reserved for privileged users or administrators but are exposed to use by lower or non-privileged accounts. Access to sensitive information and functionality must be controlled to ensure that only authorized users are able to access these resources.
CAPEC-233: Privilege Escalation
An adversary exploits a weakness enabling them to elevate their privilege and perform an action that they are not supposed to be authorized to perform.
CAPEC-58: Restful Privilege Elevation
An adversary identifies a Rest HTTP (Get, Put, Delete) style permission method allowing them to perform various malicious actions upon server data due to lack of access control mechanisms implemented within the application service accepting HTTP messages.