praisonai-platform: Label endpoints' unchecked label_id/issue_id enable cross-workspace label IDOR (edit, delete, link)
Date: 2026-05
Affected: pip/praisonai-platform
Attack vector: auth-bypass
Category: vulnerability-disclosure
Severity: High
CVE: CVE-2026-47414
CWE: CWE-639
CVSS: 7.6 (CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:H/A:L)

## Summary **Type:** Insecure Direct Object Reference. Five label endpoints — `PATCH /workspaces/{workspace_id}/labels/{label_id}`, `DELETE .../labels/{label_id}`, `POST .../issues/{issue_id}/labels/{label_id}`, `DELETE .../issues/{issue_id}/labels/{label_id}`, `GET .../issues/{issue_id}/labels` — gate access on `require_workspace_member(workspace_id)` only and pass URL-supplied `label_id` and `issue_id` straight through to `LabelService` without verifying either belongs to the workspace. **File:** `src/praisonai-platform/praisonai_platform/services/label_service.py`, lines 35-100; route handlers at `src/praisonai-platform/praisonai_platform/api/routes/labels.py`, lines 42-106. **Root cause:** identical pattern to the agent / issue / project / comment IDORs in this codebase: the route's `workspace_id` is used as a membership predicate but never threaded through to the service layer. `LabelService.get(label_id)` runs `session.get(IssueLabel, label_id)` with no workspace filter; `update`/`delete` inherit the gap; `add_to_issue(issue_id, label_id)` and `remove_from_issue(issue_id, label_id)` write/delete association rows without verifying either ID belongs to the membership-checked workspace; `list_for_issue(issue_id)` reads them. ## Affected Code **File 1:** `src/praisonai-platform/praisonai_platform/services/label_service.py`, lines 35-100. ```python class LabelService: ... async def get(self, label_id: str) -> Optional[IssueLabel]: return await self._sess


Mitigations:

Architectural layers (MAESTRO):