From 3e26ff824801d5084791a52980021784e794e35f Mon Sep 17 00:00:00 2001 From: Matt Riedemann Date: Mon, 31 Aug 2015 12:32:25 -0700 Subject: [PATCH] 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 --- keystoneclient/session.py | 4 +++- keystoneclient/tests/unit/test_session.py | 29 +++++++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/keystoneclient/session.py b/keystoneclient/session.py index 8ac5de6d0..bd6e0eb04 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 ee76337d8..f7384cdb4 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):