mirror of
https://github.com/jupyterhub/jupyterhub.git
synced 2025-10-16 14:33:00 +00:00
Merge pull request #3575 from VaishnaviHire/add_content_type
Validate Content-Type Header for api POST requests
This commit is contained in:
@@ -78,14 +78,39 @@ class APIHandler(BaseHandler):
|
||||
return False
|
||||
return True
|
||||
|
||||
def check_post_content_type(self):
|
||||
"""Check request content-type, e.g. for cross-site POST requests
|
||||
|
||||
Cross-site POST via form will include content-type
|
||||
"""
|
||||
content_type = self.request.headers.get("Content-Type")
|
||||
if not content_type:
|
||||
# not specified, e.g. from a script
|
||||
return True
|
||||
|
||||
# parse content type for application/json
|
||||
fields = content_type.lower().split(";")
|
||||
if not any(f.lstrip().startswith("application/json") for f in fields):
|
||||
self.log.warning(f"Not allowing POST with content-type: {content_type}")
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
def get_current_user_cookie(self):
|
||||
"""Override get_user_cookie to check Referer header"""
|
||||
"""Extend get_user_cookie to add checks for CORS"""
|
||||
cookie_user = super().get_current_user_cookie()
|
||||
# check referer only if there is a cookie user,
|
||||
# CORS checks for cookie-authentication
|
||||
# check these only if there is a cookie user,
|
||||
# avoiding misleading "Blocking Cross Origin" messages
|
||||
# when there's no cookie set anyway.
|
||||
if cookie_user and not self.check_referer():
|
||||
return None
|
||||
if cookie_user:
|
||||
if not self.check_referer():
|
||||
return None
|
||||
if (
|
||||
self.request.method.upper() == 'POST'
|
||||
and not self.check_post_content_type()
|
||||
):
|
||||
return None
|
||||
return cookie_user
|
||||
|
||||
def get_json_body(self):
|
||||
|
@@ -65,7 +65,7 @@ async def test_auth_api(app):
|
||||
assert r.status_code == 403
|
||||
|
||||
|
||||
async def test_referer_check(app):
|
||||
async def test_cors_checks(app):
|
||||
url = ujoin(public_host(app), app.hub.base_url)
|
||||
host = urlparse(url).netloc
|
||||
# add admin user
|
||||
@@ -110,6 +110,32 @@ async def test_referer_check(app):
|
||||
)
|
||||
assert r.status_code == 200
|
||||
|
||||
r = await api_request(
|
||||
app,
|
||||
'users',
|
||||
method='post',
|
||||
data='{}',
|
||||
headers={
|
||||
"Authorization": "",
|
||||
"Content-Type": "text/plain",
|
||||
},
|
||||
cookies=cookies,
|
||||
)
|
||||
assert r.status_code == 403
|
||||
|
||||
r = await api_request(
|
||||
app,
|
||||
'users',
|
||||
method='post',
|
||||
data='{}',
|
||||
headers={
|
||||
"Authorization": "",
|
||||
"Content-Type": "application/json; charset=UTF-8",
|
||||
},
|
||||
cookies=cookies,
|
||||
)
|
||||
assert r.status_code == 400 # accepted, but invalid
|
||||
|
||||
|
||||
# --------------
|
||||
# User API tests
|
||||
|
Reference in New Issue
Block a user