# PraisonAI: Platform member PATCH routes allow owner resource rewrites and project lead reassignment delete bypass

Ordinary workspace members could PATCH owner-created projects, issues and agents; reassigning project lead_id to self then bypassed the delete ownership guard.

- Payout: Research
- Severity: high
- Program: PraisonAI Platform
- Found by: rexpository
- Disclosed: 2026-10-08
- CVE: CVE-2026-61442
- Write-up quality: 7/10
- Original: https://github.com/advisories/GHSA-c78w-2q4r-68r7
- Library page: https://bugbountylibrary.com/r/ghsa%3AGHSA-c78w-2q4r-68r7
- Tags: area:web domain:api impact:data-leak impact:integrity kind:research platform:ghsa sev:high tech:python technique:chained technique:source-review vuln:access-control vuln:auth-bypass vuln:idor

**Target:** FastAPI platform API (project/issue/agent PATCH routes)
**Root cause:** PATCH routes only depend on require_workspace_member while paired DELETE routes enforce require_delete_permission against resource owner; project lead_id is member-writable and later trusted as the delete ownership field.
**Steps:**
1. Register owner, member, outsider; owner creates workspace and adds member with role `member`.
2. Owner creates project with `lead_id` = owner id.
3. Member DELETE project -> `403` (guard works).
4. Member `PATCH /api/v1/workspaces/{workspace_id}/projects/{project_id}` with `{"lead_type":"member","lead_id":<member_id>}` -> `200`.
5. Member DELETE same project -> `204`; owner GET -> `404`.
6. Member PATCH owner issue `{"title":"Member rewrote owner issue","status":"done"}` -> `200`; DELETE still `403`.
7. Member PATCH owner agent `{"instructions":"member-controlled instructions"}` -> `200`; DELETE still `403`.
8. Outsider PATCH issue -> `403` (negative control).
**How found:** Compared authorization dependencies across route pairs: noticed PATCH routes use require_workspace_member while DELETE routes use require_delete_permission with resource_owner_id, then traced that ProjectService.update writes lead_id — the exact field the delete guard trusts.
**Exploitation:** A legitimate workspace member patches the project's lead_id to their own user id, then deletes the owner-created project; the delete route's require_delete_permission trusts project.lead_id and returns 204, destroying owner data. Same member can silently rewrite owner issue titles/statuses and agent instructions/runtime_config.
**Escalation:** Ownership-field rewrite (lead_id) converts a denied delete into an allowed one; agent instructions/runtime_config tampering can alter agent behavior beyond data integrity.
**Insight:** When a delete guard authorizes against a mutable ownership field (lead_id, creator_id, owner_id), check whether any update route lets a lower-privileged caller write that field; the asymmetry between PATCH and DELETE dependencies is the tell.

