Merge "Avoid logging sensitive info in http requests."

This commit is contained in:
Jenkins 2016-02-29 22:06:26 +00:00 committed by Gerrit Code Review
commit e4692518b4
3 changed files with 57 additions and 2 deletions

View File

@ -21,6 +21,7 @@ OpenStack Client interface. Handles the REST calls and responses.
from __future__ import print_function
import glob
import hashlib
import imp
import itertools
import logging
@ -39,6 +40,7 @@ from cinderclient import exceptions
import cinderclient.extension
from cinderclient.openstack.common import importutils
from cinderclient.openstack.common.gettextutils import _
from oslo_utils import encodeutils
from oslo_utils import strutils
osprofiler_web = importutils.try_import("osprofiler.web")
@ -145,6 +147,7 @@ class SessionClient(adapter.LegacyJsonAdapter):
class HTTPClient(object):
SENSITIVE_HEADERS = ('X-Auth-Token', 'X-Subject-Token',)
USER_AGENT = 'python-cinderclient'
def __init__(self, user, password, projectid, auth_url=None,
@ -198,6 +201,16 @@ class HTTPClient(object):
self._logger = logging.getLogger(__name__)
def _safe_header(self, name, value):
if name in HTTPClient.SENSITIVE_HEADERS:
encoded = value.encode('utf-8')
hashed = hashlib.sha1(encoded)
digested = hashed.hexdigest()
return encodeutils.safe_decode(name), "{SHA1}%s" % digested
else:
return (encodeutils.safe_decode(name),
encodeutils.safe_decode(value))
def http_log_req(self, args, kwargs):
if not self.http_log_debug:
return
@ -210,7 +223,8 @@ class HTTPClient(object):
string_parts.append(' %s' % element)
for element in kwargs['headers']:
header = ' -H "%s: %s"' % (element, kwargs['headers'][element])
header = ("-H '%s: %s'" %
self._safe_header(element, kwargs['headers'][element]))
string_parts.append(header)
if 'data' in kwargs:

View File

@ -33,13 +33,16 @@ try:
except ImportError:
import json
import hashlib
import requests
from cinderclient.openstack.common.apiclient import exceptions
from cinderclient.openstack.common import importutils
from oslo_utils import encodeutils
_logger = logging.getLogger(__name__)
SENSITIVE_HEADERS = ('X-Auth-Token', 'X-Subject-Token',)
class HTTPClient(object):
@ -97,6 +100,16 @@ class HTTPClient(object):
self.cached_token = None
def _safe_header(self, name, value):
if name in SENSITIVE_HEADERS:
encoded = value.encode('utf-8')
hashed = hashlib.sha1(encoded)
digested = hashed.hexdigest()
return encodeutils.safe_decode(name), "{SHA1}%s" % digested
else:
return (encodeutils.safe_decode(name),
encodeutils.safe_decode(value))
def _http_log_req(self, method, url, kwargs):
if not self.debug:
return
@ -108,7 +121,8 @@ class HTTPClient(object):
]
for element in kwargs['headers']:
header = "-H '%s: %s'" % (element, kwargs['headers'][element])
header = ("-H '%s: %s'" %
self._safe_header(element, kwargs['headers'][element]))
string_parts.append(header)
_logger.debug("REQ: %s" % " ".join(string_parts))

View File

@ -186,3 +186,30 @@ class ClientTest(utils.TestCase):
# AuthorizationFailure exception, check exceptions.from_response
# is not getting called.
self.assertFalse(mock_from_resp.called)
class ClientTestSensitiveInfo(utils.TestCase):
def test_req_does_not_log_sensitive_info(self):
self.logger = self.useFixture(
fixtures.FakeLogger(
format="%(message)s",
level=logging.DEBUG,
nuke_handlers=True
)
)
secret_auth_token = "MY_SECRET_AUTH_TOKEN"
kwargs = {
'headers': {"X-Auth-Token": secret_auth_token},
'data': ('{"auth": {"tenantName": "fakeService",'
' "passwordCredentials": {"username": "fakeUser",'
' "password": "fakePassword"}}}')
}
cs = cinderclient.client.HTTPClient("user", None, None,
"http://127.0.0.1:5000")
cs.http_log_debug = True
cs.http_log_req('PUT', kwargs)
output = self.logger.output.split('\n')
self.assertNotIn(secret_auth_token, output[1])