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

[2017.7] Ensure that tokens are hex to avoid hanging/errors in cherrypy #50202

Merged
merged 3 commits into from Oct 24, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
13 changes: 12 additions & 1 deletion salt/netapi/rest_cherrypy/app.py
Expand Up @@ -1078,6 +1078,13 @@ def exec_lowstate(self, client=None, token=None):
if cherrypy.session.get('groups'):
chunk['__current_eauth_groups'] = cherrypy.session.get('groups')

if 'token' in chunk:
# Make sure that auth token is hex
try:
int(chunk['token'], 16)
except (TypeError, ValueError):
raise cherrypy.HTTPError(401, 'Invalid token')

if client:
chunk['client'] = client

Expand Down Expand Up @@ -2078,7 +2085,11 @@ def _is_valid_token(self, auth_token):

:return bool: True if valid, False if not valid.
'''
if auth_token is None:
# Make sure that auth token is hex. If it's None, or something other
# than hex, this will raise a ValueError.
try:
int(auth_token, 16)
except (TypeError, ValueError):
return False

# First check if the given token is in our session table; if so it's a
Expand Down
66 changes: 66 additions & 0 deletions tests/integration/netapi/rest_cherrypy/test_app.py
Expand Up @@ -2,6 +2,7 @@

# Import python libs
from __future__ import absolute_import
import os
import json

# Import salt libs
Expand Down Expand Up @@ -124,6 +125,71 @@ def test_run_bad_login(self):
})
self.assertEqual(response.status, '401 Unauthorized')

def test_run_empty_token(self):
'''
Test the run URL with empty token
'''
cmd = dict(self.low, **{'token': ''})
body = urlencode(cmd)

request, response = self.request('/run', method='POST', body=body,
headers={
'content-type': 'application/x-www-form-urlencoded'
})
assert response.status == '401 Unauthorized'

def test_run_empty_token_upercase(self):
'''
Test the run URL with empty token with upercase characters
'''
cmd = dict(self.low, **{'ToKen': ''})
body = urlencode(cmd)

request, response = self.request('/run', method='POST', body=body,
headers={
'content-type': 'application/x-www-form-urlencoded'
})
assert response.status == '401 Unauthorized'

def test_run_wrong_token(self):
'''
Test the run URL with incorrect token
'''
cmd = dict(self.low, **{'token': 'bad'})
body = urlencode(cmd)

request, response = self.request('/run', method='POST', body=body,
headers={
'content-type': 'application/x-www-form-urlencoded'
})
assert response.status == '401 Unauthorized'

def test_run_pathname_token(self):
'''
Test the run URL with path that exists in token
'''
cmd = dict(self.low, **{'token': os.path.join('etc', 'passwd')})
body = urlencode(cmd)

request, response = self.request('/run', method='POST', body=body,
headers={
'content-type': 'application/x-www-form-urlencoded'
})
assert response.status == '401 Unauthorized'

def test_run_pathname_not_exists_token(self):
'''
Test the run URL with path that does not exist in token
'''
cmd = dict(self.low, **{'token': os.path.join('tmp', 'doesnotexist')})
body = urlencode(cmd)

request, response = self.request('/run', method='POST', body=body,
headers={
'content-type': 'application/x-www-form-urlencoded'
})
assert response.status == '401 Unauthorized'


class TestWebhookDisableAuth(cptc.BaseRestCherryPyTest):

Expand Down