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-platform on 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_id and another object ID but do not pass workspace_id into 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-platform dependency, lockfile, image, deployment, generated dependency report, and SBOM to 0.1.4+.
  • Treat route-level membership as necessary but insufficient. Every service method that touches workspace-owned objects must receive workspace_id and 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-platform to 0.1.2 or 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_id to list methods but not to get, 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.0 development 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-platform runtime to 0.1.4+, scopes all workspace-owned service lookups by workspace_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.md when 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.

References