CVE-2026-18950: Odh-dashboard: odh-dashboard: confused-deputy privilege escalation via unchecked roleref in rolebinding creation
A flaw was found in odh-dashboard. An authenticated user of the dashboard can exploit a vulnerability related to how RoleBindings are created. The system does not properly validate the roleRef field, allowing a user to specify an arbitrary role, including highly privileged ones like cluster-admin. This can lead to privilege escalation, where an attacker gains unauthorized elevated access within their namespace and potentially persistent control over the system.
Other sources
Description
Description of problem The POST route at backend/src/routes/api/rolebindings/index.ts:35-62 accepts the full V1RoleBinding body from the user and passes it to the K8s API. The requestSecurityGuard() validates metadata.namespace and metadata.name but does NOT validate roleRef.name.
A user can create a RoleBinding with an arbitrary roleRef (e.g., referencing cluster-admin or any other ClusterRole) as long as the name and namespace match the expected patterns. The dashboard SA has create rolebindings permission cluster-wide.
Impact:
Authenticated dashboard user can grant themselves any ClusterRole within their namespace
Combined with RHOAIENG-69306 (cluster-wide secrets access via dashboard SA), this enables privilege escalation
Enables persistent access by binding privileged roles to attacker-controlled service accounts
Prerequisites RHOAI/ODH with dashboard component enabled
Authenticated dashboard user (any valid credential)
User must have access to the RHOAI dashboard UI
Steps to Reproduce Authenticate to the dashboard as any user
Send a POST request to the rolebindings endpoint with a crafted roleRef:
curl -X POST -H "Authorization: Bearer <user-token>" \ -H "Content-Type: application/json" \ https://<dashboard-url>/api/rolebindings \ -d '{ "apiVersion": "rbac.authorization.k8s.io/v1", "kind": "RoleBinding", "metadata": { "name": "jupyter-nb-<username>", "namespace": "<user-namespace>" }, "roleRef": { "apiGroup": "rbac.authorization.k8s.io", "kind": "ClusterRole", "name": "cluster-admin" }, "subjects": [{ "kind": "User", "name": "<attacker-username>" }] }' The dashboard backend creates the RoleBinding without validating the roleRef, granting cluster-admin in the target namespace.
Actual results The requestSecurityGuard() at route-security.ts:43-107 validates:
metadata.namespace: must be workbenchNamespace or dashboardNamespace
metadata.name: must match jupyter-nb-<translatedUsername>, jupyterhub-singleuser-profile-<translatedUsername>-envs, or <workbenchNamespace>-image-pullers
But roleRef.name is NOT validated. The dashboard SA creates the RoleBinding using its own permissions (which include cluster-wide rolebindings CRUD per RHOAIENG-69306).
Expected results roleRef.name should be validated against an allowlist of permitted roles (e.g., only image-puller, notebook-access roles)
The RoleBinding should be created using the user's token (impersonation), not the SA token
Reproducibility Always - The code path is deterministic.
Found in what build CONFIRMED in code: opendatahub-io/odh-dashboard (current main branch)
LIKELY VULNERABLE: All RHOAI versions with dashboard rolebindings API
Describe any workarounds Restrict dashboard access to trusted users only
Monitor for unexpected RoleBindings referencing cluster-admin (audit log alerting)
Implement OPA/Gatekeeper policy to reject RoleBindings with cluster-admin roleRef in user namespaces
Additional information Root Cause:
// backend/src/routes/api/rolebindings/index.ts:35-62 // Uses secureRoute(fastify) (NOT secureAdminRoute) // Entire request.body (V1RoleBinding) passed to createNamespacedCustomObject // requestSecurityGuard checks metadata.namespace and metadata.name // but does NOT check roleRef.name CWEs:
CWE-441: Unintended Proxy or Intermediary (Confused Deputy)
CWE-863: Incorrect Authorization
CWE-269: Improper Privilege Management
Discovery Method:
Project Glasswing (Mythos) automated security audit.
Related issues:
RHOAIENG-69306: Dashboard SA cluster-wide RBAC permissions (enables the CRB creation)
RHOAIENG-69307: Cross-namespace SSRF via llama-stack proxy (same dashboard)
— Red Hat
Affected Software
Remediation
Recommended actions to resolve this vulnerability, in priority order.
- Configuration
Update backend/src/routes/api/rolebindings/index.ts (request handling) / requestSecurityGuard() so that roleRef.name is validated against an allowlist of permitted roles; reject requests where roleRef.name references cluster-admin (and other disallowed ClusterRoles) in user namespaces.
odh-dashboard (RoleBindings API) roleRef.name validation = Validated against allowlist of permitted roles only (e.g., only image-puller, notebook-access roles) - Configuration
Implement an OPA/Gatekeeper policy to reject RoleBinding objects whose roleRef points to the cluster-admin ClusterRole when RoleBindings are created from within user namespaces.
OPA/Gatekeeper Constraint to reject RoleBindings with cluster-admin roleRef in user namespaces = enabled - Compensating control
Monitor/audit for unexpected RoleBindings that reference cluster-admin and alert on matches (audit log alerting).
- Compensating control
Restrict ODH dashboard access to trusted users only, since an authenticated dashboard user can exploit the RoleBindings creation issue.
Event History
Frequently Asked Questions
What is the severity of CVE-2026-18950?
CVE-2026-18950 has a high severity rating of 8.8.
How do I fix CVE-2026-18950?
To mitigate CVE-2026-18950, ensure proper validation is implemented for the `roleRef` field in RoleBindings.
What type of attack does CVE-2026-18950 enable?
CVE-2026-18950 enables a privilege escalation attack through a confused deputy pattern.
Who is affected by CVE-2026-18950?
Authenticated users of the odh-dashboard are affected by CVE-2026-18950.
What component is vulnerable in CVE-2026-18950?
The vulnerable component in CVE-2026-18950 is the odh-dashboard related to RoleBinding creation.