CVE-2026-47407 - PraisonAI Platform workspace takeover
PraisonAI Platform versions 0.1.2 and earlier contain an authorization chain
that can collapse workspace isolation. The API verifies that a caller belongs
to the workspace_id in the URL, but nested-resource handlers can then fetch
agents, issues, projects, labels, comments, or dependencies by global primary
key without proving that the target object belongs to that same workspace.
The same vulnerable route family also exposes privileged workspace and member operations behind member-level checks. A basic workspace member can therefore reach cross-workspace records when UUIDs are known or leaked, then use weak member-management gates to promote, demote, remove, or delete workspace membership and state.
For agentic systems, this is more than an ordinary IDOR. Agent instructions, runtime configuration, issues, dependencies, project state, prompts, and workspace membership can all become authorization boundaries. The review must prove that both route-layer and service-layer checks use the same workspace and role model.
Affected versions
- Vulnerable package:
praisonai-platform <=0.1.2 - Fixed package:
praisonai-platform 0.1.4+ - Affected coordinate:
praisonai-platformon PyPI - Affected surface: PraisonAI Platform API routes under
/api/v1/workspaces/{workspace_id}/..., especially agents, issues, projects, labels, comments, dependencies, workspaces, and members - Affected code pattern: route code validates membership in URL
workspace_id, then calls a service method keyed only by inner resource ID or mutates workspace membership/state with only member-level authorization
Indicator-of-exposure
- The repository depends on, vendors, forks, wraps, builds, or deploys
praisonai-platform <=0.1.2. - The platform is used for more than one workspace, tenant, team, project, agent, issue queue, dependency graph, or customer environment.
- Resource services use
session.get(Model, id)or equivalent primary-key-only lookups for workspace-owned objects. - Routes receive both
workspace_idand another object ID but do not passworkspace_idinto the service method that reads, updates, deletes, labels, comments on, or links the object. - Member-management routes rely on default workspace membership rather than an explicit owner/admin gate for role changes, member removal, workspace update, or workspace deletion.
- Tests use one workspace or only happy-path owner flows, so UUID swaps and member self-promotion are not exercised.
Quick checks:
rg -n "praisonai-platform|praisonai_platform|require_workspace_member|session\\.get\\(|workspace_id.*(agent_id|issue_id|project_id|label_id|comment_id|dependency_id|user_id)|AgentService|IssueService|ProjectService|LabelService|CommentService|DependencyService|MemberService|update_member_role|delete_workspace|remove_member|add_member" .
python -m pip show praisonai-platform
python -m pip freeze | rg -i '^praisonai-platform=='
Windows:
rg -n "praisonai-platform|praisonai_platform|require_workspace_member|session\\.get\\(|workspace_id.*(agent_id|issue_id|project_id|label_id|comment_id|dependency_id|user_id)|AgentService|IssueService|ProjectService|LabelService|CommentService|DependencyService|MemberService|update_member_role|delete_workspace|remove_member|add_member" .
python -m pip show praisonai-platform
python -m pip freeze | rg -i '^praisonai-platform=='
Do not verify exposure with production tenants, real workspace IDs, copied customer UUIDs, live bearer tokens, database dumps, or destructive member operations. Use synthetic local tenants and fixtures.
Remediation strategy
- Upgrade every controlled
praisonai-platformdependency, lockfile, image, deployment, generated dependency report, and SBOM to0.1.4+. - Treat route-level membership as necessary but insufficient. Every service
method that touches workspace-owned objects must receive
workspace_idand enforce it in the query. - Replace global primary-key lookups for agents, issues, projects, labels,
comments, and dependencies with queries scoped by both object ID and
workspace_id. - Move mutation authorization into the service layer as well as the route layer. Services that update roles or workspace-owned resources should receive caller identity and caller role.
- Require explicit owner/admin policy for member add, role update, member removal, workspace update, and workspace deletion. Preserve last-owner protection.
- Add tenant-boundary and RBAC tests that prove cross-workspace UUID swaps and member self-promotion fail without leaking object existence or sensitive content.
- Add audit events for denied cross-workspace access and privileged membership changes without logging tokens, prompts, tenant content, model-provider keys, or database row contents.
When to use it
Use this recipe when a repository deploys, vendors, forks, wraps, or packages
PraisonAI Platform for multi-workspace, multi-tenant, team, project, issue,
agent, dependency, or customer environments. It is most important when routes
accept both workspace_id and nested resource IDs, or when member-management
routes use default membership checks.
Use it to upgrade the package and prove workspace isolation at both route and service layers. Do not use it to probe production tenants, reuse customer UUIDs, or perform destructive member/workspace operations outside local fixtures.
Inputs
- Python manifests, lockfiles, constraints, Dockerfiles, Compose files, Helm charts, Kubernetes manifests, Procfiles, systemd units, CI jobs, runner images, deployment templates, docs, SBOMs, generated reports, forks, wrappers, route code, service code, and API clients.
- Workspace-owned object inventory: agents, issues, projects, labels, comments, dependencies, members, workspaces, stats endpoints, prompts, runtime configuration, and agent instructions.
- Authorization evidence: route dependencies, service method signatures, caller identity propagation, role policy, owner/admin gates, last-owner protection, registration defaults, bind address, and audit logging.
- Tenant-boundary fixtures for at least two synthetic workspaces with distinct users, members, owners, agents, issues, projects, labels, comments, and dependencies.
- Operator evidence for exposure review: public registration, default bind address, UUID leakage, unexpected role changes, workspace deletion, project deletion, issue deletion, and agent instruction/config changes.
The prompt
You are remediating CVE-2026-47407 / GHSA-h8q5-cp56-rr65, the PraisonAI
Platform workspace takeover chain where URL-level membership checks are paired
with unscoped nested-resource lookups and member-level gates on privileged
workspace operations. Produce exactly one output:
- A reviewer-ready PR/change request that upgrades affected package usage,
scopes every workspace-owned service lookup, fixes member/workspace role
gates, adds safe tenant-boundary regression tests, refreshes generated
artifacts, and documents operator review actions, or
- TRIAGE.md if this repository does not control an affected PraisonAI Platform
runtime, fork, wrapper, image, deployment, or dependency.
## Rules
- Scope only CVE-2026-47407 / GHSA-h8q5-cp56-rr65 and directly related
workspace scoping, object ownership, member-management authorization, and
default deployment exposure.
- Treat bearer tokens, cookies, user IDs, workspace IDs, agent IDs, issue IDs,
project IDs, label/comment/dependency IDs, prompts, agent instructions,
runtime config, tenant data, model-provider keys, audit logs, and database
rows as sensitive.
- Do not send cross-tenant probes to production, use real customer accounts,
print tokens, dump tenant tables, replay public PoCs against live services,
or perform destructive member/workspace operations outside local fixtures.
- Do not weaken authentication, authorization, tenant isolation, CSRF
protection, audit logging, registration controls, or tests to silence the
finding.
- Do not auto-merge.
## Steps
1. Inventory every PraisonAI Platform reference controlled by this repository:
requirements, pyproject files, lockfiles, constraints, Dockerfiles,
Compose files, Helm charts, Kubernetes manifests, Procfiles, systemd units,
CI jobs, runner images, deployment templates, `.env.example`, docs, SBOMs,
generated dependency reports, forks, copied route/service code, and local
API wrappers.
2. Determine every resolved `praisonai-platform` version. A target is
vulnerable if it resolves to `0.1.2` or earlier.
3. Search owned code for the affected route/service pattern:
`require_workspace_member`, `workspace_id`, `AgentService`, `IssueService`,
`ProjectService`, `LabelService`, `CommentService`, `DependencyService`,
`MemberService`, `session.get`, `get`, `update`, `delete`, `get_stats`,
`add_member`, `update_member_role`, `remove_member`, `update_workspace`,
`delete_workspace`, and `/workspaces/{workspace_id}` routes.
4. For every nested route that accepts `workspace_id` plus another object ID,
prove that the service query filters by both object ID and the same
`workspace_id`.
5. For every mutation, prove that the service receives caller identity or role
and enforces the required role itself instead of trusting the route to have
done so.
6. If this repository only calls an externally owned PraisonAI Platform
service, stop with `TRIAGE.md` listing checked files, the external owner,
the required fixed version, and the expected tenant-boundary and RBAC
contract.
7. Upgrade all controlled package pins to `praisonai-platform 0.1.4+`.
Regenerate lockfiles, constraints, image metadata, SBOMs, dependency
reports, and generated docs.
8. Where the repository owns a fork, wrapper, route, compatibility shim, or
local service layer, fix workspace scoping:
- service `get`, `update`, `delete`, link, comment, label, and stats
methods receive `workspace_id`;
- queries filter by both resource ID and `workspace_id`;
- not-found and forbidden responses do not reveal whether another
workspace's object exists;
- route handlers pass URL `workspace_id` through to every service call;
- service-layer checks remain present even when route dependencies exist.
9. Fix member and workspace authorization in the same touched route family:
- role changes require owner authority or the documented product policy;
- member add/remove requires explicit owner/admin policy;
- members cannot promote themselves, demote owners, remove owners, or delete
workspaces;
- last-owner protection is enforced;
- workspace update/delete routes do not inherit a default member gate.
10. Review deployment defaults where this repo controls them:
- default bind address is intentional and documented;
- registration is disabled, invite-only, or explicitly gated for deployed
environments;
- reverse proxies and firewall rules do not expose test instances by
accident;
- seed/demo tenants cannot reach production data.
11. Add safe local regression tests with synthetic tenants:
- workspace A member cannot read, update, delete, link, label, comment on,
or get stats for workspace B resources;
- guessed agent, issue, project, label, comment, and dependency IDs fail
without object-existence leakage;
- member cannot promote self, promote another member, demote an owner,
remove an owner, or delete a workspace;
- owner/admin success paths still work according to product policy;
- denied responses and audit logs omit tokens, prompts, tenant content, and
secret values.
12. Add or verify audit events for denied cross-workspace attempts and
privileged member/workspace actions. Include actor, workspace, target
resource type, target ID, decision, and request ID, but no credentials or
sensitive content.
13. Add a PR body section named `CVE-2026-47407 operator actions` that states:
- PraisonAI Platform versions before and after;
- every workspace-owned route and service reviewed;
- before/after query scoping for agents, issues, projects, labels,
comments, dependencies, members, and workspaces;
- before/after role gates for member and workspace operations;
- whether open registration, default bind address, or public exposure
existed in controlled deployments;
- which logs operators should review for UUID swapping, unexpected
owner/member changes, workspace deletion, project/issue deletion, and
agent instruction or runtime configuration changes;
- which validation commands passed.
14. Run relevant validation: dependency install, lockfile checks,
tenant-boundary unit tests, API route tests, RBAC tests, migration checks,
lint/typecheck, deployment-template rendering, container build, SBOM
refresh, dependency/security scans, and local non-secret smoke checks
available in this repository.
15. Use PR title:
`fix(sec): remediate CVE-2026-47407 in PraisonAI workspace isolation`
## Stop conditions
- No affected PraisonAI Platform runtime, package pin, fork, wrapper, image, or
deployment is controlled by this repository.
- A fixed `praisonai-platform` version cannot be consumed without a broader
platform migration.
- The repository intentionally allows cross-workspace object access,
member-level role changes, open registration, or public default-bound
deployment; document the product/security-owner decision needed in
`TRIAGE.md`.
- Verification would require production cross-tenant probes, live customer
accounts, tenant-data queries, credential disclosure, or destructive
workspace/member operations.
- Validation fails for unrelated pre-existing reasons; document those failures
instead of broadening scope.
Verification - what the reviewer looks for
- No controlled lockfile, image, SBOM, dependency report, or deployment target
resolves
praisonai-platformto0.1.2or earlier. - Every workspace-owned service method filters by
workspace_id; route code does not discard the URL workspace before calling the service. - Mutating services enforce caller identity and role, not just object IDs.
- Member and workspace operations require the intended owner/admin policy and protect against self-promotion, owner demotion/removal, and last-owner loss.
- Negative tests cover cross-workspace reads, writes, deletes, stats, labels, comments, dependencies, agent records, member changes, and workspace deletion.
- Operator notes include exposure review for open registration, default bind address, UUID swapping, role changes, destructive actions, and agent instruction/runtime configuration changes.
Watch for
- Treating CVE-2026-47407 as fixed because only the package pin changed while a fork, wrapper, image, lockfile, or SBOM still carries vulnerable behavior.
- Fixing issues and projects while agents, labels, comments, dependencies, or workspace/member routes keep global lookups or default member gates.
- Route code that passes
workspace_idto list methods but not toget,update,delete, stats, label, or comment methods. - Service methods that assume the route already checked authorization.
- Test fixtures with one workspace only, which cannot catch UUID swapping.
- Returning different 403/404 bodies that reveal whether another workspace’s object exists.
- Leaving public registration and
0.0.0.0development defaults enabled in a deployed environment after the package upgrade.
Output contract
Return one of:
- A reviewer-ready PR/change request that upgrades every controlled
praisonai-platformruntime to0.1.4+, scopes all workspace-owned service lookups byworkspace_id, enforces role checks in services and routes, hardens member/workspace operations, adds tenant-boundary and RBAC tests, refreshes artifacts, and documents operator review actions. TRIAGE.mdwhen no affected runtime, package pin, fork, wrapper, image, deployment, route, service layer, or dependency is controlled by the repository.
The output must list versions before/after, every workspace-owned route and service reviewed, before/after query scoping, before/after role gates, registration/bind exposure, audit events, validation commands, and logs to review for UUID swapping or membership changes. It must not use production tenants, disclose tokens or prompts, weaken tenant isolation, or run destructive workspace/member operations outside fixtures.
Related recipes
- CVE-2026-48169 - PraisonAI Platform cross-workspace IDOR
- narrower issue/project and member-management recipe for the same package family.
- CVE-2026-47416 - PraisonAI Platform workspace owner promotion
- focused RBAC recipe for the member-role escalation slice.
- CVE-2026-47410 - PraisonAI Platform default JWT secret
- separate authentication weakness that can combine with workspace takeover exposure if secrets are shared or defaulted.
References
- GitHub Advisory Database: https://github.com/advisories/GHSA-h8q5-cp56-rr65
- Vendor advisory: https://github.com/MervinPraison/PraisonAI/security/advisories/GHSA-h8q5-cp56-rr65
- CVE record: https://www.cve.org/CVERecord?id=CVE-2026-47407
- PraisonAI project: https://github.com/MervinPraison/PraisonAI