Skip to content

Commit

Permalink
restore task arg splatting (ansible#43798)
Browse files Browse the repository at this point in the history
* restore task arg splatting

* reverts ansible#41804
* supersedes ansible#41295
* fixes ansible#42192
* after lots of discussion amongst the core team, we decided to preserve this feature, clarify the runtime warnings/docs, and prioritize a path toward fixing the underlying behavior that causes this feature to be insecure (un-namespaced facts).

* update faq text

note that warning is disabled when inject_facts_as_vars is

* wordsmithing FAQ entry
  • Loading branch information
nitzmahone authored Aug 14, 2018
1 parent 8a52f2f commit 6b81c36
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 2 deletions.
34 changes: 33 additions & 1 deletion docs/docsite/rst/reference_appendices/faq.rst
Original file line number Diff line number Diff line change
Expand Up @@ -446,7 +446,7 @@ In OpenBSD, a similar option is available in the base system called encrypt(1):
encrypt
.. _commercial_support:
.. _dot_or_array_notation:

Ansible supports dot notation and array notation for variables. Which notation should I use?
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Expand All @@ -464,6 +464,38 @@ safer to use the array notation for variables.
Also array notation allows for dynamic variable composition, see dynamic_variables_.


.. _argsplat_unsafe:

When is it unsafe to bulk-set task arguments from a variable?
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++


You can set all of a task's arguments from a dictionary-typed variable. This
technique can be useful in some dynamic execution scenarios. However, it
introduces a security risk. We do not recommend it, so Ansible issues a
warning when you do something like this::

#...
vars:
usermod_args:
name: testuser
state: present
update_password: always
tasks:
- user: '{{ usermod_args }}'

This particular example is safe. However, constructing tasks like this is
risky because the parameters and values passed to ``usermod_args`` could
be overwritten by malicious values in the ``host facts`` on a compromised
target machine. To mitigate this risk:

* set bulk variables at a level of precedence greater than ``host facts`` in the order of precedence found in :ref:`ansible_variable_precedence` (the example above is safe because play vars take precedence over facts)
* disable the :ref:`inject_facts_as_vars` configuration setting to prevent fact values from colliding with variables (this will also disable the original warning)


.. _commercial_support:

Can I get training on Ansible?
++++++++++++++++++++++++++++++

Expand Down
6 changes: 5 additions & 1 deletion lib/ansible/executor/task_executor.py
Original file line number Diff line number Diff line change
Expand Up @@ -519,7 +519,11 @@ def _execute(self, variables=None):
if '_variable_params' in self._task.args:
variable_params = self._task.args.pop('_variable_params')
if isinstance(variable_params, dict):
raise AnsibleError("Using a variable for a task's 'args' is not allowed as it is unsafe, facts can come from untrusted sources.")
if C.INJECT_FACTS_AS_VARS:
display.warning("Using a variable for a task's 'args' is unsafe in some situations "
"(see https://docs.ansible.com/ansible/devel/reference_appendices/faq.html#argsplat-unsafe)")
variable_params.update(self._task.args)
self._task.args = variable_params

# get the connection and the handler for this execution
if (not self._connection or
Expand Down

0 comments on commit 6b81c36

Please sign in to comment.