Don't show params when there is an issue with set_option(s) (#75805)
This commit is contained in:
5
changelogs/fragments/avoid-set_options-leak.yaml
Normal file
5
changelogs/fragments/avoid-set_options-leak.yaml
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
security_fixes:
|
||||
- Do not include params in exception when a call to ``set_options`` fails.
|
||||
Additionally, block the exception that is returned from being displayed to stdout.
|
||||
(CVE-2021-3620)
|
||||
@ -99,7 +99,11 @@ class ConnectionProcess(object):
|
||||
self.play_context.private_key_file = os.path.join(self.original_path, self.play_context.private_key_file)
|
||||
self.connection = connection_loader.get(self.play_context.connection, self.play_context, '/dev/null',
|
||||
task_uuid=self._task_uuid, ansible_playbook_pid=self._ansible_playbook_pid)
|
||||
self.connection.set_options(var_options=variables)
|
||||
try:
|
||||
self.connection.set_options(var_options=variables)
|
||||
except ConnectionError as exc:
|
||||
messages.append(('debug', to_text(exc)))
|
||||
raise ConnectionError('Unable to decode JSON from response set_options. See the debug log for more information.')
|
||||
|
||||
self.connection._socket_path = self.socket_path
|
||||
self.srv.register(self.connection)
|
||||
@ -301,7 +305,11 @@ def main():
|
||||
else:
|
||||
messages.append(('vvvv', 'found existing local domain socket, using it!'))
|
||||
conn = Connection(socket_path)
|
||||
conn.set_options(var_options=variables)
|
||||
try:
|
||||
conn.set_options(var_options=variables)
|
||||
except ConnectionError as exc:
|
||||
messages.append(('debug', to_text(exc)))
|
||||
raise ConnectionError('Unable to decode JSON from response set_options. See the debug log for more information.')
|
||||
pc_data = to_text(init_data)
|
||||
try:
|
||||
conn.update_play_context(pc_data)
|
||||
|
||||
@ -163,6 +163,11 @@ class Connection(object):
|
||||
try:
|
||||
response = json.loads(out)
|
||||
except ValueError:
|
||||
# set_option(s) has sensitive info, and the details are unlikely to matter anyway
|
||||
if name.startswith("set_option"):
|
||||
raise ConnectionError(
|
||||
"Unable to decode JSON from response to {0}. Received '{1}'.".format(name, out)
|
||||
)
|
||||
params = [repr(arg) for arg in args] + ['{0}={1!r}'.format(k, v) for k, v in iteritems(kwargs)]
|
||||
params = ', '.join(params)
|
||||
raise ConnectionError(
|
||||
|
||||
22
test/units/module_utils/test_connection.py
Normal file
22
test/units/module_utils/test_connection.py
Normal file
@ -0,0 +1,22 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright: (c) 2021, Matt Martz <matt@sivel.net>
|
||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
|
||||
from __future__ import (absolute_import, division, print_function)
|
||||
__metaclass__ = type
|
||||
|
||||
from ansible.module_utils import connection
|
||||
|
||||
import pytest
|
||||
|
||||
|
||||
def test_set_options_credential_exposure():
|
||||
def send(data):
|
||||
return '{'
|
||||
|
||||
c = connection.Connection(connection.__file__)
|
||||
c.send = send
|
||||
with pytest.raises(connection.ConnectionError) as excinfo:
|
||||
c._exec_jsonrpc('set_options', become_pass='password')
|
||||
|
||||
assert 'password' not in str(excinfo.value)
|
||||
Reference in New Issue
Block a user