Don't return the sensitive information to user

We return back the sensitive information to user
when some exceptions happened, for example,
when DBError happened, we return the whole sql
statement to user, it's not safe.
This patch changes to return the message if the
exception is the HeatException, otherwise the message
won't be revealed to user.

Change-Id: I6e01b1003a39106274e79c3b413917a30b5651b6
Closes-Bug: #1708122
This commit is contained in:
huangtianhua 2017-08-03 11:56:11 +08:00
parent 78a48ad4c4
commit 8cdfc3b293
4 changed files with 19 additions and 12 deletions

View File

@ -319,20 +319,22 @@ def map_remote_error(ex):
request_limit_exceeded = ('RequestLimitExceeded')
ex_type = reflection.get_class_name(ex, fully_qualified=False)
if ex_type.endswith('_Remote'):
ex_type = ex_type[:-len('_Remote')]
safe = getattr(ex, 'safe', False)
detail = six.text_type(ex) if safe else None
if ex_type in inval_param_errors:
return HeatInvalidParameterValueError(detail=six.text_type(ex))
return HeatInvalidParameterValueError(detail=detail)
elif ex_type in denied_errors:
return HeatAccessDeniedError(detail=six.text_type(ex))
return HeatAccessDeniedError(detail=detail)
elif ex_type in already_exists_errors:
return AlreadyExistsError(detail=six.text_type(ex))
return AlreadyExistsError(detail=detail)
elif ex_type in invalid_action_errors:
return HeatActionInProgressError(detail=six.text_type(ex))
return HeatActionInProgressError(detail=detail)
elif ex_type in request_limit_exceeded:
return HeatRequestLimitExceeded(detail=six.text_type(ex))
return HeatRequestLimitExceeded(detail=detail)
else:
# Map everything else to internal server error for now
return HeatInternalFailureError(detail=six.text_type(ex))
return HeatInternalFailureError(detail=detail)

View File

@ -110,6 +110,8 @@ class FaultWrapper(wsgi.Middleware):
trace = None
traceback_marker = 'Traceback (most recent call last)'
webob_exc = None
safe = getattr(ex, 'safe', False)
if isinstance(ex, exception.HTTPExceptionDisguise):
# An HTTP exception was disguised so it could make it here
# let's remove the disguise and set the original HTTP exception
@ -151,11 +153,12 @@ class FaultWrapper(wsgi.Middleware):
'title': webob_exc.title,
'explanation': webob_exc.explanation,
'error': {
'message': message,
'type': ex_type,
'traceback': trace,
}
}
if safe:
error['error']['message'] = message
return error

View File

@ -55,6 +55,8 @@ class HeatException(Exception):
# YYY - Specific error code for a given exception.
error_code = None
safe = True
def __init__(self, **kwargs):
self.kwargs = kwargs
@ -448,6 +450,8 @@ class HTTPExceptionDisguise(Exception):
They can be handled by the webob fault application in the wsgi pipeline.
"""
safe = True
def __init__(self, exception):
self.exc = exception
self.tb = sys.exc_info()[2]

View File

@ -144,8 +144,7 @@ class FaultMiddlewareTest(common.HeatTestCase):
wrapper = fault.FaultWrapper(None)
msg = wrapper._error(remote_error)
expected = {'code': 500,
'error': {'message': msg['error']['message'],
'traceback': None,
'error': {'traceback': None,
'type': 'RemoteError'},
'explanation': msg['explanation'],
'title': 'Internal Server Error'}
@ -211,8 +210,7 @@ class FaultMiddlewareTest(common.HeatTestCase):
msg = wrapper._error(NotMappedException('A message'))
expected = {'code': 500,
'error': {'message': u'A message',
'traceback': None,
'error': {'traceback': None,
'type': 'NotMappedException'},
'explanation': ('The server has either erred or is '
'incapable of performing the requested '