Common Weakness Enumeration

CWE-639

Allowed

Authorization Bypass Through User-Controlled Key

Abstraction: Base · Status: Incomplete

The system's authorization functionality does not prevent one user from gaining access to another user's data or record by modifying the key value identifying the data.

3254 vulnerabilities reference this CWE, most recent first.

GHSA-92CG-GHQ6-9587

Vulnerability from github – Published: 2023-12-12 03:31 – Updated: 2024-09-30 18:52
VLAI
Summary
Duplicate Advisory: Privilege escalation in sap/cloud-security-client-go
Details

Duplicate Advisory

This advisory has been withdrawn because it is a duplicate of GHSA-m8rw-rcpq-2vp2. This link is maintained to preserve external references.

Original Description

SAP BTP Security Services Integration Library ([Golang] github.com/sap/cloud-security-client-go) - versions < 0.17.0, allow under certain conditions an escalation of privileges. On successful exploitation, an unauthenticated attacker can obtain arbitrary permissions within the application.

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "Go",
        "name": "github.com/sap/cloud-security-client-go"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "0.17.0"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [],
  "database_specific": {
    "cwe_ids": [
      "CWE-269",
      "CWE-639",
      "CWE-749"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2023-12-15T03:39:45Z",
    "nvd_published_at": "2023-12-12T03:15:07Z",
    "severity": "CRITICAL"
  },
  "details": "## Duplicate Advisory\nThis advisory has been withdrawn because it is a duplicate of GHSA-m8rw-rcpq-2vp2. This link is maintained to preserve external references.\n\n## Original Description\nSAP\u00a0BTP\u00a0Security Services Integration Library ([Golang] github.com/sap/cloud-security-client-go) - versions \u003c 0.17.0, allow under certain conditions an escalation of privileges. On successful exploitation, an unauthenticated attacker can obtain arbitrary permissions within the application.\n\n",
  "id": "GHSA-92cg-ghq6-9587",
  "modified": "2024-09-30T18:52:24Z",
  "published": "2023-12-12T03:31:45Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/SAP/cloud-security-services-integration-library/security/advisories/GHSA-59c9-pxq8-9c73"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2023-50424"
    },
    {
      "type": "WEB",
      "url": "https://github.com/SAP/cloud-security-client-go/commit/2e3bd63e152e09f267316a1071034eb5d4b7f498"
    },
    {
      "type": "WEB",
      "url": "https://blogs.sap.com/2023/12/12/unveiling-critical-security-updates-sap-btp-security-note-3411067"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/SAP/cloud-security-client-go"
    },
    {
      "type": "WEB",
      "url": "https://me.sap.com/notes/3411067"
    },
    {
      "type": "WEB",
      "url": "https://pkg.go.dev/github.com/sap/cloud-security-client-go@v0.17.0"
    },
    {
      "type": "WEB",
      "url": "https://www.sap.com/documents/2022/02/fa865ea4-167e-0010-bca6-c68f7e60039b.html"
    }
  ],
  "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:N",
      "type": "CVSS_V3"
    }
  ],
  "summary": "Duplicate Advisory: Privilege escalation in sap/cloud-security-client-go",
  "withdrawn": "2024-09-30T18:52:24Z"
}

GHSA-92QM-MQ2F-95W2

Vulnerability from github – Published: 2024-05-02 18:30 – Updated: 2026-04-08 18:33
VLAI
Details

The FileBird – WordPress Media Library Folders & File Manager plugin for WordPress is vulnerable to Insecure Direct Object Reference in all versions up to, and including, 5.6.3 via folder deletion due to missing validation on a user controlled key. This makes it possible for authenticated attackers, with author access or higher, to delete folders created by other users and make their file uploads visible.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2024-2346"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-639"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2024-05-02T17:15:16Z",
    "severity": "MODERATE"
  },
  "details": "The FileBird \u2013 WordPress Media Library Folders \u0026 File Manager plugin for WordPress is vulnerable to Insecure Direct Object Reference in all versions up to, and including, 5.6.3 via folder deletion due to missing validation on a user controlled key. This makes it possible for authenticated attackers, with author access or higher, to delete folders created by other users and make their file uploads visible.",
  "id": "GHSA-92qm-mq2f-95w2",
  "modified": "2026-04-08T18:33:03Z",
  "published": "2024-05-02T18:30:53Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2024-2346"
    },
    {
      "type": "WEB",
      "url": "https://plugins.trac.wordpress.org/changeset?sfp_email=\u0026sfph_mail=\u0026reponame=\u0026new=3060898%40filebird%2Ftrunk\u0026old=3049188%40filebird%2Ftrunk\u0026sfp_email=\u0026sfph_mail="
    },
    {
      "type": "WEB",
      "url": "https://www.wordfence.com/threat-intel/vulnerabilities/id/82cde234-ae87-438f-911e-bdd0e3ac1132?source=cve"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:L/A:N",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-9324-W765-4VQ2

Vulnerability from github – Published: 2026-06-29 09:30 – Updated: 2026-06-29 09:30
VLAI
Details

Authorization Bypass Through User-Controlled Key vulnerability in Matteo Manna Simple User Avatar allows Exploiting Incorrectly Configured Access Control Security Levels.

This issue affects Simple User Avatar: from n/a through 4.9.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2026-57676"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-639"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2026-06-29T09:16:31Z",
    "severity": "MODERATE"
  },
  "details": "Authorization Bypass Through User-Controlled Key vulnerability in Matteo Manna Simple User Avatar allows Exploiting Incorrectly Configured Access Control Security Levels.\n\nThis issue affects Simple User Avatar: from n/a through 4.9.",
  "id": "GHSA-9324-w765-4vq2",
  "modified": "2026-06-29T09:30:29Z",
  "published": "2026-06-29T09:30:29Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-57676"
    },
    {
      "type": "WEB",
      "url": "https://patchstack.com/database/wordpress/plugin/simple-user-avatar/vulnerability/wordpress-simple-user-avatar-plugin-4-9-insecure-direct-object-references-idor-vulnerability?_s_id=cve"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-93RH-HCCW-9Q28

Vulnerability from github – Published: 2025-09-30 12:30 – Updated: 2025-10-08 21:30
VLAI
Details

Insecure Direct Object Reference (IDOR) vulnerability in BOLD Workplanner in versions prior to 2.5.25 (4935b438f9b), consisting of a lack of adequate validation of user input, allowing an authenticated user to access to calendar details using unauthorised internal identifiers.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2025-41091"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-639"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2025-09-30T11:37:39Z",
    "severity": "HIGH"
  },
  "details": "Insecure Direct Object Reference (IDOR) vulnerability in BOLD Workplanner in versions prior to 2.5.25 (4935b438f9b), consisting of a lack of adequate validation of user input, allowing an authenticated user to\u00a0access to calendar details using unauthorised internal identifiers.",
  "id": "GHSA-93rh-hccw-9q28",
  "modified": "2025-10-08T21:30:23Z",
  "published": "2025-09-30T12:30:51Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2025-41091"
    },
    {
      "type": "WEB",
      "url": "https://www.incibe.es/en/incibe-cert/notices/aviso/insecure-direct-object-reference-gps-bold-workplanner"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N",
      "type": "CVSS_V3"
    },
    {
      "score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:N/VA:N/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-943C-GHG8-8G2W

Vulnerability from github – Published: 2026-02-05 12:30 – Updated: 2026-02-05 12:30
VLAI
Details

The ProfileGrid – User Profiles, Groups and Communities plugin for WordPress is vulnerable to Insecure Direct Object Reference in all versions up to, and including, 5.9.7.2 via the 'pm_upload_image' and 'pm_upload_cover_image' AJAX actions. This is due to the update_user_meta() function being called outside of the user authorization check in public/partials/crop.php and public/partials/coverimg_crop.php. This makes it possible for authenticated attackers, with Subscriber-level access and above, to change any user's profile picture or cover image, including administrators.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2026-1271"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-639"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2026-02-05T10:16:03Z",
    "severity": "MODERATE"
  },
  "details": "The ProfileGrid \u2013 User Profiles, Groups and Communities plugin for WordPress is vulnerable to Insecure Direct Object Reference in all versions up to, and including, 5.9.7.2 via the \u0027pm_upload_image\u0027 and \u0027pm_upload_cover_image\u0027 AJAX actions. This is due to the update_user_meta() function being called outside of the user authorization check in public/partials/crop.php and public/partials/coverimg_crop.php. This makes it possible for authenticated attackers, with Subscriber-level access and above, to change any user\u0027s profile picture or cover image, including administrators.",
  "id": "GHSA-943c-ghg8-8g2w",
  "modified": "2026-02-05T12:30:25Z",
  "published": "2026-02-05T12:30:25Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-1271"
    },
    {
      "type": "WEB",
      "url": "https://plugins.trac.wordpress.org/browser/profilegrid-user-profiles-groups-and-communities/tags/5.9.6.7/public/partials/coverimg_crop.php#L60"
    },
    {
      "type": "WEB",
      "url": "https://plugins.trac.wordpress.org/browser/profilegrid-user-profiles-groups-and-communities/tags/5.9.6.7/public/partials/crop.php#L73"
    },
    {
      "type": "WEB",
      "url": "https://plugins.trac.wordpress.org/browser/profilegrid-user-profiles-groups-and-communities/trunk/public/partials/coverimg_crop.php#L60"
    },
    {
      "type": "WEB",
      "url": "https://plugins.trac.wordpress.org/browser/profilegrid-user-profiles-groups-and-communities/trunk/public/partials/crop.php#L73"
    },
    {
      "type": "WEB",
      "url": "https://plugins.trac.wordpress.org/changeset?sfp_email=\u0026sfph_mail=\u0026reponame=\u0026old=3448434%40profilegrid-user-profiles-groups-and-communities\u0026new=3448434%40profilegrid-user-profiles-groups-and-communities\u0026sfp_email=\u0026sfph_mail="
    },
    {
      "type": "WEB",
      "url": "https://www.wordfence.com/threat-intel/vulnerabilities/id/712535ce-8c38-4944-aa0a-36d9bacaeb67?source=cve"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-943M-6WX2-RC2J

Vulnerability from github – Published: 2026-06-01 14:17 – Updated: 2026-06-01 14:17
VLAI
Summary
praisonai-platform: Project endpoints accept any project_id without workspace ownership check, cross-workspace read/update/delete IDOR
Details

Summary

Type: Insecure Direct Object Reference. The project CRUD endpoints (GET / PATCH / DELETE /workspaces/{workspace_id}/projects/{project_id} and GET .../{project_id}/stats) gate access on require_workspace_member(workspace_id) only, then resolve project_id through ProjectService.get(project_id) / update(project_id, ...) / delete(project_id) / get_stats(project_id). None of these calls thread workspace_id through to constrain the lookup. A user who is a member of any workspace W1 can read, modify, delete, or read stats for projects that belong to a different workspace W2. File: src/praisonai-platform/praisonai_platform/services/project_service.py, lines 47-108; route handlers at src/praisonai-platform/praisonai_platform/api/routes/projects.py, lines 51-108. Root cause: identical to the agent and issue IDORs in this codebase. The route accepts workspace_id from URL, uses it solely for the membership gate, then calls ProjectService.get(project_id) which is session.get(Project, project_id) — a primary-key-only lookup with no workspace_id predicate. update and delete call self.get(project_id) first, inheriting the gap. get_stats likewise has no workspace check.

Affected Code

File 1: src/praisonai-platform/praisonai_platform/services/project_service.py, lines 47-108.

class ProjectService:
    ...

    async def get(self, project_id: str) -> Optional[Project]:
        """Get project by ID."""
        return await self._session.get(Project, project_id)         # <-- BUG: no workspace_id predicate

    async def update(
        self,
        project_id: str,
        ...
    ) -> Optional[Project]:
        project = await self.get(project_id)                        # <-- inherits the gap
        ...

    async def delete(self, project_id: str) -> bool:
        project = await self.get(project_id)                        # <-- inherits the gap
        ...

    async def get_stats(self, project_id: str) -> dict:
        ...                                                          # <-- also no workspace check; returns issue counts for any project

File 2: src/praisonai-platform/praisonai_platform/api/routes/projects.py, lines 51-108.

@router.get("/{project_id}", response_model=ProjectResponse)
async def get_project(
    workspace_id: str,
    project_id: str,
    user: AuthIdentity = Depends(require_workspace_member),
    session: AsyncSession = Depends(get_db),
):
    svc = ProjectService(session)
    project = await svc.get(project_id)                             # <-- workspace_id never threaded through
    if project is None:
        raise HTTPException(status_code=404, detail="Project not found")
    return ProjectResponse.model_validate(project)


@router.patch("/{project_id}", response_model=ProjectResponse)
async def update_project(...):
    svc = ProjectService(session)
    project = await svc.update(project_id, title=body.title, ...)   # <-- writes to any project in the DB

@router.delete("/{project_id}", ...)
async def delete_project(...):
    deleted = await svc.delete(project_id)                          # <-- deletes any project in the DB

@router.get("/{project_id}/stats")
async def project_stats(...):
    return await svc.get_stats(project_id)                          # <-- returns stats for any project in the DB

Why it's wrong: workspace_id from the route is treated as a UI hint (gates "are you in some workspace W?") rather than an authoritative predicate (should also gate "is the project you are addressing actually inside W?"). The MemberService in this same codebase uses a composite (workspace_id, user_id) key and demonstrates the safe pattern; the project service simply did not apply it.

Exploit Chain

  1. Attacker registers a workspace W_attacker (where they are a member) and harvests a target project UUID P_T. Project IDs leak through the activity feed (act_svc.log records entity_id), issue records (every issue carries project_id), webhook payloads, error messages, exported issue dumps, or operator screenshots. State: attacker holds P_T.
  2. Attacker authenticates and sends GET /workspaces/W_attacker/projects/P_T. require_workspace_member(W_attacker, attacker) passes. State: control flow enters get_project with workspace_id=W_attacker, project_id=P_T.
  3. ProjectService.get(P_T) runs session.get(Project, "P_T"), which is SELECT * FROM projects WHERE id = 'P_T' LIMIT 1 with no workspace_id filter. The row is returned: title, description (often the project's confidential roadmap), status, lead_type, lead_id, icon, created_at, workspace_id (the foreign workspace's UUID is itself disclosed). State: response body is the JSON-serialised foreign project.
  4. Attacker repeats with PATCH /workspaces/W_attacker/projects/P_T and {"title": "<reset>", "description": "<wiped>", "status": "archived"}. update_project calls svc.update(P_T, ...) and mutates the foreign row. State: target project is silently re-titled, re-described, and archived.
  5. Attacker calls DELETE /workspaces/W_attacker/projects/P_T to delete the foreign project entirely. State: target project is gone (every issue still referencing it now has a dangling project_id).
  6. Attacker calls GET /workspaces/W_attacker/projects/P_T/stats to read aggregate issue counts (open/closed/in-progress) for the foreign project — useful for competitive intelligence even when full-issue read is not possible.
  7. Final state: any attacker with one workspace-member token can enumerate, exfiltrate, rewrite, and delete every project in the multi-tenant deployment given the project UUIDs.

Security Impact

Severity: sec-high. CVSS: network attack, low complexity, low privileges, no user interaction, scope unchanged, high confidentiality (project content + cross-workspace metadata via the leaked workspace_id field), high integrity (arbitrary writes / deletes), no availability claim (issue rows survive parent-project deletion). Attacker capability: read, edit, archive, delete, and stats-fingerprint any project in the multi-tenant deployment given the project UUID. Beyond plain content disclosure, the response also includes workspace_id, allowing the attacker to map the deployment's workspace topology (which workspaces exist, which projects each owns). Preconditions: praisonai-platform is deployed multi-tenant; the attacker has any membership token; the target project's UUID is known or guessable. Differential: source-inspection-verified end-to-end. The asymmetry between ProjectService.get(project_id) (no workspace check) and MemberService.get(workspace_id, user_id) (composite key check) confirms the gap. With the suggested fix below, ProjectService.get(workspace_id, project_id) returns None for foreign-workspace projects and the route handler returns 404.

Suggested Fix

Same shape as the companion agent and issue advisories. Make the resource-lookup query include the workspace predicate; treat foreign-workspace rows as 404.

--- a/src/praisonai-platform/praisonai_platform/services/project_service.py
+++ b/src/praisonai-platform/praisonai_platform/services/project_service.py
@@ -45,9 +45,12 @@ class ProjectService:
         await self._session.flush()
         return project

-    async def get(self, project_id: str) -> Optional[Project]:
-        """Get project by ID."""
-        return await self._session.get(Project, project_id)
+    async def get(self, workspace_id: str, project_id: str) -> Optional[Project]:
+        """Get project by ID, scoped to a workspace."""
+        stmt = select(Project).where(
+            Project.id == project_id, Project.workspace_id == workspace_id
+        )
+        return (await self._session.execute(stmt)).scalar_one_or_none()

     async def update(
         self,
+        workspace_id: str,
         project_id: str,
         ...
     ) -> Optional[Project]:
-        project = await self.get(project_id)
+        project = await self.get(workspace_id, project_id)

-    async def delete(self, project_id: str) -> bool:
+    async def delete(self, workspace_id: str, project_id: str) -> bool:
-        project = await self.get(project_id)
+        project = await self.get(workspace_id, project_id)

-    async def get_stats(self, project_id: str) -> dict:
+    async def get_stats(self, workspace_id: str, project_id: str) -> dict:
+        # Also constrain the underlying issue counts query by workspace_id.

Update the route handlers in routes/projects.py to thread workspace_id through every call. The same single-key-lookup pattern is filed separately for AgentService, IssueService, CommentService, and LabelService.

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "PyPI",
        "name": "praisonai-platform"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "0.1.4"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-47418"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-639"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-06-01T14:17:04Z",
    "nvd_published_at": null,
    "severity": "HIGH"
  },
  "details": "## Summary\n\n**Type:** Insecure Direct Object Reference. The project CRUD endpoints (`GET / PATCH / DELETE /workspaces/{workspace_id}/projects/{project_id}` and `GET .../{project_id}/stats`) gate access on `require_workspace_member(workspace_id)` only, then resolve `project_id` through `ProjectService.get(project_id)` / `update(project_id, ...)` / `delete(project_id)` / `get_stats(project_id)`. None of these calls thread `workspace_id` through to constrain the lookup. A user who is a member of any workspace `W1` can read, modify, delete, or read stats for projects that belong to a different workspace `W2`.\n**File:** `src/praisonai-platform/praisonai_platform/services/project_service.py`, lines 47-108; route handlers at `src/praisonai-platform/praisonai_platform/api/routes/projects.py`, lines 51-108.\n**Root cause:** identical to the agent and issue IDORs in this codebase. The route accepts `workspace_id` from URL, uses it solely for the membership gate, then calls `ProjectService.get(project_id)` which is `session.get(Project, project_id)` \u2014 a primary-key-only lookup with no `workspace_id` predicate. `update` and `delete` call `self.get(project_id)` first, inheriting the gap. `get_stats` likewise has no workspace check.\n\n## Affected Code\n\n**File 1:** `src/praisonai-platform/praisonai_platform/services/project_service.py`, lines 47-108.\n\n```python\nclass ProjectService:\n    ...\n\n    async def get(self, project_id: str) -\u003e Optional[Project]:\n        \"\"\"Get project by ID.\"\"\"\n        return await self._session.get(Project, project_id)         # \u003c-- BUG: no workspace_id predicate\n\n    async def update(\n        self,\n        project_id: str,\n        ...\n    ) -\u003e Optional[Project]:\n        project = await self.get(project_id)                        # \u003c-- inherits the gap\n        ...\n\n    async def delete(self, project_id: str) -\u003e bool:\n        project = await self.get(project_id)                        # \u003c-- inherits the gap\n        ...\n\n    async def get_stats(self, project_id: str) -\u003e dict:\n        ...                                                          # \u003c-- also no workspace check; returns issue counts for any project\n```\n\n**File 2:** `src/praisonai-platform/praisonai_platform/api/routes/projects.py`, lines 51-108.\n\n```python\n@router.get(\"/{project_id}\", response_model=ProjectResponse)\nasync def get_project(\n    workspace_id: str,\n    project_id: str,\n    user: AuthIdentity = Depends(require_workspace_member),\n    session: AsyncSession = Depends(get_db),\n):\n    svc = ProjectService(session)\n    project = await svc.get(project_id)                             # \u003c-- workspace_id never threaded through\n    if project is None:\n        raise HTTPException(status_code=404, detail=\"Project not found\")\n    return ProjectResponse.model_validate(project)\n\n\n@router.patch(\"/{project_id}\", response_model=ProjectResponse)\nasync def update_project(...):\n    svc = ProjectService(session)\n    project = await svc.update(project_id, title=body.title, ...)   # \u003c-- writes to any project in the DB\n\n@router.delete(\"/{project_id}\", ...)\nasync def delete_project(...):\n    deleted = await svc.delete(project_id)                          # \u003c-- deletes any project in the DB\n\n@router.get(\"/{project_id}/stats\")\nasync def project_stats(...):\n    return await svc.get_stats(project_id)                          # \u003c-- returns stats for any project in the DB\n```\n\n**Why it\u0027s wrong:** `workspace_id` from the route is treated as a UI hint (gates \"are you in some workspace W?\") rather than an authoritative predicate (should also gate \"is the project you are addressing actually inside W?\"). The `MemberService` in this same codebase uses a composite `(workspace_id, user_id)` key and demonstrates the safe pattern; the project service simply did not apply it.\n\n## Exploit Chain\n\n1. Attacker registers a workspace `W_attacker` (where they are a member) and harvests a target project UUID `P_T`. Project IDs leak through the activity feed (`act_svc.log` records `entity_id`), issue records (every issue carries `project_id`), webhook payloads, error messages, exported issue dumps, or operator screenshots. State: attacker holds `P_T`.\n2. Attacker authenticates and sends `GET /workspaces/W_attacker/projects/P_T`. `require_workspace_member(W_attacker, attacker)` passes. State: control flow enters `get_project` with `workspace_id=W_attacker, project_id=P_T`.\n3. `ProjectService.get(P_T)` runs `session.get(Project, \"P_T\")`, which is `SELECT * FROM projects WHERE id = \u0027P_T\u0027 LIMIT 1` with no `workspace_id` filter. The row is returned: `title`, `description` (often the project\u0027s confidential roadmap), `status`, `lead_type`, `lead_id`, `icon`, `created_at`, `workspace_id` (the foreign workspace\u0027s UUID is itself disclosed). State: response body is the JSON-serialised foreign project.\n4. Attacker repeats with `PATCH /workspaces/W_attacker/projects/P_T` and `{\"title\": \"\u003creset\u003e\", \"description\": \"\u003cwiped\u003e\", \"status\": \"archived\"}`. `update_project` calls `svc.update(P_T, ...)` and mutates the foreign row. State: target project is silently re-titled, re-described, and archived.\n5. Attacker calls `DELETE /workspaces/W_attacker/projects/P_T` to delete the foreign project entirely. State: target project is gone (every issue still referencing it now has a dangling `project_id`).\n6. Attacker calls `GET /workspaces/W_attacker/projects/P_T/stats` to read aggregate issue counts (open/closed/in-progress) for the foreign project \u2014 useful for competitive intelligence even when full-issue read is not possible.\n7. Final state: any attacker with one workspace-member token can enumerate, exfiltrate, rewrite, and delete every project in the multi-tenant deployment given the project UUIDs.\n\n## Security Impact\n\n**Severity:** sec-high. CVSS: network attack, low complexity, low privileges, no user interaction, scope unchanged, high confidentiality (project content + cross-workspace metadata via the leaked `workspace_id` field), high integrity (arbitrary writes / deletes), no availability claim (issue rows survive parent-project deletion).\n**Attacker capability:** read, edit, archive, delete, and stats-fingerprint any project in the multi-tenant deployment given the project UUID. Beyond plain content disclosure, the response also includes `workspace_id`, allowing the attacker to map the deployment\u0027s workspace topology (which workspaces exist, which projects each owns).\n**Preconditions:** `praisonai-platform` is deployed multi-tenant; the attacker has any membership token; the target project\u0027s UUID is known or guessable.\n**Differential:** source-inspection-verified end-to-end. The asymmetry between `ProjectService.get(project_id)` (no workspace check) and `MemberService.get(workspace_id, user_id)` (composite key check) confirms the gap. With the suggested fix below, `ProjectService.get(workspace_id, project_id)` returns `None` for foreign-workspace projects and the route handler returns 404.\n\n## Suggested Fix\n\nSame shape as the companion agent and issue advisories. Make the resource-lookup query include the workspace predicate; treat foreign-workspace rows as 404.\n\n```diff\n--- a/src/praisonai-platform/praisonai_platform/services/project_service.py\n+++ b/src/praisonai-platform/praisonai_platform/services/project_service.py\n@@ -45,9 +45,12 @@ class ProjectService:\n         await self._session.flush()\n         return project\n\n-    async def get(self, project_id: str) -\u003e Optional[Project]:\n-        \"\"\"Get project by ID.\"\"\"\n-        return await self._session.get(Project, project_id)\n+    async def get(self, workspace_id: str, project_id: str) -\u003e Optional[Project]:\n+        \"\"\"Get project by ID, scoped to a workspace.\"\"\"\n+        stmt = select(Project).where(\n+            Project.id == project_id, Project.workspace_id == workspace_id\n+        )\n+        return (await self._session.execute(stmt)).scalar_one_or_none()\n\n     async def update(\n         self,\n+        workspace_id: str,\n         project_id: str,\n         ...\n     ) -\u003e Optional[Project]:\n-        project = await self.get(project_id)\n+        project = await self.get(workspace_id, project_id)\n\n-    async def delete(self, project_id: str) -\u003e bool:\n+    async def delete(self, workspace_id: str, project_id: str) -\u003e bool:\n-        project = await self.get(project_id)\n+        project = await self.get(workspace_id, project_id)\n\n-    async def get_stats(self, project_id: str) -\u003e dict:\n+    async def get_stats(self, workspace_id: str, project_id: str) -\u003e dict:\n+        # Also constrain the underlying issue counts query by workspace_id.\n```\n\nUpdate the route handlers in `routes/projects.py` to thread `workspace_id` through every call. The same single-key-lookup pattern is filed separately for `AgentService`, `IssueService`, `CommentService`, and `LabelService`.",
  "id": "GHSA-943m-6wx2-rc2j",
  "modified": "2026-06-01T14:17:04Z",
  "published": "2026-06-01T14:17:04Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/MervinPraison/PraisonAI/security/advisories/GHSA-943m-6wx2-rc2j"
    },
    {
      "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:H/I:H/A:N",
      "type": "CVSS_V3"
    }
  ],
  "summary": "praisonai-platform: Project endpoints accept any project_id without workspace ownership check, cross-workspace read/update/delete IDOR"
}

GHSA-94HJ-X7J9-542X

Vulnerability from github – Published: 2026-06-12 21:31 – Updated: 2026-06-12 21:31
VLAI
Details

MISP contained multiple mass assignment vulnerabilities in the handling of collections, tag collections, event delegations, and shadow attributes. Several controller actions accepted user-supplied fields that should have remained server-controlled, including record identifiers and ownership-related fields such as id, org_id, orgc_id, and user_id.

An authenticated attacker with access to the affected endpoints could craft requests containing protected fields in order to alter object ownership, redirect an update to another record, overwrite existing event delegation requests, or modify shadow attribute proposals belonging to another organization. This could result in unauthorized modification of MISP objects and, depending on object visibility and sharing configuration, unauthorized access to or transfer of sensitive threat intelligence data.

The issue was fixed by explicitly pinning ownership and identity fields to their stored values during edit operations and by removing user-supplied primary keys from create-only save paths.

Affected components:

  • CollectionsController::edit()
  • EventDelegationsController::delegateEvent()
  • ShadowAttributesController::edit()
  • TagCollectionsController::edit()915
  • TagCollectionsController::editWithTags()

Attack requirements: The attacker must be authenticated and able to reach the affected MISP endpoints. No user interaction is required.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2026-54361"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-639"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2026-06-12T20:16:48Z",
    "severity": "HIGH"
  },
  "details": "MISP contained multiple mass assignment vulnerabilities in the handling of collections, tag collections, event delegations, and shadow attributes. Several controller actions accepted user-supplied fields that should have remained server-controlled, including record identifiers and ownership-related fields such as id, org_id, orgc_id, and user_id.\n\nAn authenticated attacker with access to the affected endpoints could craft requests containing protected fields in order to alter object ownership, redirect an update to another record, overwrite existing event delegation requests, or modify shadow attribute proposals belonging to another organization. This could result in unauthorized modification of MISP objects and, depending on object visibility and sharing configuration, unauthorized access to or transfer of sensitive threat intelligence data.\n\nThe issue was fixed by explicitly pinning ownership and identity fields to their stored values during edit operations and by removing user-supplied primary keys from create-only save paths.\n\nAffected components:\n\n  *  CollectionsController::edit()\n  *  EventDelegationsController::delegateEvent()\n  *  ShadowAttributesController::edit()\n  *  TagCollectionsController::edit()915\n  *  TagCollectionsController::editWithTags()\n\n\nAttack requirements:\nThe attacker must be authenticated and able to reach the affected MISP endpoints. No user interaction is required.",
  "id": "GHSA-94hj-x7j9-542x",
  "modified": "2026-06-12T21:31:45Z",
  "published": "2026-06-12T21:31:45Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-54361"
    },
    {
      "type": "WEB",
      "url": "https://github.com/MISP/MISP/commit/9341690e9b6dde7f0605edea5533e05ba7362e35"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:L/VA:N/SC:L/SI:L/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-94Q3-Q8MX-4Q6C

Vulnerability from github – Published: 2022-05-24 16:55 – Updated: 2023-01-24 21:30
VLAI
Details

In CentOS-WebPanel.com (aka CWP) CentOS Web Panel 0.9.8.851, an insecure object reference allows an attacker to remove a target user from phpMyAdmin via an attacker account.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2019-14721"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-639"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2019-09-10T16:15:00Z",
    "severity": "MODERATE"
  },
  "details": "In CentOS-WebPanel.com (aka CWP) CentOS Web Panel 0.9.8.851, an insecure object reference allows an attacker to remove a target user from phpMyAdmin via an attacker account.",
  "id": "GHSA-94q3-q8mx-4q6c",
  "modified": "2023-01-24T21:30:33Z",
  "published": "2022-05-24T16:55:51Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2019-14721"
    },
    {
      "type": "WEB",
      "url": "https://centos-webpanel.com/changelog-cwp7"
    },
    {
      "type": "WEB",
      "url": "https://github.com/i3umi3iei3ii/CentOS-Control-Web-Panel-CVE/blob/master/CVE-2019-14721.md"
    },
    {
      "type": "WEB",
      "url": "https://packetstormsecurity.com/files/154404/Control-Web-Panel-0.9.8.851-Privilege-Escalation.html"
    }
  ],
  "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:N",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-952V-H4M8-6PCG

Vulnerability from github – Published: 2021-12-29 00:00 – Updated: 2022-01-08 00:00
VLAI
Details

https://www.sourcecodester.com/ Online Enrollment Management System in PHP and PayPal Free Source Code 1.0 is affected by: Incorrect Access Control. The impact is: gain privileges (remote).

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2021-40579"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-639"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2021-12-28T12:15:00Z",
    "severity": "MODERATE"
  },
  "details": "https://www.sourcecodester.com/ Online Enrollment Management System in PHP and PayPal Free Source Code 1.0 is affected by: Incorrect Access Control. The impact is: gain privileges (remote).",
  "id": "GHSA-952v-h4m8-6pcg",
  "modified": "2022-01-08T00:00:45Z",
  "published": "2021-12-29T00:00:45Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2021-40579"
    },
    {
      "type": "WEB",
      "url": "https://medium.com/@VAPT01/cve-2021-40579-9eac3409fd24"
    },
    {
      "type": "WEB",
      "url": "https://www.sourcecodester.com"
    }
  ],
  "schema_version": "1.4.0",
  "severity": []
}

GHSA-9555-VV9W-FMXQ

Vulnerability from github – Published: 2024-08-16 03:33 – Updated: 2024-08-16 03:33
VLAI
Details

The Custom Field For WP Job Manager plugin for WordPress is vulnerable to Insecure Direct Object Reference in all versions up to, and including, 1.2 via the the 'cm_fieldshow' shortcode due to missing validation on the 'job_id' user controlled key. This makes it possible for authenticated attackers, with contributor-level access and above, to expose potentially sensitive post metadata.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2023-7049"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-639"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2024-08-16T03:15:09Z",
    "severity": "MODERATE"
  },
  "details": "The Custom Field For WP Job Manager plugin for WordPress is vulnerable to Insecure Direct Object Reference in all versions up to, and including, 1.2 via the the \u0027cm_fieldshow\u0027 shortcode due to missing validation on the \u0027job_id\u0027 user controlled key. This makes it possible for authenticated attackers, with contributor-level access and above, to expose potentially sensitive post metadata.",
  "id": "GHSA-9555-vv9w-fmxq",
  "modified": "2024-08-16T03:33:48Z",
  "published": "2024-08-16T03:33:48Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2023-7049"
    },
    {
      "type": "WEB",
      "url": "https://plugins.trac.wordpress.org/changeset/3134344/custom-field-for-wp-job-manager/trunk/includes/CFWJM_Shortcode.php"
    },
    {
      "type": "WEB",
      "url": "https://www.wordfence.com/threat-intel/vulnerabilities/id/9891587b-2a63-41be-b79d-afe407dd57fa?source=cve"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N",
      "type": "CVSS_V3"
    }
  ]
}

Mitigation
Architecture and Design

For each and every data access, ensure that the user has sufficient privilege to access the record that is being requested.

Mitigation
Architecture and Design Implementation

Make sure that the key that is used in the lookup of a specific user's record is not controllable externally by the user or that any tampering can be detected.

Mitigation
Architecture and Design

Use encryption in order to make it more difficult to guess other legitimate values of the key or associate a digital signature with the key so that the server can verify that there has been no tampering.

No CAPEC attack patterns related to this CWE.