From 0dc1ad1e9c47aa7b04b944e88b071ea1a646ae91 Mon Sep 17 00:00:00 2001 From: gengjh Date: Tue, 9 Apr 2013 22:13:31 +0800 Subject: Replace password to "***" in the debug message Use regex pattern to replace password to "***" for both env vars and request body output Fix bug 1166697 Change-Id: I671ea25cca78b4dea1fbf2e63c89b82912279f2d --- keystone/common/wsgi.py | 57 ++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 44 insertions(+), 13 deletions(-) (limited to 'keystone') diff --git a/keystone/common/wsgi.py b/keystone/common/wsgi.py index 018041d7..4e293a13 100644 --- a/keystone/common/wsgi.py +++ b/keystone/common/wsgi.py @@ -20,6 +20,7 @@ """Utility methods for working with WSGI servers.""" +import re import socket import sys @@ -389,21 +390,23 @@ class Debug(Middleware): @webob.dec.wsgify(RequestClass=Request) def __call__(self, req): - LOG.debug('%s %s %s', ('*' * 20), 'REQUEST ENVIRON', ('*' * 20)) - for key, value in req.environ.items(): - LOG.debug('%s = %s', key, value) - LOG.debug('') - LOG.debug('%s %s %s', ('*' * 20), 'REQUEST BODY', ('*' * 20)) - for line in req.body_file: - LOG.debug(line) - LOG.debug('') + if LOG.isEnabledFor(logging.DEBUG): + LOG.debug('%s %s %s', ('*' * 20), 'REQUEST ENVIRON', ('*' * 20)) + for key, value in req.environ.items(): + LOG.debug('%s = %s', key, mask_password(value, + is_unicode=True)) + LOG.debug('') + LOG.debug('%s %s %s', ('*' * 20), 'REQUEST BODY', ('*' * 20)) + for line in req.body_file: + LOG.debug(mask_password(line)) + LOG.debug('') resp = req.get_response(self.application) - - LOG.debug('%s %s %s', ('*' * 20), 'RESPONSE HEADERS', ('*' * 20)) - for (key, value) in resp.headers.iteritems(): - LOG.debug('%s = %s', key, value) - LOG.debug('') + if LOG.isEnabledFor(logging.DEBUG): + LOG.debug('%s %s %s', ('*' * 20), 'RESPONSE HEADERS', ('*' * 20)) + for (key, value) in resp.headers.iteritems(): + LOG.debug('%s = %s', key, value) + LOG.debug('') resp.app_iter = self.print_generator(resp.app_iter) @@ -580,3 +583,31 @@ def render_exception(error): if isinstance(error, exception.AuthPluginException): body['error']['identity'] = error.authentication return render_response(status=(error.code, error.title), body=body) + + +_RE_PASS = re.compile(r'([\'"].*?password[\'"]\s*:\s*u?[\'"]).*?([\'"])', + re.DOTALL) + + +def mask_password(message, is_unicode=False, secret="***"): + """Replace password with 'secret' in message. + + :param message: The string which include security information. + :param is_unicode: Is unicode string ? + :param secret: substitution string default to "***". + :returns: The string + + For example: + >>> mask_password('"password" : "aaaaa"') + '"password" : "***"' + >>> mask_password("'original_password' : 'aaaaa'") + "'original_password' : '***'" + >>> mask_password("u'original_password' : u'aaaaa'") + "u'original_password' : u'***'" + """ + if is_unicode: + message = unicode(message) + # Match the group 1,2 and replace all others with 'secret' + secret = r"\g<1>" + secret + r"\g<2>" + result = _RE_PASS.sub(secret, message) + return result -- cgit