feat: Add support to run notebooks on its own subdomains in Istio - #562
feat: Add support to run notebooks on its own subdomains in Istio#562sven-ernw wants to merge 7 commits into
Conversation
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
|
Hi @kimwnasptd @juliusvonkohout @thesuperzapper @ederign, CC: @lorinl |
|
/area v1 |
|
I am still struggling to find time to review this. Maybe after GSOC has finished in October. |
|
Hi Julius, |
|
This pull request has been automatically marked as stale because it has not had recent activity. Members may comment |
|
I will finish the open tasks of the MR next month. |
It could make sense to align first in the WG calls or on slack with @andyatmiami @ederign @thesuperzapper @kimwnasptd |
|
This pull request has been automatically marked as stale because it has not had recent activity. Members may comment |
|
The patch is still work in progress. |
|
This pull request has been automatically marked as stale because it has not had recent activity. Members may comment |
|
Please always use rebase, not merge from master. Rebase kaaeps a valid commit history. |
…domains when Istio is used. This isolates the notebook's origin from the dashboard / Kubeflow API origin in the browser and addresses a security problem that allows session hijacking through a malicious notebook. Signed-off-by: Lorin Lehawany <llehawany@ernw.de> Signed-off-by: Sven Nobis <snobis@ernw.de>
|
Thanks @juliusvonkohout . Did a rebase. The feature is now complete. |
…domains when Istio is used. This isolates the notebook's origin from the dashboard / Kubeflow API origin in the browser and addresses a security problem that allows session hijacking through a malicious notebook. Added configuration changes to manifests. Signed-off-by: Lorin Lehawany <llehawany@ernw.de> Signed-off-by: Sven Nobis <snobis@ernw.de>
|
@thesuperzapper @christian-heusel for review |
There was a problem hiding this comment.
Pull request overview
Adds opt-in Istio subdomain routing to isolate notebooks from Kubeflow dashboard/API origins and support the external security hardening flow.
Changes:
- Generates notebook, authentication, and legacy-route redirect VirtualServices.
- Adds controller configuration and documentation.
- Adds fixture-based VirtualService tests.
Reviewed changes
Copilot reviewed 13 out of 13 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
components/notebook-controller/README.md |
Documents Istio settings. |
controllers/test_fixtures/notebook_controller_virtualservice_test_subdomains.yaml |
Covers default subdomain routing. |
controllers/test_fixtures/notebook_controller_virtualservice_test_subdomains_different_auth_path.yaml |
Covers custom authentication paths. |
controllers/test_fixtures/notebook_controller_virtualservice_test_rewrite.yaml |
Covers URI rewriting. |
controllers/test_fixtures/notebook_controller_virtualservice_test_istio_host_set.yaml |
Covers custom Istio hosts. |
controllers/test_fixtures/notebook_controller_virtualservice_test_istio_gateway_set.yaml |
Covers custom gateways. |
controllers/test_fixtures/notebook_controller_virtualservice_test_headers.yaml |
Covers request headers. |
controllers/test_fixtures/notebook_controller_virtualservice_test_default_config.yaml |
Covers default routing. |
controllers/test_fixtures/notebook_controller_virtualservice_test_cluster_domain_set.yaml |
Covers custom cluster domains. |
controllers/notebook_controller.go |
Implements multi-VirtualService routing and reconciliation. |
controllers/notebook_controller_test.go |
Adds generation tests and fixture decoding. |
config/manager/params.env |
Adds subdomain configuration defaults. |
config/manager/manager.yaml |
Injects new controller environment variables. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
…domains when Istio is used. This isolates the notebook's origin from the dashboard / Kubeflow API origin in the browser and addresses a security problem that allows session hijacking through a malicious notebook. Improved preparation and clean-up of environment variables. Signed-off-by: Lorin Lehawany <llehawany@ernw.de> Signed-off-by: Sven Nobis <snobis@ernw.de>
…domains when Istio is used. This isolates the notebook's origin from the dashboard / Kubeflow API origin in the browser and addresses a security problem that allows session hijacking through a malicious notebook. Delete redirect VirtualServices that are no longer part of the desired state, for example after ISTIO_USE_NOTEBOOK_SUBDOMAINS is disabled. Signed-off-by: Lorin Lehawany <llehawany@ernw.de> Signed-off-by: Sven Nobis <snobis@ernw.de>
|
@thesuperzapper @christian-heusel I have reviewed and fixed all suggestions from the CoPilot review. |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 13 out of 13 changed files in this pull request and generated 2 comments.
Comments suppressed due to low confidence (1)
components/notebook-controller/controllers/notebook_controller_test.go:643
- This cleanup only restores variables that existed before the test.
TestReconcileVirtualServiceDeletesStaleRedirectssetsISTIO_HOST_NOTEBOOKandISTIO_HOST_AUTHeven when they were originally absent, so those values leak into later package tests. Register cleanup for both original states and unset keys that were absent.
oldValue, hadValue := os.LookupEnv(key)
if hadValue {
t.Cleanup(func() {
os.Setenv(key, oldValue)
})
}
…domains when Istio is used. This isolates the notebook's origin from the dashboard / Kubeflow API origin in the browser and addresses a security problem that allows session hijacking through a malicious notebook. Check actualErrorState before comparing error text. Signed-off-by: Lorin Lehawany <llehawany@ernw.de> Signed-off-by: Sven Nobis <snobis@ernw.de>
…domains when Istio is used. This isolates the notebook's origin from the dashboard / Kubeflow API origin in the browser and addresses a security problem that allows session hijacking through a malicious notebook. Improved comment why the Authorization token is removed. Signed-off-by: Lorin Lehawany <llehawany@ernw.de> Signed-off-by: Sven Nobis <snobis@ernw.de>
| "remove": []interface{}{ | ||
| "Authorization", | ||
| }, |
There was a problem hiding this comment.
This is true. Good catch because Istio does not documented this feature.
There was a problem hiding this comment.
We have added the environment setting ISTIO_DISABLE_ENVOY_HEADER_MANIPULATION to disable envoy's substitution commands syntax in headers. This should be enabled for security reasons because this prevents access token leakage to user-controlled notebooks.
It is not enabled by default to avoid breaking changes. What do you think @thesuperzapper @christian-heusel ?
See commit: ed4c42b for details.
…domains when Istio is used. This isolates the notebook's origin from the dashboard / Kubeflow API origin in the browser and addresses a security problem that allows session hijacking through a malicious notebook. Added environment setting ISTIO_DISABLE_ENVOY_HEADER_MANIPULATION to disable envoy's substitution commands syntax in headers. This should be enabled for security reasons because this prevents access token leakage to user-controlled notebooks. Signed-off-by: Lorin Lehawany <llehawany@ernw.de> Signed-off-by: Sven Nobis <snobis@ernw.de>
|
@thesuperzapper @christian-heusel |
This PR makes it possible to host notebooks on their own subdomains when Istio is used by adding this feature to the Kubeflow
notebook-controller. This isolates the notebook's origin from the dashboard / Kubeflow API origin in the browser and addresses a security problem that allows session hijacking through a malicious notebook.This pull request addresses the security issue described in GHSA-qjw6-hpc7-w36h
The relevant changes to the community-distribution can be found in pull request kubeflow/community-distribution#3550 .
Please note, we will add the feature to v2 once the feature is approved.
(reopend PR from !7742 in kubeflow/kubeflow)
Motivation / Why this change is needed
This change addresses a security problem that allows session hijacking through a malicious notebook:
An attacker can log session cookies by misusing the Notebook feature: An attacker can create a Notebook with a custom image that logs the cookies / trigger API requests. Afterwards, they must convince the victim to visit the URL of the Notebook (a phishing attack). This is a classic phishing attack scenario.
Disallowing custom images wouldn't be sufficient because you can achieve the same thing with a few extra steps using one of default images.
The problem relies on the fact that the Notebooks and the Kubeflow Dashboard / APIs are in the Browser's same origin. Thus, any attacker-controlled site would be able to access the Kubeflow API in the context of the victim.
To prevent this attack, the authenticating cookies need to be removed from requests forwarded to Notebook's Pods, and the notebooks need to be hosted on a different domain. This PR accomplishes this.
A proof of concept that demonstrates the problem is available but will not be disclosed until the problem is fixed.
Request for Feedback
At the moment, we are removing all cookie headers for security reasons before the request is forwarded to the notebook container. This breaks the functionality in some notebook images. So the goal is to remove only the authenticating cookie and keep the remaining cookies..Our idea is to use a Istio Wasm Plugin that accomplishes this.As discussed with @thesuperzapper, we will ad a envoy filter to remove the authorizing cookie. This will be part of a pull request in kubeflow-manifests.
What this PR accomplishes
ISTIO_HOST_NOTEBOOKin the notebook's VirtualServices whenISTIO_USE_NOTEBOOK_SUBDOMAINSis set to prevent access to the dashboard / APIs from attacker-controlled notebooks through the browser.ISTIO_HOST_AUTHfor theISTIO_AUTH_PATH.components/notebook-controller/controllers/notebook_controller.go). The cookie header cannot be removed as cookies are required by some notebook images. We remove the authenticating cookie through anEnvoyFilter. This is part of security: Prevent session hijacking through a malicious notebook. community-distribution#3550 and not this PR.This pull request does not change any default behavior of the notebook's controller. Unless
ISTIO_USE_NOTEBOOK_SUBDOMAINSis explicitly set, the notebook controller works as before.Open Tasks(done)This PR is a draft at the moment because the following parts are work in progress:EnvoyFilter. This will not be part of this pull request as it will be part of the Kubeflow manifests repository. Thanks to @thesuperzapper for the productive discussion last year.Configuration
The subdomain feature is disabled by default as the setup has some prerequisites and is a breaking change. It requires a wildcard domain and wildcard TLS certificate or automated domain and certificate management.
To enable the feature, do the following configuration steps:
notebook-controller:configmapofoauth2must also be adjusted by enabling cookies for subdomains. Edit theoauth2_proxy.cfgconfiguration of theoauth2-proxy-hk55gm96k4ConfigMap in theoauth2-proxynamespace and add the following setting:cookie_domains = "kubeflow.example.com"Detailed instructions are part of the pull request !3550 in kubeflow-manifests.
Notes
Setting
forwardOriginalTokentofalseis not a solution as this would break existing functionality. We rather remove the token from requests to the notebooks only.