Merge pull request #3575 from VaishnaviHire/add_content_type

Validate Content-Type Header for api POST requests
This commit is contained in:
Min RK
2021-09-01 10:16:39 +02:00
committed by GitHub
2 changed files with 56 additions and 5 deletions

View File

@@ -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):

View File

@@ -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