# understanding fetch module's security implications

**URL:** <https://forum.ansible.com/t/understanding-fetch-modules-security-implications/19932>\
**Category:** Ansible Project\
**Created:** [December 3, 2015, 11:40pm UTC](https://forum.ansible.com/t/understanding-fetch-modules-security-implications/19932 "2015-12-03T23:40:32Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![Nusenu1](https://avatars.discourse-cdn.com/v4/letter/n/db5fbb/32.png) [@Nusenu1](https://forum.ansible.com/u/Nusenu1)\
**Post date:** [December 3, 2015, 11:40pm UTC](https://forum.ansible.com/t/understanding-fetch-modules-security-implications/19932/1 "2015-12-03T23:40:32Z")

</div>

Hi,

I consider the ansible host as trusted, the target server that is  
managed with ansible is considered less trusted (it might start attacks  
against the ansible host).

Does ansible's security design match that threat model in general?

Given the following fetch module example:

- fetch: src={{ DataDir }}/{{ item[0] }}/{{ item[1] }}  
&nbsp;&nbsp;&nbsp;&nbsp;dest={{ foo\_dir }}/{{ item[0] }}/{{ item[1] }}.untrustedremotefile  
&nbsp;&nbsp;&nbsp;&nbsp;flat=yes  
&nbsp;&nbsp;with\_nested:  
&nbsp;&nbsp;&nbsp;- "{{ ansible\_all\_ipv4\_addresses }}"  
&nbsp;&nbsp;&nbsp;- ['a', 'b']  
become: yes

I assume the target host trying to attack the ansible hosts can provide  
arbitrary strings (i.e "../../../../")  
as one of its IP addresses to trick the ansible host to write to  
arbitrary locations (flat=yes) , but is it at least safe to assume that  
the static strings defined in the playbook/role ('a', 'b' and file  
suffix '.untrustedremotefile') can not be altered by the target server  
or is the entire dest= path composed/generated remotely and transmitted  
back to the ansible host and therefore considered untrusted entirely?

If static strings can not be altered by the remote (attacking) server  
the remote server would only be able to override files named  
a/b.untrustedremotefile in arbitrary locations but not for example  
~/.ssh/authorized\_keys.

Another question that came up while writing this email:  
Is 'become: yes' in the fetch context limited to the target server or  
will ansible try to escalate its privileges on the ansible host as well  
(localhost)?

thanks!

---

<div class="post-metadata">

**Author:** ![Brian\_Coca](https://avatars.discourse-cdn.com/v4/letter/b/6de8d8/32.png) [@Brian\_Coca](https://forum.ansible.com/u/Brian_Coca)\
**Post date:** [December 5, 2015, 6:55am UTC](https://forum.ansible.com/t/understanding-fetch-modules-security-implications/19932/2 "2015-12-05T06:55:58Z")

</div>

- All templating (variable substitution) is done on the 'controller',  
it makes no sense to send that data, plus the template to the targets  
and then have to install jinja2 to run it, get it back and then update  
the task, copy the updated module and run it remotely ...

- the fact variables (what ansible\_all\_ipv4\_addresses is) are  
sanitized against template injection but not verified against  
directories, most variables can legitimately return such structures.  
The attacker would have to know your exact playbook to do this, as you  
already state, since they cannot update the ['a', 'b'] list, it  
minimizes the issue.

- become executes privilege escalation on the target, the current  
ansible process does not elevate privilege when the target is another  
server, even when targeting localhost, only the forked task will get  
the changed privilege, as intended.

Ansible mostly works using by ssh and sudo like you would in the  
command line, you can gather data from other machines and use it, but  
only send the minimal data to achieve a task.

---

<div class="post-metadata">

**Author:** ![Nusenu1](https://avatars.discourse-cdn.com/v4/letter/n/db5fbb/32.png) [@Nusenu1](https://forum.ansible.com/u/Nusenu1)\
**Post date:** [December 9, 2015, 8:45pm UTC](https://forum.ansible.com/t/understanding-fetch-modules-security-implications/19932/3 "2015-12-09T20:45:54Z")

</div>

thanks for your answer!

> - the fact variables (what ansible\_all\_ipv4\_addresses is) are  
> sanitized against template injection but not verified against  
> directories, most variables can legitimately return such structures.  
> The attacker would have to know your exact playbook to do this, as you  
> already state, since they cannot update the ['a', 'b'] list, it  
> minimizes the issue.

Would it make sense to add a check to ansible that verifies elements of  
ansible\_all\_ipv4\_addresses against an IP regex? (If I understood you  
correctly that is not the case yet.)

It doesn't help in my specific case since an attacker will still be able  
to override files it should not but maybe as a general precaution it  
doesn't hurt I guess (I'll have to remove 'flat=yes' in my case.)

---

<div class="post-metadata">

**Author:** ![Nusenu1](https://avatars.discourse-cdn.com/v4/letter/n/db5fbb/32.png) [@Nusenu1](https://forum.ansible.com/u/Nusenu1)\
**Post date:** [February 6, 2016, 1:16pm UTC](https://forum.ansible.com/t/understanding-fetch-modules-security-implications/19932/4 "2016-02-06T13:16:32Z")

</div>

I tried to address this security problem (which turned out to be more  
severe then I initially thought, because it probably allowed a relay to  
steal keys) by prefixing the fact with a var that can not be manipulated  
by the target server ( inventory\_hostname ).

[https://github.com/nusenu/ansible-relayor/commit/d0a969fabe731e8f20dad074ec772ec12faaab7b#diff-0ab2a3945984f21ca36ce37d625d716cL147](https://github.com/nusenu/ansible-relayor/commit/d0a969fabe731e8f20dad074ec772ec12faaab7b#diff-0ab2a3945984f21ca36ce37d625d716cL147)

---

<div class="post-metadata">

**Author:** ![Brian\_Coca](https://avatars.discourse-cdn.com/v4/letter/b/6de8d8/32.png) [@Brian\_Coca](https://forum.ansible.com/u/Brian_Coca)\
**Post date:** [February 6, 2016, 4:23pm UTC](https://forum.ansible.com/t/understanding-fetch-modules-security-implications/19932/5 "2016-02-06T16:23:03Z")

</div>

Prefixing with trusted vars is still open to directory traversal. In  
most cases you can setup your systems so the variable data is set by  
the 'master' always and not derived from the target, which avoids this  
issue altogether.

This is only a problem if you rely on untrusted data to access  
secrets, there is not much Ansible can do in that case. I would advise  
creating assert/fail tasks to validate the data before using it.

---

<div class="post-metadata">

**Author:** ![Nusenu1](https://avatars.discourse-cdn.com/v4/letter/n/db5fbb/32.png) [@Nusenu1](https://forum.ansible.com/u/Nusenu1)\
**Post date:** [February 6, 2016, 5:50pm UTC](https://forum.ansible.com/t/understanding-fetch-modules-security-implications/19932/6 "2016-02-06T17:50:10Z")

</div>

Brian Coca:

> Prefixing with trusted vars is still open to directory traversal.

oh that is true, thanks for pointing that out!  
(example: 1.1.1.1/../foo-2.2.2.2)

> In  
> most cases you can setup your systems so the variable data is set by  
> the 'master' always and not derived from the target, which avoids this  
> issue altogether.

I agree, but in my case I use the IP address as unique identifier and  
only the target knows its IPs.

> This is only a problem if you rely on untrusted data to access  
> secrets, there is not much Ansible can do in that case. I would advise  
> creating assert/fail tasks to validate the data before using it.

I opened a github issue to validate all elements of  
ansible\_all\_ipv4\_addresses  
by default against an IP address regex:

[https://github.com/ansible/ansible/issues/14350](https://github.com/ansible/ansible/issues/14350)

---

<div class="post-metadata">

**Author:** ![Nusenu1](https://avatars.discourse-cdn.com/v4/letter/n/db5fbb/32.png) [@Nusenu1](https://forum.ansible.com/u/Nusenu1)\
**Post date:** [February 6, 2016, 7:52pm UTC](https://forum.ansible.com/t/understanding-fetch-modules-security-implications/19932/7 "2016-02-06T19:52:26Z")

</div>

Brian Coca:

> Prefixing with trusted vars is still open to directory traversal.

I hope the ipv4('address') filter method is safe?

[https://github.com/nusenu/ansible-relayor/commit/d2c2108a8850241369aa8867faf4ac53246171d5](https://github.com/nusenu/ansible-relayor/commit/d2c2108a8850241369aa8867faf4ac53246171d5)
