diff --git a/releasenotes/notes/fix-credential-logging-98089c897d801355.yaml b/releasenotes/notes/fix-credential-logging-98089c897d801355.yaml new file mode 100644 index 0000000000..e06e2e2774 --- /dev/null +++ b/releasenotes/notes/fix-credential-logging-98089c897d801355.yaml @@ -0,0 +1,6 @@ +--- +security: + - | + Recently we moved the logging of API request in rest_client's + raw_request which end up logging the credentials also from + Token client request. This issue has been fixed now. diff --git a/tempest/lib/common/rest_client.py b/tempest/lib/common/rest_client.py index 6cc0561a28..431a0a01e5 100644 --- a/tempest/lib/common/rest_client.py +++ b/tempest/lib/common/rest_client.py @@ -556,7 +556,8 @@ class RestClient(object): return resp, resp_body - def raw_request(self, url, method, headers=None, body=None, chunked=False): + def raw_request(self, url, method, headers=None, body=None, chunked=False, + log_req_body=None): """Send a raw HTTP request without the keystone catalog or auth This method sends a HTTP request in the same manner as the request() @@ -572,6 +573,11 @@ class RestClient(object): explicitly requires no headers use an empty dict. :param str body: Body to send with the request :param bool chunked: sends the body with chunked encoding + :param str log_req_body: Whether to log the request body or not. + It is default to None which means request + body is safe to log otherwise pass any string + you want to log in place of request body. + For example: '' :rtype: tuple :return: a tuple with the first entry containing the response headers and the second the response body @@ -585,8 +591,9 @@ class RestClient(object): url, method, headers=headers, body=body, chunked=chunked) end = time.time() + req_body = body if log_req_body is None else log_req_body self._log_request(method, url, resp, secs=(end - start), - req_headers=headers, req_body=body, + req_headers=headers, req_body=req_body, resp_body=resp_body) return resp, resp_body diff --git a/tempest/lib/services/identity/v2/token_client.py b/tempest/lib/services/identity/v2/token_client.py index 458c862ad6..9f10f58361 100644 --- a/tempest/lib/services/identity/v2/token_client.py +++ b/tempest/lib/services/identity/v2/token_client.py @@ -105,9 +105,8 @@ class TokenClient(rest_client.RestClient): headers = self.get_headers(accept_type="json") resp, resp_body = self.raw_request(url, method, - headers=headers, body=body) - self._log_request(method, url, resp, req_headers=headers, - req_body='', resp_body=resp_body) + headers=headers, body=body, + log_req_body='') if resp.status in [401, 403]: resp_body = json.loads(resp_body) diff --git a/tempest/lib/services/identity/v3/token_client.py b/tempest/lib/services/identity/v3/token_client.py index d591f03b42..69562977ce 100644 --- a/tempest/lib/services/identity/v3/token_client.py +++ b/tempest/lib/services/identity/v3/token_client.py @@ -160,10 +160,8 @@ class V3TokenClient(rest_client.RestClient): headers = self.get_headers(accept_type="json") resp, resp_body = self.raw_request(url, method, - headers=headers, body=body) - self._log_request(method, url, resp, req_headers=headers, - req_body='', resp_body=resp_body) - + headers=headers, body=body, + log_req_body='') if resp.status in [401, 403]: resp_body = json.loads(resp_body) raise exceptions.Unauthorized(resp_body['error']['message']) diff --git a/tempest/tests/lib/fake_identity.py b/tempest/tests/lib/fake_identity.py index 8bae34f88f..9d7b0fd064 100644 --- a/tempest/tests/lib/fake_identity.py +++ b/tempest/tests/lib/fake_identity.py @@ -192,7 +192,7 @@ ALT_IDENTITY_V3 = IDENTITY_V3_RESPONSE def _fake_v3_response(self, uri, method="GET", body=None, headers=None, - redirections=5, connection_type=None): + redirections=5, connection_type=None, log_req_body=None): fake_headers = { "x-subject-token": TOKEN } @@ -202,7 +202,7 @@ def _fake_v3_response(self, uri, method="GET", body=None, headers=None, def _fake_v3_response_domain_scope(self, uri, method="GET", body=None, headers=None, redirections=5, - connection_type=None): + connection_type=None, log_req_body=None): fake_headers = { "status": "201", "x-subject-token": TOKEN @@ -213,7 +213,7 @@ def _fake_v3_response_domain_scope(self, uri, method="GET", body=None, def _fake_v3_response_no_scope(self, uri, method="GET", body=None, headers=None, redirections=5, - connection_type=None): + connection_type=None, log_req_body=None): fake_headers = { "status": "201", "x-subject-token": TOKEN @@ -223,7 +223,7 @@ def _fake_v3_response_no_scope(self, uri, method="GET", body=None, def _fake_v2_response(self, uri, method="GET", body=None, headers=None, - redirections=5, connection_type=None): + redirections=5, connection_type=None, log_req_body=None): return (fake_http.fake_http_response({}, status=200), json.dumps(IDENTITY_V2_RESPONSE)) diff --git a/tempest/tests/lib/services/identity/v2/test_token_client.py b/tempest/tests/lib/services/identity/v2/test_token_client.py index a592ada4e6..5b4e210d4b 100644 --- a/tempest/tests/lib/services/identity/v2/test_token_client.py +++ b/tempest/tests/lib/services/identity/v2/test_token_client.py @@ -86,6 +86,9 @@ class TestTokenClientV2(base.TestCase): with mock.patch.object(token_client_v2, 'raw_request') as mock_raw_r: mock_raw_r.return_value = response, body resp, body = token_client_v2.request('GET', 'fake_uri') + mock_raw_r.assert_called_once_with('fake_uri', 'GET', + headers=mock.ANY, body=None, + log_req_body='') self.assertIsInstance(body, dict) def test_request_with_bytes_body(self): diff --git a/tempest/tests/lib/services/identity/v3/test_token_client.py b/tempest/tests/lib/services/identity/v3/test_token_client.py index a9c58dfe97..656e10a30e 100644 --- a/tempest/tests/lib/services/identity/v3/test_token_client.py +++ b/tempest/tests/lib/services/identity/v3/test_token_client.py @@ -136,6 +136,9 @@ class TestTokenClientV3(base.TestCase): mock_raw_r.return_value = ( fake_identity._fake_v3_response(None, None)) resp, body = token_client_v3.request('GET', 'fake_uri') + mock_raw_r.assert_called_once_with('fake_uri', 'GET', + headers=mock.ANY, body=None, + log_req_body='') self.assertIsInstance(body, dict)