# Remote Code Execution in Ansible dynamic inventory plugins

**URL:** <https://forum.ansible.com/t/remote-code-execution-in-ansible-dynamic-inventory-plugins/4332>\
**Category:** Get Help\
**Created:** [March 12, 2024, 9:48am UTC](https://forum.ansible.com/t/remote-code-execution-in-ansible-dynamic-inventory-plugins/4332 "2024-03-12T09:48:41Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![chris](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/chris/32/293_2.png) [@chris](https://forum.ansible.com/u/chris)\
**Post date:** [March 12, 2024, 9:48am UTC](https://forum.ansible.com/t/remote-code-execution-in-ansible-dynamic-inventory-plugins/4332/1 "2024-03-12T09:48:41Z")

</div>

I was wondering if this was raised at a GitHub issue, if it was I’d be interested in reading the discussion that followed:

> **[Remote Code Execution in Ansible dynamic inventory plugins](https://www.die-welt.net/2024/03/remote-code-execution-in-ansible-dynamic-inventory-plugins/)**
>
> I had reported this to Ansible a year ago (2023-02-23), but it seems this is considered expected behavior, so I am posting it here now.
> TL;DR
> Don't ever consume any data you got from an inventory if t

Does the same thing apply to scripts in the `/etc/ansible/facts.d` directory?

---

<div class="post-metadata">

**Author:** ![jpmens](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/jpmens/32/5543_2.png) [@jpmens](https://forum.ansible.com/u/jpmens)\
**Post date:** [March 12, 2024, 11:56am UTC](https://forum.ansible.com/t/remote-code-execution-in-ansible-dynamic-inventory-plugins/4332/2 "2024-03-12T11:56:51Z")

</div>

It doesn’t appear to:

```console
$ cat /etc/ansible/facts.d/j2.fact
#!/bin/sh

echo "\"{{ lookup('pipe', 'touch /tmp/hacked' ) }}\""

$ ssh node /etc/ansible/facts.d/j2.fact | jq .
"{{ lookup('pipe', 'touch /tmp/hacked' ) }}"

```

```yaml
- hosts: node
  gather_facts: true
  tasks:
   - copy: content="{{ ansible_local.j2 }}" dest=/tmp/bla

```

```console
$ ssh node cat /tmp/bla
{{ lookup('pipe', 'touch /tmp/hacked' ) }}

$ ls -l /tmp/hac*
ls: cannot access '/tmp/hac*': No such file or directory

```

---

<div class="post-metadata">

**Author:** ![felixfontein](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/felixfontein/32/7530_2.png) [@felixfontein](https://forum.ansible.com/u/felixfontein)\
**Post date:** [March 12, 2024, 12:48pm UTC](https://forum.ansible.com/t/remote-code-execution-in-ansible-dynamic-inventory-plugins/4332/3 "2024-03-12T12:48:18Z")

</div>

My guess is that the original discussion happened outside GitHub. I can kind of understand why this doesn’t count as a vulnerability in ansible-core, but I would definitely consider it a vulnerability in almost all inventory plugins.

IMO the problem is that the API makes the common thing (set something that should NOT be interpreted as a template) hard (you basically need to wrap strings as unsafe yourself), and something dangerous easy. Unfortunately fixing the API isn’t trivial (you don’t want to break valid use-cases, and if you add new functions they won’t work with older ansible-core releases).

---

<div class="post-metadata">

**Author:** ![felixfontein](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/felixfontein/32/7530_2.png) [@felixfontein](https://forum.ansible.com/u/felixfontein)\
**Post date:** [March 13, 2024, 8:02pm UTC](https://forum.ansible.com/t/remote-code-execution-in-ansible-dynamic-inventory-plugins/4332/4 "2024-03-13T20:02:28Z")

</div>

One interesting find: if you make the value of `ansible_connection` unsafe, some older versions of ansible-core will crash, at least when using the `raw` module. (Found while working on [Prevent RCE via inventory plugins by felixfontein · Pull Request #815 · ansible-collections/community.docker · GitHub](https://github.com/ansible-collections/community.docker/pull/815))

---

<div class="post-metadata">

**Author:** ![sivel](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/sivel/32/1198_2.png) [@sivel](https://forum.ansible.com/u/sivel)\
**Post date:** [March 13, 2024, 8:50pm UTC](https://forum.ansible.com/t/remote-code-execution-in-ansible-dynamic-inventory-plugins/4332/5 "2024-03-13T20:50:24Z")

</div>

The unsafe plugin name issue was recently discovered with the unsafe persistence fixes: [plugin names derived from unsafe sources result in `ValueError: unmarshallable object` · Issue #82708 · ansible/ansible · GitHub](https://github.com/ansible/ansible/issues/82708)

A fix has been merged to the stable-2.16 branch, but no releases have been cut yet. The rc1 releases for next week will include the fix.
