Bug 2506350 (CVE-2026-16745)

Summary: CVE-2026-16745 odh-dashboard: odh-dashboard: Backend port 8080 trusts x-forwarded-access-token without origin validation
Product: [Other] Security Response Reporter: OSIDB Bzimport <bzimport>
Component: vulnerabilityAssignee: Product Security <prodsec-ir-bot>
Status: NEW --- QA Contact:
Severity: high Docs Contact:
Priority: high    
Version: unspecifiedKeywords: Security
Target Milestone: ---   
Target Release: ---   
Hardware: All   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: ---
Doc Text:
A flaw was found in odh-dashboard, the web console component of Red Hat OpenShift AI (RHOAI). Due to incorrect network binding, a malicious actor within the cluster can bypass authentication and impersonate any user by providing an arbitrary access token. This allows an attacker to gain unauthorized access to the Kubernetes API, potentially leading to arbitrary code execution, privilege escalation, or information disclosure.
Story Points: ---
Clone Of: Environment:
Last Closed: Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:

Description OSIDB Bzimport 2026-07-23 06:18:06 UTC
A flaw was found in odh-dashboard, the web console component of Red Hat OpenShift AI (RHOAI). The dashboard backend's HTTP server binds to 0.0.0.0:8080 (backend/src/utils/constants.ts: `export const IP = process.env.IP || '0.0.0.0';`) and treats the `x-forwarded-access-token` header as an authenticated identity assertion (backend/src/utils/directCallUtils.ts, `getDirectCallOptions`), using its value directly as the Bearer token for calls made to the Kubernetes API on behalf of the caller.

In the intended deployment, a kube-rbac-proxy sidecar terminates TLS and sets this header only after validating the caller's real OpenShift OAuth token, then forwards the request to the backend over localhost. However, because the backend binds to 0.0.0.0 rather than 127.0.0.1, and the shipped NetworkPolicy (manifests/modular-architecture/networkpolicy.yaml) only restricts ingress on the TLS-fronted ports (8443, 8043, 8143, 8243, 8343, 8543, 8643, 8743), port 8080 itself is left unrestricted. The base manifests (manifests/core-bases/base/) ship no NetworkPolicy at all.

As a result, any pod in the cluster that can reach the dashboard backend's pod IP on port 8080 can send a plain HTTP request directly to the backend, bypassing the kube-rbac-proxy sidecar entirely, and set x-forwarded-access-token to an arbitrary value. The backend accepts this value as the caller's Kubernetes bearer token with no origin or provenance check, allowing impersonation of any user whose token the attacker supplies. This was verified on a live OCP 4.21 cluster: port 8080 was reachable from any pod in any namespace.

Fixed upstream via opendatahub-io/odh-dashboard PR #7411 (merged 2026-05-27), which binds the backend to 127.0.0.1 (only reachable from the kube-rbac-proxy sidecar in the same pod) and switches the liveness/readiness probes to exec-based curl checks against 127.0.0.1, since the kubelet can no longer reach the previous 0.0.0.0-bound port directly. Confirmed still present on main prior to that PR; the fix is not yet in RHOAI 3.4's release branch, only RHOAI 3.5.

This affects RHOAI 2.25, 3.3, and 3.4; fixed in RHOAI 3.5.

Identified by Red Hat Product Security's Project Glasswing (Mythos) AI security audit; tracked as RHOAIENG-69351 (see also sibling tickets RHOAIENG-73379 and RHOAIENG-73380 for the same finding on RHOAI 2.25 and 3.3 respectively).