CVE-2026-47418 - PraisonAI Platform project IDOR
PraisonAI Platform versions before 0.1.4 contain a project-level
cross-workspace authorization flaw. Project routes check that the caller is a
member of the workspace_id in the URL, but service methods can then look up,
update, delete, or return statistics for project_id by global primary key.
If a member of workspace A learns a project UUID from workspace B, the route
can authorize workspace A while the service acts on workspace B’s project.
This recipe targets the project-specific fix, not just the generic dependency bump. Multi-tenant agent platforms often store roadmaps, agent work queues, issue aggregates, and customer-sensitive operational context inside projects, so the PR needs workspace-scoped service queries and negative tenant-boundary tests for reads, writes, deletes, and stats.
Affected versions
- Vulnerable package:
praisonai-platform <0.1.4 - Fixed package:
praisonai-platform 0.1.4+ - Affected coordinate:
praisonai-platformon PyPI - Affected surface:
GET,PATCH,DELETE, and stats routes for/workspaces/{workspace_id}/projects/{project_id}and local forks or wrappers with the same route/service split - Affected code pattern: route code validates membership for URL
workspace_id, then calls project service methods such asget(project_id),update(project_id, ...),delete(project_id), orget_stats(project_id)without also filtering byworkspace_id.
Indicator-of-exposure
- The repository depends on, vendors, forks, wraps, or deploys
praisonai-platform <0.1.4. - The deployment supports multiple workspaces, projects, issues, agents, or tenants.
- Project service methods use
session.get(Project, project_id)or another primary-key-only lookup for workspace-owned project records. - Route handlers receive both
workspace_idandproject_id, checkrequire_workspace_member, and then discardworkspace_idbefore calling the service. - Tests use only one workspace or only happy-path owner/member fixtures, so they cannot catch a cross-workspace project ID swap.
Quick checks:
rg -n "praisonai-platform|praisonai_platform|ProjectService|project_id|get_stats|require_workspace_member|session\\.get\\(Project|workspace_id.*project_id|/projects" .
python -m pip show praisonai-platform
python -m pip freeze | rg -i '^praisonai-platform=='
Windows:
rg -n "praisonai-platform|praisonai_platform|ProjectService|project_id|get_stats|require_workspace_member|session\\.get\\(Project|workspace_id.*project_id|/projects" .
python -m pip show praisonai-platform
python -m pip freeze | rg -i '^praisonai-platform=='
Do not validate by swapping production workspace or project IDs. Use local fixtures with synthetic tenants and non-sensitive project records.
Remediation strategy
- Upgrade every controlled
praisonai-platformdependency, constraints file, lockfile, image, deployment artifact, SBOM, and generated dependency report to0.1.4+. - Require project service methods to receive
workspace_idand filter by bothProject.idandProject.workspace_id. - Enforce caller role for mutating project operations in the service layer as well as the route layer. Reads, writes, deletes, and stats should all bind the project to the authorized workspace.
- Normalize forbidden/not-found behavior so denied cross-workspace requests do not reveal whether the foreign project exists.
- Add local regression tests for cross-workspace project read, update, delete, stats, and any issue/project aggregate path that exposes project metadata.
- Add audit events for denied cross-workspace project access without logging bearer tokens, cookies, prompts, project content, tenant data, or secrets.
When to use it
Use this recipe when a repository deploys, vendors, forks, wraps, or packages
PraisonAI Platform project APIs for multi-workspace or customer environments.
It is most important when routes accept both workspace_id and project_id,
then project services read, update, delete, or return stats by global project
ID.
Use it to upgrade the package and bind every project operation to the authorized workspace at the service layer. Do not use it to swap production workspace or project IDs while validating exposure.
Inputs
- Python manifests, lockfiles, constraints, Dockerfiles, Compose files, Helm charts, Kubernetes manifests, Procfiles, systemd units, CI jobs, deployment templates, docs, SBOMs, generated reports, forks, wrappers, route code, project services, API clients, and project aggregate helpers.
- Project-owned data paths: project get/update/delete/stats, project issue aggregates, metadata, status, title, description, lead, icon, labels, comments, agents, and any joins through project records.
- Authorization evidence: URL
workspace_id,project_id, route dependencies, service query predicates, caller identity, caller role, mutation policy, not-found/forbidden behavior, and audit logging. - Synthetic tenant-boundary fixtures for two or more workspaces with distinct owners, members, projects, issues, labels, comments, and aggregate stats.
- Operator evidence for UUID-swapping review: unexpected project reads, edits, deletes, stats access, issue aggregate access, and suspicious denied cross-workspace attempts.
The prompt
You are remediating CVE-2026-47418 / GHSA-943m-6wx2-rc2j, a PraisonAI
Platform project IDOR where workspace membership is checked for one workspace
but project service methods act on a globally looked-up project from another
workspace. Produce exactly one output:
- A reviewer-ready PR/change request that upgrades affected package usage,
scopes project service queries by workspace, adds negative tenant-boundary
tests for project read/write/delete/stats paths, 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-47418 / GHSA-943m-6wx2-rc2j and directly related project
tenant-boundary checks.
- Treat bearer tokens, cookies, user IDs, workspace IDs, project IDs, issue
IDs, tenant data, prompts, agent configuration, 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 project tables, or broaden into unrelated PraisonAI
advisories except where shared project service helpers must be fixed.
- Do not weaken authentication, authorization, tenant isolation, CSRF
protection, audit logging, 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, deployment templates, `.env.example`, docs, SBOMs, generated
dependency reports, forks, wrappers, and local API routes.
2. Determine every resolved `praisonai-platform` version. A target is
vulnerable if it resolves to a version earlier than `0.1.4`.
3. Search owned code for project route/service splits:
`ProjectService`, `project_id`, `workspace_id`, `require_workspace_member`,
`session.get(Project`, `get_stats`, `update_project`, `delete_project`,
`list_for_workspace`, and routes under
`/workspaces/{workspace_id}/projects`.
4. For each route that receives both `workspace_id` and `project_id`, prove the
service query also filters by the same `workspace_id` and enforces the
caller's role for mutations.
5. 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 project-isolation contract.
6. Upgrade all controlled package pins to `praisonai-platform 0.1.4+`.
Regenerate lockfiles, constraints, image metadata, SBOMs, dependency
reports, and generated docs.
7. Where the repository owns a fork, wrapper, route, or compatibility shim,
fix project scoping:
- service `get`, `update`, `delete`, and stats methods receive
`workspace_id`;
- queries filter by both `Project.id` and `Project.workspace_id`;
- mutating methods receive caller identity and enforce caller role;
- not-found and forbidden responses do not reveal whether another
workspace's project exists;
- issue and aggregate helpers that join through project data preserve the
same workspace predicate.
8. Add safe local regression tests with synthetic tenants:
- workspace A member cannot read workspace B project by UUID;
- workspace A member cannot update workspace B project title, description,
status, lead, icon, or metadata;
- workspace A member cannot delete workspace B project;
- workspace A member cannot retrieve workspace B project stats or aggregate
issue counts;
- owner success paths still work for projects inside the caller's
workspace;
- denied responses and audit logs omit tokens, prompts, tenant content, and
secret values.
9. Add or verify audit events for denied cross-workspace project attempts.
Include actor, authorized workspace, requested project ID, decision, and
request ID, but no credentials or project content.
10. Add a PR body section named `CVE-2026-47418 operator actions` that states:
- PraisonAI Platform versions before and after;
- every project route and service method reviewed;
- before/after query predicates for `get`, `update`, `delete`, and stats;
- whether low-privilege members could read, modify, delete, or infer
foreign project data before the patch;
- which logs operators should review for UUID swapping, unexpected project
edits, project deletion, and suspicious stats access;
- which validation commands passed.
11. Run relevant validation: dependency install, lockfile checks,
tenant-boundary unit tests, API route tests, migration checks,
lint/typecheck, deployment-template rendering, container build, SBOM
refresh, dependency/security scans, and local non-secret smoke checks.
12. Use PR title:
`fix(sec): remediate CVE-2026-47418 in PraisonAI projects`.
## 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 project access; document
the product/security-owner decision required in `TRIAGE.md`.
- Verification would require production cross-tenant probes, live customer
accounts, tenant-data queries, or credential disclosure.
- 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, or deployment resolves
praisonai-platformbelow0.1.4. - Project service methods filter by
workspace_idand do not rely on global primary-key lookup for tenant authorization. - Route-layer and service-layer authorization agree on caller identity, workspace membership, and minimum role for project mutations.
- Negative tests prove cross-workspace project ID swaps fail for reads, updates, deletes, stats, and related issue aggregates.
- Operator notes include log review for project UUID swapping, unexpected edits, project deletions, and suspicious stats access.
Watch for
- Updating the package while Docker images, constraints, generated reports, or SBOMs still resolve a vulnerable version.
- Fixing project list routes while leaving
get,update,delete, or stats methods as global primary-key lookups. - Route code that checks
workspace_idbut then discards it before calling project services. - Service methods that trust callers to have already authorized the operation.
- Tests with only one workspace fixture.
- Error responses that disclose whether a guessed foreign project exists.
Output contract
Return one of:
- A reviewer-ready PR/change request that upgrades every controlled
praisonai-platformruntime to0.1.4+, scopes project service queries byworkspace_id, enforces caller role for mutations, normalizes denied responses, adds tenant-boundary tests for read/update/delete/stats paths, refreshes artifacts, and documents operator review actions. TRIAGE.mdwhen no affected runtime, package pin, fork, wrapper, image, deployment, project route, service layer, or dependency is controlled by the repository.
The output must list versions before/after, every project route and service reviewed, before/after query predicates, mutation role gates, denied-response behavior, tests added, audit events, validation commands, and logs to review for project UUID swapping. It must not probe production tenants, dump project tables, disclose tokens/prompts, or weaken tenant isolation.
Related recipes
- CVE-2026-48169 - PraisonAI Platform cross-workspace IDOR
- the broader tenant-boundary cluster that includes project and issue IDOR patterns.
- CVE-2026-47412 - PraisonAI Platform workspace delete RBAC bypass
- a destructive workspace action in the same authorization family.
References
- GitHub Advisory: https://github.com/advisories/GHSA-943m-6wx2-rc2j
- Vendor advisory: https://github.com/MervinPraison/PraisonAI/security/advisories/GHSA-943m-6wx2-rc2j
- NVD CVE: https://nvd.nist.gov/vuln/detail/CVE-2026-47418
- GitLab Advisory Database: https://advisories.gitlab.com/pkg/pypi/praisonai-platform/CVE-2026-47418/
- PraisonAI project: https://github.com/MervinPraison/PraisonAI