copy - redact 'content' from invocation in check mode (#71033) (#71068)

* sanitize copy module invocation secrets in check mode

(cherry picked from commit 991714b9d1)
pull/71153/head
Sloane Hertel 4 years ago committed by GitHub
parent 59c9a1833e
commit 6cae9a4b16
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -0,0 +1,7 @@
security_fixes:
- >
**security issue** - copy - Redact the value of the no_log 'content'
parameter in the result's invocation.module_args in check mode.
Previously when used with check mode and with '-vvv', the module
would not censor the content if a change would be made to the
destination path. (CVE-2020-14332)

@ -212,6 +212,8 @@ class ActionModule(ActionBase):
# NOTE: adding invocation arguments here needs to be kept in sync with
# any no_log specified in the argument_spec in the module.
# This is not automatic.
# NOTE: do not add to this. This should be made a generic function for action plugins.
# This should also use the same argspec as the module instead of keeping it in sync.
if 'invocation' not in result:
if self._play_context.no_log:
result['invocation'] = "CENSORED: no_log is set"
@ -221,8 +223,11 @@ class ActionModule(ActionBase):
result['invocation'] = self._task.args.copy()
result['invocation']['module_args'] = self._task.args.copy()
if isinstance(result['invocation'], dict) and 'content' in result['invocation']:
if isinstance(result['invocation'], dict):
if 'content' in result['invocation']:
result['invocation']['content'] = 'CENSORED: content is a no_log parameter'
if result['invocation'].get('module_args', {}).get('content') is not None:
result['invocation']['module_args']['content'] = 'VALUE_SPECIFIED_IN_NO_LOG_PARAMETER'
return result

@ -74,6 +74,8 @@
- import_tasks: acls.yml
when: ansible_system == 'Linux'
- import_tasks: no_log.yml
# https://github.com/ansible/ansible/issues/57618
- name: Test diff contents
copy:

@ -0,0 +1,82 @@
- block:
- set_fact:
dest: "{{ local_temp_dir }}/test_no_log"
- name: ensure playbook and dest files don't exist yet
file:
path: "{{ item }}"
state: absent
loop:
- "{{ local_temp_dir }}/test_no_log.yml"
- "{{ dest }}"
- name: create a playbook to run with command
copy:
dest: "{{local_temp_dir}}/test_no_log.yml"
content: !unsafe |
---
- hosts: localhost
gather_facts: no
tasks:
- copy:
dest: "{{ dest }}"
content: "{{ secret }}"
- name: copy the secret while using -vvv and check mode
command: "ansible-playbook {{local_temp_dir}}/test_no_log.yml -vvv -e secret=SECRET -e dest={{dest}} --check"
register: result
- assert:
that:
- "'SECRET' not in result.stdout"
- name: copy the secret while using -vvv
command: "ansible-playbook {{local_temp_dir}}/test_no_log.yml -vvv -e secret=SECRET -e dest={{dest}}"
register: result
- assert:
that:
- "'SECRET' not in result.stdout"
- name: copy the secret while using -vvv and check mode again
command: "ansible-playbook {{local_temp_dir}}/test_no_log.yml -vvv -e secret=SECRET -e dest={{dest}} --check"
register: result
- assert:
that:
- "'SECRET' not in result.stdout"
- name: copy the secret while using -vvv again
command: "ansible-playbook {{local_temp_dir}}/test_no_log.yml -vvv -e secret=SECRET -e dest={{dest}}"
register: result
- assert:
that:
- "'SECRET' not in result.stdout"
- name: copy a new secret while using -vvv and check mode
command: "ansible-playbook {{local_temp_dir}}/test_no_log.yml -vvv -e secret=NEWSECRET -e dest={{dest}} --check"
register: result
- assert:
that:
- "'NEWSECRET' not in result.stdout"
- name: copy a new secret while using -vvv
command: "ansible-playbook {{local_temp_dir}}/test_no_log.yml -vvv -e secret=NEWSECRET -e dest={{dest}}"
register: result
- assert:
that:
- "'NEWSECRET' not in result.stdout"
always:
- name: remove temp test files
file:
path: "{{ item }}"
state: absent
loop:
- "{{ local_temp_dir }}/test_no_log.yml"
- "{{ dest }}"
Loading…
Cancel
Save