mirror of
https://github.com/jupyterhub/jupyterhub.git
synced 2025-10-14 13:33:00 +00:00
Compare commits
10 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
42191672ac | ||
![]() |
669d8d7b65 | ||
![]() |
171026583c | ||
![]() |
78a3dc5b01 | ||
![]() |
21c37309a5 | ||
![]() |
3d40be5890 | ||
![]() |
ac72c60cb3 | ||
![]() |
92264696b1 | ||
![]() |
f2b7b69c3e | ||
![]() |
e0f001271b |
@@ -6,7 +6,7 @@ info:
|
|||||||
description: The REST API for JupyterHub
|
description: The REST API for JupyterHub
|
||||||
license:
|
license:
|
||||||
name: BSD-3-Clause
|
name: BSD-3-Clause
|
||||||
version: 4.1.2
|
version: 4.1.4
|
||||||
servers:
|
servers:
|
||||||
- url: /hub/api
|
- url: /hub/api
|
||||||
security:
|
security:
|
||||||
|
@@ -10,6 +10,40 @@ command line for details.
|
|||||||
|
|
||||||
## 4.1
|
## 4.1
|
||||||
|
|
||||||
|
### 4.1.4 - 2024-03-30
|
||||||
|
|
||||||
|
([full changelog](https://github.com/jupyterhub/jupyterhub/compare/4.1.3...4.1.4))
|
||||||
|
|
||||||
|
#### Bugs fixed
|
||||||
|
|
||||||
|
- avoid xsrf check on navigate GET requests [#4759](https://github.com/jupyterhub/jupyterhub/pull/4759) ([@minrk](https://github.com/minrk), [@consideRatio](https://github.com/consideRatio))
|
||||||
|
|
||||||
|
#### Contributors to this release
|
||||||
|
|
||||||
|
The following people contributed discussions, new ideas, code and documentation contributions, and review.
|
||||||
|
See [our definition of contributors](https://github-activity.readthedocs.io/en/latest/#how-does-this-tool-define-contributions-in-the-reports).
|
||||||
|
|
||||||
|
([GitHub contributors page for this release](https://github.com/jupyterhub/jupyterhub/graphs/contributors?from=2024-03-26&to=2024-03-30&type=c))
|
||||||
|
|
||||||
|
@consideRatio ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Fjupyterhub+involves%3AconsideRatio+updated%3A2024-03-26..2024-03-30&type=Issues)) | @minrk ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Fjupyterhub+involves%3Aminrk+updated%3A2024-03-26..2024-03-30&type=Issues))
|
||||||
|
|
||||||
|
### 4.1.3 - 2024-03-26
|
||||||
|
|
||||||
|
([full changelog](https://github.com/jupyterhub/jupyterhub/compare/4.1.2...4.1.3))
|
||||||
|
|
||||||
|
#### Bugs fixed
|
||||||
|
|
||||||
|
- respect jupyter-server disable_check_xsrf setting [#4753](https://github.com/jupyterhub/jupyterhub/pull/4753) ([@minrk](https://github.com/minrk), [@consideRatio](https://github.com/consideRatio))
|
||||||
|
|
||||||
|
#### Contributors to this release
|
||||||
|
|
||||||
|
The following people contributed discussions, new ideas, code and documentation contributions, and review.
|
||||||
|
See [our definition of contributors](https://github-activity.readthedocs.io/en/latest/#how-does-this-tool-define-contributions-in-the-reports).
|
||||||
|
|
||||||
|
([GitHub contributors page for this release](https://github.com/jupyterhub/jupyterhub/graphs/contributors?from=2024-03-25&to=2024-03-26&type=c))
|
||||||
|
|
||||||
|
@consideRatio ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Fjupyterhub+involves%3AconsideRatio+updated%3A2024-03-25..2024-03-26&type=Issues)) | @minrk ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Fjupyterhub+involves%3Aminrk+updated%3A2024-03-25..2024-03-26&type=Issues))
|
||||||
|
|
||||||
### 4.1.2 - 2024-03-25
|
### 4.1.2 - 2024-03-25
|
||||||
|
|
||||||
4.1.2 fixes a regression in 4.1.0 affecting named servers.
|
4.1.2 fixes a regression in 4.1.0 affecting named servers.
|
||||||
|
@@ -3,7 +3,7 @@
|
|||||||
# Copyright (c) Jupyter Development Team.
|
# Copyright (c) Jupyter Development Team.
|
||||||
# Distributed under the terms of the Modified BSD License.
|
# Distributed under the terms of the Modified BSD License.
|
||||||
# version_info updated by running `tbump`
|
# version_info updated by running `tbump`
|
||||||
version_info = (4, 1, 2, "", "")
|
version_info = (4, 1, 4, "", "")
|
||||||
|
|
||||||
# pep 440 version: no dot before beta/rc, but before .dev
|
# pep 440 version: no dot before beta/rc, but before .dev
|
||||||
# 0.1.0rc1
|
# 0.1.0rc1
|
||||||
|
@@ -178,10 +178,35 @@ def get_xsrf_token(handler, cookie_path=""):
|
|||||||
return xsrf_token
|
return xsrf_token
|
||||||
|
|
||||||
|
|
||||||
|
def _needs_check_xsrf(handler):
|
||||||
|
"""Does the given cookie-authenticated request need to check xsrf?"""
|
||||||
|
|
||||||
|
if getattr(handler, "_token_authenticated", False):
|
||||||
|
return False
|
||||||
|
|
||||||
|
fetch_mode = handler.request.headers.get("Sec-Fetch-Mode", "unspecified")
|
||||||
|
if fetch_mode in {"websocket", "no-cors"} or (
|
||||||
|
fetch_mode in {"navigate", "unspecified"}
|
||||||
|
and handler.request.method.lower() in {"get", "head", "options"}
|
||||||
|
):
|
||||||
|
# no xsrf check needed for regular page views or no-cors
|
||||||
|
# or websockets after allow_websocket_cookie_auth passes
|
||||||
|
if fetch_mode == "unspecified":
|
||||||
|
app_log.warning(
|
||||||
|
f"Skipping XSRF check for insecure request {handler.request.method} {handler.request.path}"
|
||||||
|
)
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
def check_xsrf_cookie(handler):
|
def check_xsrf_cookie(handler):
|
||||||
"""Check that xsrf cookie matches xsrf token in request"""
|
"""Check that xsrf cookie matches xsrf token in request"""
|
||||||
# overrides tornado's implementation
|
# overrides tornado's implementation
|
||||||
# because we changed what a correct value should be in xsrf_token
|
# because we changed what a correct value should be in xsrf_token
|
||||||
|
if not _needs_check_xsrf(handler):
|
||||||
|
# don't require XSRF for regular page views
|
||||||
|
return
|
||||||
|
|
||||||
token = (
|
token = (
|
||||||
handler.get_argument("_xsrf", None)
|
handler.get_argument("_xsrf", None)
|
||||||
|
@@ -62,6 +62,7 @@ from traitlets.config import SingletonConfigurable
|
|||||||
|
|
||||||
from .._xsrf_utils import (
|
from .._xsrf_utils import (
|
||||||
_anonymous_xsrf_id,
|
_anonymous_xsrf_id,
|
||||||
|
_needs_check_xsrf,
|
||||||
_set_xsrf_cookie,
|
_set_xsrf_cookie,
|
||||||
check_xsrf_cookie,
|
check_xsrf_cookie,
|
||||||
get_xsrf_token,
|
get_xsrf_token,
|
||||||
@@ -931,7 +932,9 @@ class HubOAuth(HubAuth):
|
|||||||
|
|
||||||
Applies JupyterHub check_xsrf_cookie if not token authenticated
|
Applies JupyterHub check_xsrf_cookie if not token authenticated
|
||||||
"""
|
"""
|
||||||
if getattr(handler, '_token_authenticated', False):
|
if getattr(handler, '_token_authenticated', False) or handler.settings.get(
|
||||||
|
"disable_check_xsrf", False
|
||||||
|
):
|
||||||
return
|
return
|
||||||
check_xsrf_cookie(handler)
|
check_xsrf_cookie(handler)
|
||||||
|
|
||||||
@@ -944,31 +947,11 @@ class HubOAuth(HubAuth):
|
|||||||
kwargs["secure"] = True
|
kwargs["secure"] = True
|
||||||
return handler.clear_cookie(cookie_name, **kwargs)
|
return handler.clear_cookie(cookie_name, **kwargs)
|
||||||
|
|
||||||
def _needs_check_xsrf(self, handler):
|
|
||||||
"""Does the given cookie-authenticated request need to check xsrf?"""
|
|
||||||
if getattr(handler, "_token_authenticated", False):
|
|
||||||
return False
|
|
||||||
|
|
||||||
fetch_mode = handler.request.headers.get("Sec-Fetch-Mode", "unspecified")
|
|
||||||
if fetch_mode in {"websocket", "no-cors"} or (
|
|
||||||
fetch_mode in {"navigate", "unspecified"}
|
|
||||||
and handler.request.method.lower() in {"get", "head", "options"}
|
|
||||||
):
|
|
||||||
# no xsrf check needed for regular page views or no-cors
|
|
||||||
# or websockets after allow_websocket_cookie_auth passes
|
|
||||||
if fetch_mode == "unspecified":
|
|
||||||
self.log.warning(
|
|
||||||
f"Skipping XSRF check for insecure request {handler.request.method} {handler.request.path}"
|
|
||||||
)
|
|
||||||
return False
|
|
||||||
else:
|
|
||||||
return True
|
|
||||||
|
|
||||||
async def _get_user_cookie(self, handler):
|
async def _get_user_cookie(self, handler):
|
||||||
# check xsrf if needed
|
# check xsrf if needed
|
||||||
token = self._get_token_cookie(handler)
|
token = self._get_token_cookie(handler)
|
||||||
session_id = self.get_session_id(handler)
|
session_id = self.get_session_id(handler)
|
||||||
if token and self._needs_check_xsrf(handler):
|
if token and _needs_check_xsrf(handler):
|
||||||
# call handler.check_xsrf_cookie instead of self.check_xsrf_cookie
|
# call handler.check_xsrf_cookie instead of self.check_xsrf_cookie
|
||||||
# to allow subclass overrides
|
# to allow subclass overrides
|
||||||
try:
|
try:
|
||||||
|
@@ -157,7 +157,7 @@ async def test_permission_error_messages(app, user, auth, expected_message):
|
|||||||
params["_xsrf"] = cookies["_xsrf"]
|
params["_xsrf"] = cookies["_xsrf"]
|
||||||
if auth == "cookie_xsrf_mismatch":
|
if auth == "cookie_xsrf_mismatch":
|
||||||
params["_xsrf"] = "somethingelse"
|
params["_xsrf"] = "somethingelse"
|
||||||
|
headers['Sec-Fetch-Mode'] = 'cors'
|
||||||
r = await async_requests.get(url, **kwargs)
|
r = await async_requests.get(url, **kwargs)
|
||||||
assert r.status_code == 403
|
assert r.status_code == 403
|
||||||
response = r.json()
|
response = r.json()
|
||||||
|
@@ -43,7 +43,7 @@ target_version = [
|
|||||||
github_url = "https://github.com/jupyterhub/jupyterhub"
|
github_url = "https://github.com/jupyterhub/jupyterhub"
|
||||||
|
|
||||||
[tool.tbump.version]
|
[tool.tbump.version]
|
||||||
current = "4.1.2"
|
current = "4.1.4"
|
||||||
|
|
||||||
# Example of a semver regexp.
|
# Example of a semver regexp.
|
||||||
# Make sure this matches current_version before
|
# Make sure this matches current_version before
|
||||||
|
Reference in New Issue
Block a user