restore conditional lookup nerfing (#81460)

* a recent optimization lost the unsafe lookup disable behavior when templating conditionals with inline templates that referred to untrusted values
* added regression test to catch this case
pull/81481/head
Matt Davis 10 months ago committed by GitHub
parent fa5fe8a7db
commit 1c765a6afc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -101,10 +101,15 @@ class Conditional:
elif conditional == "":
return False
# If the result of the first-pass template render (to resolve inline templates) is marked unsafe,
# explicitly disable lookups on the final pass to prevent evaluation of untrusted content in the
# constructed template.
disable_lookups = hasattr(conditional, '__UNSAFE__')
# NOTE The spaces around True and False are intentional to short-circuit literal_eval for
# jinja2_native=False and avoid its expensive calls.
return templar.template(
"{%% if %s %%} True {%% else %%} False {%% endif %%}" % conditional
).strip() == "True"
"{%% if %s %%} True {%% else %%} False {%% endif %%}" % conditional,
disable_lookups=disable_lookups).strip() == "True"
except AnsibleUndefinedVariable as e:
raise AnsibleUndefinedVariable("error while evaluating conditional (%s): %s" % (original, e))

@ -665,3 +665,29 @@
- item
loop:
- 1 == 1
- set_fact:
sentinel_file: '{{ lookup("env", "OUTPUT_DIR")}}/LOOKUP_SIDE_EFFECT.txt'
- name: ensure sentinel file is absent
file:
path: '{{ sentinel_file }}'
state: absent
- name: get an untrusted var that's a valid Jinja expression with a side-effect
shell: |
echo "lookup('pipe', 'echo bang > \"$SENTINEL_FILE\" && cat \"$SENTINEL_FILE\"')"
environment:
SENTINEL_FILE: '{{ sentinel_file }}'
register: untrusted_expr
- name: use a conditional with an inline template that refers to the untrusted expression
debug:
msg: look at some seemingly innocuous stuff
when: '"foo" in {{ untrusted_expr.stdout }}'
ignore_errors: true
- name: ensure the untrusted expression side-effect has not executed
stat:
path: '{{ sentinel_file }}'
register: sentinel_stat
- assert:
that:
- not sentinel_stat.stat.exists

Loading…
Cancel
Save