diff options
author | Matt Riedemann <mriedem@us.ibm.com> | 2015-08-31 12:32:25 -0700 |
---|---|---|
committer | Matt Riedemann <mriedem@us.ibm.com> | 2015-08-31 12:49:34 -0700 |
commit | 3e26ff824801d5084791a52980021784e794e35f (patch) | |
tree | bbe9bd5e7f6852c6a4894a74477aeba1d80a8245 | |
parent | ee6d64a8fb96756abd4d85aa50f7842104602328 (diff) | |
download | python-keystoneclient-3e26ff824801d5084791a52980021784e794e35f.tar.gz |
Mask passwords when logging the HTTP response
We should sanitize the response body before logging to make sure we
aren't leaking through credentials like in the case of the response from
the os-initialize_connection volume API.
Closes-Bug: #1490693
Change-Id: Ifd95d3fb624b4636fb72cc11762af62e00a026a0
-rw-r--r-- | keystoneclient/session.py | 4 | ||||
-rw-r--r-- | keystoneclient/tests/unit/test_session.py | 29 |
2 files changed, 32 insertions, 1 deletions
diff --git a/keystoneclient/session.py b/keystoneclient/session.py index 8ac5de6..bd6e0eb 100644 --- a/keystoneclient/session.py +++ b/keystoneclient/session.py @@ -23,6 +23,7 @@ from debtcollector import removals from oslo_config import cfg from oslo_serialization import jsonutils from oslo_utils import importutils +from oslo_utils import strutils import requests import six from six.moves import urllib @@ -206,7 +207,8 @@ class Session(object): for header in six.iteritems(response.headers): string_parts.append('%s: %s' % self._process_header(header)) if text: - string_parts.append('\nRESP BODY: %s\n' % text) + string_parts.append('\nRESP BODY: %s\n' % + strutils.mask_password(text)) logger.debug(' '.join(string_parts)) diff --git a/keystoneclient/tests/unit/test_session.py b/keystoneclient/tests/unit/test_session.py index ee76337..f7384cd 100644 --- a/keystoneclient/tests/unit/test_session.py +++ b/keystoneclient/tests/unit/test_session.py @@ -250,6 +250,35 @@ class SessionTests(utils.TestCase): session.get, self.TEST_URL) + def test_mask_password_in_http_log_response(self): + session = client_session.Session() + + def fake_debug(msg): + self.assertNotIn('verybadpass', msg) + + logger = mock.Mock(isEnabledFor=mock.Mock(return_value=True)) + logger.debug = mock.Mock(side_effect=fake_debug) + body = { + "connection_info": { + "driver_volume_type": "iscsi", + "data": { + "auth_password": "verybadpass", + "target_discovered": False, + "encrypted": False, + "qos_specs": None, + "target_iqn": ("iqn.2010-10.org.openstack:volume-" + "744d2085-8e78-40a5-8659-ef3cffb2480e"), + "target_portal": "172.99.69.228:3260", + "volume_id": "744d2085-8e78-40a5-8659-ef3cffb2480e", + "target_lun": 1, + "access_mode": "rw", + "auth_username": "verybadusername", + "auth_method": "CHAP"}}} + body_json = jsonutils.dumps(body) + response = mock.Mock(text=body_json, status_code=200, headers={}) + session._http_log_response(response, logger) + self.assertEqual(1, logger.debug.call_count) + class RedirectTests(utils.TestCase): |