# How to skip optional arguments to a module after new security patch?

**URL:** <https://forum.ansible.com/t/how-to-skip-optional-arguments-to-a-module-after-new-security-patch/15796>\
**Category:** Ansible Project\
**Created:** [July 29, 2014, 12:30am UTC](https://forum.ansible.com/t/how-to-skip-optional-arguments-to-a-module-after-new-security-patch/15796 "2014-07-29T00:30:42Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![Victor\_Lin](https://avatars.discourse-cdn.com/v4/letter/v/87869e/32.png) [@Victor\_Lin](https://forum.ansible.com/u/Victor_Lin)\
**Post date:** [July 29, 2014, 12:30am UTC](https://forum.ansible.com/t/how-to-skip-optional-arguments-to-a-module-after-new-security-patch/15796/1 "2014-07-29T00:30:42Z")

</div>

I noticed that since the new ansible with security patched is released, many our roles and playbooks are broken. For example, our role depends on this, it is also broken

[https://github.com/Ansibles/generic-users/blob/master/tasks/main.yml#L3-L5](https://github.com/Ansibles/generic-users/blob/master/tasks/main.yml#L3-L5)

since it uses if else statements to generate optional arguments like gid. In the latest version of Ansible, it adds new arguments, so it fails to pass security check, an error like

`A variable inserted a new parameter into the module args. Be sure to quote variables if they contain equal signs (for example: "{{var}}").`

is raised.

I tried to modify the way arguments are passed by leveraging default filter

`

- name: generic-users | Make sure all groups are present  
group: \>  
name=“{{ item.name }}”  
system=“{{ item.system|default(‘no’) }}”  
gid=“{{ item.gid|default(None) }}”  
state=present  
with\_items: genericusers\_groups

`

For argument “system”, there is a value “no” I can use as a default value, no problem at all. But for “gid”, I tried to feed it with “default(None)”, the value will be rendered as string first anyway, so that would be gid=None, ValueError be raised. As a result, unavoidable, I need to pass a valid value to gid.

I saw some discuss in this issue report: [https://github.com/ansible/ansible/issues/8233](https://github.com/ansible/ansible/issues/8233)

I understand that for security reason, if-else statements in playbook are not welcomed, but the problem is without if-else statements, I have no idea how to omit arguments without “do not set anything for this” value. The problem is a little bit like Python’s not set default value, we usually create an object stands for not\_set value like this

`  
NOT\_SET = object()

def foobar(value=NOT\_SET):  
pass  
`

But in ansible, I didn’t see anything like that. Or did I miss something? I think it would be helpful if there is some kind of special filter like

`

- name: generic-users | Make sure all groups are present  
group: \>  
name=“{{ item.name }}”  
system=“{{ item.system|default(‘no’) }}”  
gid=“{{ item.gid|default\_omit) }}”  
state=present  
with\_items: genericusers\_groups

`

The default\_omit filter here omits “gid” argument if it is not defined. Just an idea. However, since modifying context in a jinja2 template would be difficult to implement, I think maybe it’s better to encourage YAML style arguments like this:

`

- name: generic-users | Make sure all groups are present  
group:  
name: “{{ item.name }}”  
system: “{{ item.system|default(‘no’) }}”  
gid: “{{ item.gid|default\_omit) }}”  
state=present  
with\_items: genericusers\_groups  
`

And for the default\_omit, maybe it can return a random nonce generated by system (so that attacker cannot inject this value to remove argument), like this

**omit\_place\_holder\_8843d7f92416211de9ebb963ff4ce28125932878**

And when ansible sees this value for a argument, it simply remove the key from arguments instead of passing it down to module.

But anyway, these are just some thinkings, the more important thing is, I would like to know, at this moment, how can I solve that “gid” cannot be omit issue? Is there any workaround? There are so many modules there, if you give an argument there, it means you want to change that thing, and there is no not\_set value.

---

<div class="post-metadata">

**Author:** ![Michael\_DeHaan1](https://avatars.discourse-cdn.com/v4/letter/m/5e9695/32.png) [@Michael\_DeHaan1](https://forum.ansible.com/u/Michael_DeHaan1)\
**Post date:** [July 29, 2014, 12:34am UTC](https://forum.ansible.com/t/how-to-skip-optional-arguments-to-a-module-after-new-security-patch/15796/2 "2014-07-29T00:34:08Z")

</div>

Replying shortly.

For clarity purposes what you have selected in the original pastebin which is no longer legal was:

```auto

- name: generic-users | Make sure all groups are present

  group: name={{[item.name](http://item.name)}}{% if item.system is defined %} {{item.system}}{% endif %}{% if item.gid is defined %} gid={{item.gid}}{% endif %} state=present

  with_items: genericusers_groups

```

---

<div class="post-metadata">

**Author:** ![Michael\_DeHaan1](https://avatars.discourse-cdn.com/v4/letter/m/5e9695/32.png) [@Michael\_DeHaan1](https://forum.ansible.com/u/Michael_DeHaan1)\
**Post date:** [July 29, 2014, 12:40am UTC](https://forum.ansible.com/t/how-to-skip-optional-arguments-to-a-module-after-new-security-patch/15796/3 "2014-07-29T00:40:14Z")

</div>

For completeness, the security bug was about untrusted remote data (from facts) being used to add arguments to commands in playbooks if things were formatted in ways that would allow it.

I can’t say I entirely follow the omit proposal but I think I get the gist. However, it’s better if we can do something that covers both key=value and longform arguments. I like the following idea a little better:

Basically what would need to be done here is to teach the code what to do if the gid was None, and introduce the concept that None meant “no change” as if the argument was not set.

This may require something on argument\_spec (sorry, code internals) that looks like

argument\_spec = dict(  
param = dict(name=‘foo’, required=False, nullable=True)  
)

And if the param is “None” or “”, it would be /removed/ from the input parameter list, if set nullable.

For completeness, you have the following workaround available now but probably won’t like it:

- module\_name: foo=bar  
when: baz is undefined
- module\_name: foo=bar baz={{ baz }}  
when: baz is defined

I understand that’s not perfect, but we do need to protect against variable additions.

In my proposal, you could still do

- module\_name: foo=bar baz={{ baz }}

Because baz should insert None if set None. if undefined, needs to be |default(None).

---

<div class="post-metadata">

**Author:** ![Victor\_Lin](https://avatars.discourse-cdn.com/v4/letter/v/87869e/32.png) [@Victor\_Lin](https://forum.ansible.com/u/Victor_Lin)\
**Post date:** [July 29, 2014, 1:59am UTC](https://forum.ansible.com/t/how-to-skip-optional-arguments-to-a-module-after-new-security-patch/15796/4 "2014-07-29T01:59:45Z")

</div>

Yeah, I understand that nullable approach, I also had the same idea originally. However, it requires all modules to be modified to support nullable value isn’t it. In the mean time, my default omit could be a pretty helpful temporary solution. Just made a pull request to show how it works

[https://github.com/ansible/ansible/pull/8323](https://github.com/ansible/ansible/pull/8323)

Michael DeHaan於 2014年7月28日星期一UTC-7下午5時40分18秒寫道：

---

<div class="post-metadata">

**Author:** ![Michael\_DeHaan1](https://avatars.discourse-cdn.com/v4/letter/m/5e9695/32.png) [@Michael\_DeHaan1](https://forum.ansible.com/u/Michael_DeHaan1)\
**Post date:** [July 29, 2014, 12:57pm UTC](https://forum.ansible.com/t/how-to-skip-optional-arguments-to-a-module-after-new-security-patch/15796/5 "2014-07-29T12:57:26Z")

</div>

Thanks for this, though this appears to only work for complex args.

If you could make it work for non-complex (key=value) args as well, I’m open to having something like this, but I think the parameter should be, if this does work for them, something like “|nullable” vs “default\_omit”.

---

<div class="post-metadata">

**Author:** ![Miks\_Kalnins](https://avatars.discourse-cdn.com/v4/letter/m/d2c977/32.png) [@Miks\_Kalnins](https://forum.ansible.com/u/Miks_Kalnins)\
**Post date:** [July 30, 2014, 11:26pm UTC](https://forum.ansible.com/t/how-to-skip-optional-arguments-to-a-module-after-new-security-patch/15796/6 "2014-07-30T23:26:16Z")

</div>

I have similar problem and can’t really use the workaround.

---

<div class="post-metadata">

**Author:** ![Michael\_DeHaan1](https://avatars.discourse-cdn.com/v4/letter/m/5e9695/32.png) [@Michael\_DeHaan1](https://forum.ansible.com/u/Michael_DeHaan1)\
**Post date:** [July 31, 2014, 10:39pm UTC](https://forum.ansible.com/t/how-to-skip-optional-arguments-to-a-module-after-new-security-patch/15796/7 "2014-07-31T22:39:09Z")

</div>

This has been discussed a few times in prior threads.

Ultimately the proposal was that we would consider making certain flags automatically removable using something like a token value of {{ omit }} and the system could prune those values that used this magic variable.

priv={% if x %}{{y}}{% else %}{{ omit }}{% endif %}

Though in the above, it seems you’re trying to abstract a module around a very general purpose role in a slightly non-conventional way. In your particular usage, it might be better to just have defaults for most of those settings.

{{ item.flags | default(default\_value) }}

etc
