Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

don't distinguish private ips in xsrf tokens #4991

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

minrk
Copy link
Member

@minrk minrk commented Jan 28, 2025

almost certainly proxy ips, which don't solve the problem anyway, and can change due to multiple proxy replicas

maybe closes jupyterhub/zero-to-jupyterhub-k8s#3422 for most users. A case where it wouldn't is a proxy outside the cluster/LAN, where the proxy's own ip is a global ip. For that, we'd need a more full opt-out of using ips.

almost certainly proxy ips, which don't solve the problem anyway,
and can change due to replicas
@minrk minrk added the bug label Jan 28, 2025
@manics
Copy link
Member

manics commented Jan 28, 2025

Does this potentially open up a vulnerability with CGNAT?

…ID_HEADERS

for influencing how anonymous xsrf tokens are computed

including fully opting out of distinguishable xsrf ids for anonymous (login) requests
@minrk
Copy link
Member Author

minrk commented Jan 28, 2025

I believe is_private is False for CGNAT, so there is no change in behavior for those IPs. These values don't need to be perfect (e.g. everyone in a room behind the same router will have the same ip). The main goal is to limit the portability of xsrf cookies to mitigate things like cookie tossing.

@minrk
Copy link
Member Author

minrk commented Jan 28, 2025

I added a couple of environment variables $JUPYTERHUB_XSRF_ANONYMOUS_USE_IP and $JUPYTERHUB_XSRF_ANONYMOUS_ID_HEADERS to influence how the anonymous id is computed. I did this because it's influencing a top-level utility function and traitlets-style config will be a bit of a pain to get a Configurable instance properly loaded. But not impossible, if folks think standard config would be better here. The unique anonymous id can be fully disabled with:

JUPYTERHUB_XSRF_ANONYMOUS_USE_IP=0
JUPYTERHUB_XSRF_ANONYMOUS_ID_HEADERS=

in which case an xsrf cookie for one client is valid for all clients (assuming client is not authenticated), which opens a path to cookie tossing.

@@ -230,6 +234,17 @@ def check_xsrf_cookie(handler):
)


# allow disabling using ip in anonymous id
_anonymous_use_ip = _bool_env("JUPYTERHUB_XSRF_ANONYMOUS_USE_IP", default=True)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't we use JUPYTERHUB_XSRF_ANONYMOUS_USE_IP with False by default to avoid any security problem and keep the old behaviour?

I think this problem is more likely to occur in k8s deployment, so we can set this property to True on the chart side.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think so. True means keeping the current behavior by default, where the ip is used, which is correct most of the time (including in most z2jh deployments). Only where proxy headers don't properly propagate does this problem come up.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

403 Forbidden XSRF cookie does not match POST argument after updating to the latest helm chart version (3.3.7)
3 participants