From fe28767970c8ec62aabe493c46b53a5de1e5fac0 Mon Sep 17 00:00:00 2001 From: dalrrard <8892319+dalrrard@users.noreply.github.com> Date: Mon, 7 Jun 2021 15:43:11 -0500 Subject: [PATCH] Fixed exposed credentials in exception Under certain conditions, sensitive connection parameters are shown in tracebacks when Ansible receives an unexpected response (in my case `None`) from `set_options` in ansible-connection. This patch creates a list of sensitive connection parameter names from `ansible.constants`, pulls a list of those values in the `params` that are about to be dumped to the screen and log file, and sends the `params` and list of `sensitive_values` to the `module_utils.common.parameters.remove_values` function for processing to hide them before being exposed. --- lib/ansible/module_utils/connection.py | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/lib/ansible/module_utils/connection.py b/lib/ansible/module_utils/connection.py index a76fdb6bcc3c21..f828860f963ff0 100644 --- a/lib/ansible/module_utils/connection.py +++ b/lib/ansible/module_utils/connection.py @@ -38,10 +38,13 @@ import uuid from functools import partial +from ansible import constants as C from ansible.module_utils._text import to_bytes, to_text from ansible.module_utils.common.json import AnsibleJSONEncoder +from ansible.module_utils.common.parameters import remove_values from ansible.module_utils.six import iteritems from ansible.module_utils.six.moves import cPickle +from ansible.utils.helpers import deduplicate_list def write_to_file_descriptor(fd, obj): @@ -163,12 +166,26 @@ def _exec_jsonrpc(self, name, *args, **kwargs): try: response = json.loads(out) except ValueError: - params = [repr(arg) for arg in args] + ['{0}={1!r}'.format(k, v) for k, v in iteritems(kwargs)] + sensitive_keys = list( + C.MAGIC_VARIABLE_MAPPING["password"] + + C.MAGIC_VARIABLE_MAPPING["private_key_file"] + + C.MAGIC_VARIABLE_MAPPING["become_pass"] + ) + sensitive_values = [ + v2 + for k, v in iteritems(kwargs) + for k2, v2 in iteritems(v) + if k2 in sensitive_keys + ] + params = [repr(remove_values(arg, sensitive_values)) for arg in args] + [ + "{0}={1!r}".format(k, remove_values(v, sensitive_values)) + for k, v in iteritems(kwargs)] params = ', '.join(params) raise ConnectionError( "Unable to decode JSON from response to {0}({1}). Received '{2}'.".format(name, params, out) ) + if response['id'] != reqid: raise ConnectionError('invalid json-rpc id received') if "result_type" in response: