praisonai-platform: Comment endpoints accept any issue_id without workspace ownership check, cross-workspace comment read and post IDOR
Date: 2026-06
Affected: pip/praisonai-platform
Attack vector: auth-bypass
Category: vulnerability-disclosure
Severity: High
CVE: CVE-2026-47417
CWE: CWE-639
CVSS: 8.1 (CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N)

## Summary **Type:** Insecure Direct Object Reference. The comment endpoints (`POST /workspaces/{workspace_id}/issues/{issue_id}/comments` and `GET .../comments`) gate access on `require_workspace_member(workspace_id)` only, then call `CommentService.create(issue_id=issue_id, ...)` and `CommentService.list_for_issue(issue_id)` without verifying that `issue_id` belongs to `workspace_id`. A user who is a member of any workspace `W1` can read every comment on, and post new comments to, any issue in any other workspace `W2`. **File:** `src/praisonai-platform/praisonai_platform/api/routes/issues.py`, lines 143-171; `src/praisonai-platform/praisonai_platform/services/comment_service.py`, lines 19-53. **Root cause:** the route extracts `workspace_id` from the URL path and uses it solely for the membership gate, then passes the URL-supplied `issue_id` straight into `CommentService` without confirming that this issue exists in `workspace_id`. `CommentService.list_for_issue(issue_id)` runs `SELECT * FROM comments WHERE issue_id = :issue_id` with no workspace join. `CommentService.create(issue_id=issue_id, ...)` blindly writes a row with that `issue_id`. Both flows trust the URL-supplied issue ID as authoritative even though the membership check guarantees nothing about it. ## Affected Code **File 1:** `src/praisonai-platform/praisonai_platform/api/routes/issues.py`, lines 143-171. ```python @router.post("/{issue_id}/comments", response_model=CommentResponse, status_code=status.HTTP


Mitigations:

Architectural layers (MAESTRO):