GHSA-6h6v-6m7w-7vxx PraisonAI Platform workspace-scoped routes allow cross-workspace object access by global object ID
SummaryPraisonAI Platform's workspace-scoped REST routes contain a systemic object-level authorization flaw that allows an authenticated user from one workspace to access, modify, and delete objects belonging to another workspace by supplying the victim object's global UUID.The affected pattern appears in workspace-scoped routes such as agents, projects, issues, and comments. The route layer verifies that the caller is a member of the `workspace_id` provided in the URL, but the service layer later resolves the target object by global object ID only. It does not verify that the resolved object actually belongs to the workspace in the URL.As a result, a valid member of `workspace_attacker` can call a route under:while supplying an object UUID from `workspace_victim`. The server authorizes the request based on membership in `workspace_attacker`, then fetches or mutates the victim object by global UUID.This breaks the platform's workspace isolation boundary.DetailsThe root cause is that workspace membership authorization and object ownership validation are not bound together.The workspace dependency validates only that the caller is a member of the workspace named in the URL:This confirms that the caller has access to the URL workspace. However, it does not prove that the target object belongs to that workspace.For example, the agent routes are scoped under a workspace path, but object access is performed using only the raw `agent_id`:The service method resolves the agent by global UUID only:The same pattern is used for update and delete operations:There is no check equivalent to:Therefore, if an attacker is a valid member of any workspace, they can pass their own workspace ID in the URL while supplying an object ID from another workspace.The same architectural pattern appears in other workspace-scoped object routes, including projects, issues, and comments:This indicates a systemic object-level access control issue: routes are workspace-scoped, but service-layer object lookups are not workspace-bound.PoCThe following local PoC creates a real PraisonAI Platform FastAPI app backed by an in-memory SQLite database, then uses only HTTP requests against the real API routes.The PoC demonstrates the following chain:An attacker account creates `workspace_attacker`.A victim account creates `workspace_victim`.The victim creates an agent in `workspace_victim`.The attacker sends:The server returns the victim agent from `workspace_victim`.The attacker updates the victim agent through the attacker workspace path.The victim observes the attacker-controlled modification.The attacker deletes the victim agent through the attacker workspace path.Run with:Full PoC:Observed result:This confirms that an authenticated user from one workspace can read, modify, and delete an object belonging to another workspace by using the victim object's UUID through the attacker's own workspace-scoped route.ImpactAny authenticated workspace member who knows or obtains object UUIDs from another workspace may be able to:read other workspaces' agents;read agent instructions and metadata;modify victim agents;delete victim agents;potentially read, modify, or delete projects and issues that follow the same object lookup pattern;enumerate comments for issues by raw `issue_id`;corrupt activity data, project state, and issue state across workspace boundaries.This breaks the platform's tenant-isolation boundary. The impact is especially serious in multi-tenant deployments where separate users or teams rely on workspaces as an authorization boundary.The demonstrated PoC confirms read, update, and delete access against agents. The same root-cause pattern appears in other workspace-scoped object routes and should be audited across the platform.Suggested remediationRecommended fixes:Require every object fetch, update, and delete method to take both `workspace_id` and `object_id`.Enforce object ownership in the service layer. For example:Avoid service methods that resolve workspace-owned objects by global UUID alone.Apply the same object-level ownership checks to agents, projects, issues, comments, dependencies, and any other workspace-owned resources.For comment and dependency helpers that pivot from raw `issue_id`, validate that the parent issue belongs to the authorized workspace before returning or modifying child records.Add regression tests for negative cross-workspace access cases, including:Return `404 Not Found` or `403 Forbidden` consistently when an object does not belong to the authorized workspace.Security boundaryThis report concerns a workspace tenant-isolation failure. The caller is authenticated, but authentication alone is insufficient. The server must also verify that the requested object belongs to the workspace for which the caller has authorization.
CVSS v3.1 score: 8.8