Open actionable advisories and recorded vendor fixes. This public package view has no inventory attached and cannot establish whether your deployment is affected. A vendor fix never resolves your finding; verify your installed version and the source guidance.
Open advisories
24 actionable advisories, newest first. Withdrawn advisories and news are excluded. Coverage is partial.
Platform member PATCH routes allow owner resource rewrites and project lead reassignment delete bypass Summary praisonai-platform lets an ordinary workspace member patch owner-created project, issue, and agent records even though the paired delete routes enforce owner/admin authorization. For projects, the member can first patch leadid to their own user id and then delete the owner-created project, bypassing a delete guard that correctly returned 403 before the reassignment. Technical Details The affected boundary is the difference between "is a workspace member" and "owns or administers this resource". src/praisonai-platform/praisonaiplatform/api/deps.py defines requireworkspacemember, requireworkspaceadmin, requireworkspaceowner, and requiredeletepermission. requireworkspacemember only checks that the caller has at least the member role in the workspace, while requiredeletepermission allows delete only for workspace admins/owners or the resource owner. The project update route in…
Recommended action: Upgrade to 0.1.9 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
Platform members can rewrite shared labels and owner issue labels without owner/admin authorization Summary praisonai-platform lets an ordinary workspace member rename and recolor shared labels and add/remove labels on an owner-created issue even though direct label deletion is restricted to workspace admin/owner authority in current releases. Technical Details The affected boundary is the difference between ordinary workspace membership and authority to mutate shared workspace triage taxonomy or owner-created issue workflow state. src/praisonai-platform/praisonaiplatform/api/routes/labels.py defines PATCH /workspaces/{workspaceid}/labels/{labelid} with user: AuthIdentity = Depends(requireworkspacemember). The route verifies the label belongs to the URL workspace, then calls LabelService.update(labelid, body.name, body.color), which writes the shared label name/color. The paired label delete route shows a stricter intended boundary. DELETE /workspaces/{workspaceid}/labels/{labelid}…
Recommended action: Upgrade to 0.1.9 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
Platform members can delete owner issue dependencies through member-owned related issues Summary praisonai-platform issue dependency deletion can be authorized against the wrong side of a dependency edge. A workspace member cannot delete a dependency through the owner-created issue endpoint, but can delete the same dependency through a member-owned related issue endpoint because the route accepts either endpoint and checks delete permission only against the caller-selected URL issue. Technical Details The affected boundary is the difference between ordinary workspace membership and owner/admin authority over destructive changes to owner-created issue workflow state. src/praisonai-platform/praisonaiplatform/api/routes/dependencies.py defines DELETE /workspaces/{workspaceid}/issues/{issueid}/dependencies/{depid}. The route first verifies that the URL issueid is in the workspace, loads the dependency by depid, and accepts the dependency when either dep.issueid == issueid or…
Recommended action: Upgrade to 0.1.9 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
The issue create and update endpoints in praisonai-platform accept a projectid in the request body and persist it without validating that the project belongs to the URL workspace. A user who is a member of workspace WB (and has no access to workspace WA) can create issues that reference a project owned by WA. Because ProjectService.getstats() aggregates issues by projectid with no workspace constraint, those foreign issues are then counted in the victim's own legitimate view of their project statistics. This is a cross-tenant integrity violation reachable by an outsider. This is distinct from the path-parameter IDOR family fixed in 0.1.4 (CVE-2026-47415, CVE-2026-47418, CVE-2026-47419). Those fixes scoped object references supplied in the URL path. This report concerns an object reference supplied in the request body at write time, which the 0.1.4 fixes did not cover. Version 0.1.4 fixed a set of path-parameter IDORs by threading workspaceid into the service-layer lookups…
Recommended action: Upgrade to 0.1.8 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
praisonai-platform: default JWT signing secret dev-secret-change-me Researcher: Kai Aizen — SnailSploit (@SnailSploit), Adversarial & Offensive Security Research Target: https://github.com/MervinPraison/PraisonAI --- Package: praisonai-platform on PyPI Latest version (and version tested): 0.1.4, current as of 2026-06-01. File: praisonaiplatform/services/authservice.py (sha256 cc29d43c5412da2c73c818859b8d8b146587842999b777336017ab9d9e509258). Weakness: CWE-798 Use of Hardcoded Credentials + CWE-1188 Insecure Default Initialization of Resource. --- TL;DR praisonaiplatform/services/authservice.py lines 25-37: The guard at line 33 is meant to catch the "deployed to production with the default secret" failure mode. But it only fires when both: - the operator left PLATFORMJWTSECRET unset (so JWTSECRET is the default literal), and - the operator explicitly set PLATFORMENV to something other than "dev". If the operator left both env vars unset — the most common mis-deploy — PLATFORMENV falls…
Recommended action: Upgrade to 0.1.6 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
- Affected: praisonai-platform (PyPI) <= 0.1.4 — including 0.1.4, the version GHSA-3qg8-5g3r-79v5 declares as the patch; main HEAD 8acf77c531e624c46d3d61dcae37e9942e90972c is also affected. File src/praisonai-platform/praisonaiplatform/services/authservice.py - CWE: CWE-1188 (Insecure Default Initialization) + CWE-798 (Use of Hard-coded Credentials) - CWE-287 (Improper Authentication) Overview GHSA-3qg8-5g3r-79v5 (Critical) reported that praisonai-platform's JWT signing secret defaulted to the hardcoded literal "dev-secret-change-me", and that the production guard meant to prevent this was default-open (it only fired when PLATFORMENV != "dev", but PLATFORMENV defaults to "dev"). That advisory declares the issue patched in = 0.1.4. It is not. The shipped praisonai-platform==0.1.4 (and current main) still resolves the signing key to "dev-secret-change-me" in any deployment that does not explicitly set PLATFORMJWTSECRET, because the 0.1.4 change merely duplicated the same default-open…
Recommended action: Upgrade to 0.1.6 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
A workspace member can permanently delete any resource — projects, agents, issues, labels, issue dependencies, and issue-label attachments — created by the workspace owner or other members. All six content DELETE endpoints enforce workspace membership but perform no ownership or role check. A single malicious or compromised member account can wipe an entire workspace's content irreversibly. Details The published role capability matrix explicitly restricts members from modifying others' content: | Capability | Owner | Admin | Member | |---|---|---|---| | Create issues/tasks | ✅ | ✅ | ✅ | | Edit own content | ✅ | ✅ | ✅ | | Edit others' content | ✅ | ✅ | ❌ | The DELETE handlers for all content resources check that the requesting user is a workspace member, but do not verify that the user either created the resource or holds an owner/admin role. The result is that the member role has unrestricted DELETE access over all workspace content regardless of who created it. Confirmed…
Recommended action: Upgrade to 0.1.6 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
Type: Insecure Direct Object Reference. The agent CRUD endpoints (GET / PATCH / DELETE /workspaces/{workspaceid}/agents/{agentid}) gate access on requireworkspacemember(workspaceid) only, then resolve agentid through AgentService.get(agentid) which is a primary-key lookup with no workspace constraint. A user who is a member of any workspace W1 can read, modify, or delete agents that belong to a different workspace W2 by guessing or harvesting an agent UUID and calling …/workspaces/W1/agents/<W2-agent-id. File: src/praisonai-platform/praisonaiplatform/services/agentservice.py, lines 53-112; route handlers at src/praisonai-platform/praisonaiplatform/api/routes/agents.py, lines 53-100. Root cause: the route extracts workspaceid from the URL path and passes it to requireworkspacemember for the membership check, but never threads it through to the service layer. AgentService.get calls session.get(Agent, agentid), which is SELECT FROM agents WHERE id = :agentid with no AND…
Recommended action: Upgrade to 0.1.4 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
Type: Authorization bypass enabling destructive action. The DELETE /workspaces/{workspaceid} endpoint is gated only by requireworkspacemember(workspaceid) (default minrole="member"). Any member of the workspace can issue a single DELETE to wipe the entire workspace, including every project, issue, comment, agent, label, and member record (cascading via the foreign-key relationships). There is no owner-role gate, no confirmation token, no soft-delete window, no recovery path. File: src/praisonai-platform/praisonaiplatform/api/routes/workspaces.py, lines 77-86; services/workspaceservice.py's delete() method. Root cause: the route uses Depends(requireworkspacemember) which defaults to minrole="member" and is never overridden. The service method WorkspaceService.delete(workspaceid) performs the destructive operation without any caller-permission verification. The role hierarchy (MemberService.hasrole, memberservice.py:80-96) is implemented but unused for this endpoint. Affected…
Recommended action: Upgrade to 0.1.4 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
Type: Insecure Direct Object Reference. The issue CRUD endpoints (GET / PATCH / DELETE /workspaces/{workspaceid}/issues/{issueid}) gate access on requireworkspacemember(workspaceid) only, then resolve issueid through IssueService.get(issueid) which is a primary-key lookup with no workspace constraint. A user who is a member of any workspace W1 can read, modify, or delete issues that belong to a different workspace W2. File: src/praisonai-platform/praisonaiplatform/services/issueservice.py, lines 72-156; route handlers at src/praisonai-platform/praisonaiplatform/api/routes/issues.py, lines 82-137. Root cause: the route extracts workspaceid from the URL path, uses it solely for the membership gate, then calls IssueService.get(issueid) / IssueService.update(issueid, ...) / IssueService.delete(issueid) without re-checking which workspace the issue actually belongs to. IssueService.get runs a single-key lookup; update and delete call self.get(issueid) first and then mutate the…
Recommended action: Upgrade to 0.1.4 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
Type: Privilege escalation / cross-tenant member injection. The POST /workspaces/{workspaceid}/members endpoint is gated only by requireworkspacemember(workspaceid) (default minrole="member") and forwards the request body's userid and role straight into MemberService.add(workspaceid, userid, role), which has no caller-permission check. A user with the lowest workspace privilege can add any user (including a new attacker-controlled second account, or an existing account they want to grief) as owner of the workspace. File: src/praisonai-platform/praisonaiplatform/api/routes/workspaces.py, lines 92-101; services/memberservice.py, lines 26-38. Root cause: MemberService.add validates only that role is in VALIDROLES = {"owner", "admin", "member"} — the value, not the caller's right to assign it. The route's Depends(requireworkspacemember) resolves to the default minrole="member". So a member-level token plus one POST gives the attacker an alternate identity with owner role inside…
Recommended action: Upgrade to 0.1.4 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
Type: Authorization bypass enabling workspace metadata + settings tampering. The PATCH /workspaces/{workspaceid} endpoint is gated only by requireworkspacemember(workspaceid) (default minrole="member"). Any member can rewrite the workspace's name, description, and the settings JSON blob. The settings field is a free-form JSON object — depending on which downstream code reads it, this becomes a configuration-injection primitive for any setting the platform exposes there. File: src/praisonai-platform/praisonaiplatform/api/routes/workspaces.py, lines 63-74; services/workspaceservice.py's update() method. Root cause: Depends(requireworkspacemember) resolves to default minrole="member". WorkspaceService.update(workspaceid, name, description, settings) writes the new fields to the workspace row without any caller-permission check. The role hierarchy (MemberService.hasrole) is never consulted. Affected Code File: src/praisonai-platform/praisonaiplatform/api/routes/workspaces.py,…
Recommended action: Upgrade to 0.1.4 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
Type: Insecure Direct Object Reference. The comment endpoints (POST /workspaces/{workspaceid}/issues/{issueid}/comments and GET .../comments) gate access on requireworkspacemember(workspaceid) only, then call CommentService.create(issueid=issueid, ...) and CommentService.listforissue(issueid) without verifying that issueid belongs to workspaceid. 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/praisonaiplatform/api/routes/issues.py, lines 143-171; src/praisonai-platform/praisonaiplatform/services/commentservice.py, lines 19-53. Root cause: the route extracts workspaceid from the URL path and uses it solely for the membership gate, then passes the URL-supplied issueid straight into CommentService without confirming that this issue exists in workspaceid. CommentService.listforissue(issueid) runs SELECT FROM comments WHERE issueid = :issueid with no workspace join.…
Recommended action: Upgrade to 0.1.4 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
Type: Insecure Direct Object Reference. The project CRUD endpoints (GET / PATCH / DELETE /workspaces/{workspaceid}/projects/{projectid} and GET .../{projectid}/stats) gate access on requireworkspacemember(workspaceid) only, then resolve projectid through ProjectService.get(projectid) / update(projectid, ...) / delete(projectid) / getstats(projectid). None of these calls thread workspaceid 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/praisonaiplatform/services/projectservice.py, lines 47-108; route handlers at src/praisonai-platform/praisonaiplatform/api/routes/projects.py, lines 51-108. Root cause: identical to the agent and issue IDORs in this codebase. The route accepts workspaceid from URL, uses it solely for the membership gate, then calls ProjectService.get(projectid) which is session.get(Project, projectid) — a…
Recommended action: Upgrade to 0.1.4 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
Type: Vertical privilege escalation. The PATCH /workspaces/{workspaceid}/members/{userid} endpoint is gated by requireworkspacemember(workspaceid), which defaults to minrole="member" and is never overridden by the route. The handler then calls MemberService.updaterole(workspaceid, userid, body.role) which sets the target member's role to whatever the request body specifies, with no check that the caller has owner-or-admin privilege, no check that the new role is not higher than the caller's own, and no check that the caller is not silently promoting themselves. File: src/praisonai-platform/praisonaiplatform/api/routes/workspaces.py, lines 115-127; services/memberservice.py, lines 55-69; api/deps.py, lines 54-73. Root cause: requireworkspacemember exists with a minrole parameter (deps.py:58) but FastAPI's Depends(requireworkspacemember) cannot pass arguments, so every route uses the default "member". The route then passes the URL-supplied userid and the body-supplied role…
Recommended action: Upgrade to 0.1.4 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
Type: Authorization bypass enabling owner lockout. The DELETE /workspaces/{workspaceid}/members/{userid} endpoint is gated only by requireworkspacemember(workspaceid) (default minrole="member"). Any member can remove any other member, including the workspace owner, using a single DELETE. There is no caller-role check, no target-role check, no "cannot remove last owner" guard. File: src/praisonai-platform/praisonaiplatform/api/routes/workspaces.py, lines 130-140; services/memberservice.py, lines 71-78. Root cause: MemberService.remove(workspaceid, userid) performs the deletion without any caller-permission check or owner-protection logic. The route accepts the URL-supplied userid and dispatches it straight through. The role hierarchy (MemberService.hasrole) is implemented but never invoked here. A member-tier attacker can issue DELETE .../members/<owneruserid and immediately lock the legitimate owner out of the workspace. Affected Code File 1:…
Recommended action: Upgrade to 0.1.4 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
Type: Insecure Direct Object Reference. Five label endpoints — PATCH /workspaces/{workspaceid}/labels/{labelid}, DELETE .../labels/{labelid}, POST .../issues/{issueid}/labels/{labelid}, DELETE .../issues/{issueid}/labels/{labelid}, GET .../issues/{issueid}/labels — gate access on requireworkspacemember(workspaceid) only and pass URL-supplied labelid and issueid straight through to LabelService without verifying either belongs to the workspace. File: src/praisonai-platform/praisonaiplatform/services/labelservice.py, lines 35-100; route handlers at src/praisonai-platform/praisonaiplatform/api/routes/labels.py, lines 42-106. Root cause: identical pattern to the agent / issue / project / comment IDORs in this codebase: the route's workspaceid is used as a membership predicate but never threaded through to the service layer. LabelService.get(labelid) runs session.get(IssueLabel, labelid) with no workspace filter; update/delete inherit the gap; addtoissue(issueid, labelid) and…
Recommended action: Upgrade to 0.1.4 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
Type: Insecure Direct Object Reference. The dependency endpoints (POST/GET /workspaces/{workspaceid}/issues/{issueid}/dependencies and DELETE .../dependencies/{depid}) gate access on requireworkspacemember(workspaceid) only, then dispatch to DependencyService calls that take URL/body-supplied issue and dependency IDs without verifying any of them belong to the membership-checked workspace. Most damaging: createdependency accepts body.dependsonissueid from the request body — that ID is checked against nothing — letting an attacker create a "blocks" or "related" link between any two issues anywhere in the database. File: src/praisonai-platform/praisonaiplatform/api/routes/dependencies.py, lines 22-58; services/dependencyservice.py, lines 26-65. Root cause: the same Depends(requireworkspacemember) default-min-role pattern as the companion IDORs, plus a service layer (DependencyService) where every method takes raw IDs and queries them directly. create(issueid, dependsonissueid,…
Recommended action: Upgrade to 0.1.4 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
Type: Insecure default cryptographic key. The JWT signing secret defaults to the hardcoded literal "dev-secret-change-me" when PLATFORMJWTSECRET is unset. A safety check exists but only fires when PLATFORMENV != "dev"; the default value of PLATFORMENV is "dev", so the check is silently bypassed in any deployment that does not explicitly opt out. The attacker reads the literal from this public source file, mints a JWT with arbitrary sub and email claims, and authenticates as any existing user (including workspace owners and admins). File: src/praisonai-platform/praisonaiplatform/services/authservice.py, lines 25-36 and 114-137. Root cause: the production-mode guard checks os.environ.get("PLATFORMENV", "dev") != "dev" — but the default is "dev", so a clean deployment that just imports the package and runs uvicorn praisonaiplatform.api.app:app proceeds with the hardcoded secret. The package documentation does not warn loudly enough that BOTH variables must be set; the guard…
Recommended action: Upgrade to 0.1.4 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
PraisonAI Platform has a broken workspace authorization check that allows any authenticated low-privilege workspace member to escalate their own role to owner. The issue is caused by privileged workspace-management routes using the shared dependency requireworkspacemember(...) without requiring admin or owner. The dependency defaults to minrole="member", so routes that should be administrative are accessible to ordinary workspace members. As a result, a normal workspace member can: - promote their own account from member to owner; - add arbitrary users as owner or admin; - change other members' roles; - remove legitimate owners or members; - take over workspace membership completely; - perform destructive workspace operations after escalation. This is a broken access control / vertical privilege escalation vulnerability. Details The vulnerable authorization dependency is defined in: The dependency defaults to the lowest workspace role: Because minrole defaults to "member",…
Recommended action: Upgrade to 0.1.4 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
PraisonAI 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 workspaceid 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 workspaceattacker can call a route under: while supplying an object UUID from workspacevictim. The server authorizes the request based on membership in workspaceattacker, then fetches or mutates the victim object by global UUID. This breaks the platform's workspace isolation boundary. Details The root cause is that…
Recommended action: Upgrade to 0.1.4 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
The Platform server exposes resources under /api/v1/workspaces/{workspaceid}/... and protects them with a requireworkspacemember(workspaceid) FastAPI dependency. The dependency only checks that the caller is a member of the workspaceid in the URL prefix. The route handlers then look up the inner resource (agentid, issueid, projectid, labelid, commentid, dependencyid) by primary key alone. The resource's own workspaceid is never compared to the URL's workspaceid. A user can therefore put their own workspace in the URL prefix and any other workspace's resource ID in the path. The auth check passes, since they really are a member of the prefix workspace. The service then returns the cross-tenant resource for read, update, or delete. There is a second bug in the member-management routes (addmember, updatememberrole, removemember, updateworkspace, deleteworkspace). Each one inherits the default minrole="member" from requireworkspacemember. Any basic member can therefore promote…
Recommended action: Upgrade to 0.1.4 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
Type: Insecure Direct Object Reference. The GET /workspaces/{workspaceid}/issues/{issueid}/activity endpoint is gated by requireworkspacemember(workspaceid) and dispatches to ActivityService.listforissue(issueid), which executes SELECT FROM activity WHERE issueid = :issueid with no workspace constraint. A user who is a member of any workspace can read the full activity log of any issue across the entire multi-tenant deployment. File: src/praisonai-platform/praisonaiplatform/api/routes/activity.py, lines 32-43; services/activityservice.py's listforissue method. Root cause: the route extracts workspaceid from the URL path, uses it solely for the membership gate, then passes the URL-supplied issueid directly to ActivityService.listforissue(issueid) without verifying which workspace the issue belongs to. The companion listworkspaceactivity endpoint at line 19-29 is implemented correctly (it passes workspaceid to svc.listforworkspace(workspaceid)) — the asymmetry is the smoking…
Recommended action: Upgrade to 0.1.4 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
The PraisonAI Platform API has two authorization failures that together break workspace isolation. The service layer for issues and projects performs global primary-key lookups without checking workspace ownership, so any authenticated user can read, modify, and delete resources in any workspace just by swapping UUIDs in their API requests. On top of that, every member management endpoint (add, update role, remove) only requires minrole="member", which lets any workspace member promote themselves to owner and kick out the original owner. A low-privilege member of one workspace can steal data from every other workspace and take over any workspace they belong to. Both issues come from the same gap: the route layer pulls workspaceid from the URL and verifies membership, but the service layer ignores the workspace scope for resource lookups and ignores the caller's role level for member operations. The requireworkspacemember() dependency does its job correctly. The problem is…
Recommended action: Upgrade to 0.1.4 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.