From a83e10d77d939b5f3bc4a43bc9dedc4d40f7b000 Mon Sep 17 00:00:00 2001 From: Michael DeHaan Date: Wed, 10 Apr 2013 16:17:24 -0400 Subject: [PATCH] Use safe_eval vs eval. --- lib/ansible/runner/lookup_plugins/items.py | 4 +++- lib/ansible/utils/__init__.py | 28 +++++++++++++++++++++- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/lib/ansible/runner/lookup_plugins/items.py b/lib/ansible/runner/lookup_plugins/items.py index 2e4ec18246..3f1b6dda54 100644 --- a/lib/ansible/runner/lookup_plugins/items.py +++ b/lib/ansible/runner/lookup_plugins/items.py @@ -15,6 +15,8 @@ # You should have received a copy of the GNU General Public License # along with Ansible. If not, see . +from ansible.utils import safe_eval + def flatten(terms): ret = [] for term in terms: @@ -34,7 +36,7 @@ class LookupModule(object): if '{' or '[' in terms: # Jinja2-ified list needs to be converted back to a real type # TODO: something a bit less heavy than eval - terms = eval(terms) + terms = safe_eval(terms) terms = [ terms ] return flatten(terms) diff --git a/lib/ansible/utils/__init__.py b/lib/ansible/utils/__init__.py index bc29eb0673..7951c916e7 100644 --- a/lib/ansible/utils/__init__.py +++ b/lib/ansible/utils/__init__.py @@ -162,7 +162,7 @@ def check_conditional(conditional): try: conditional = conditional.replace("\n", "\\n") - result = eval(conditional) + result = safe_eval(conditional) if result not in [ True, False ]: raise errors.AnsibleError("Conditional expression must evaluate to True or False: %s" % conditional) return result @@ -684,3 +684,29 @@ def is_list_of_strings(items): return False return True +def safe_eval(str): + ''' + this is intended for allowing things like: + with_items: {{ a_list_variable }} + where Jinja2 would return a string + but we do not want to allow it to call functions (outside of Jinja2, where + the env is constrained) + ''' + # FIXME: is there a more native way to do this? + + # do not allow method calls + if re.search(r'\w\.\w+\(', str): + print "C1" + return str + # do not allow imports + if re.search(r'import \w+', str): + print "C2" + return str + return eval(str) + + + + + + +