summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames Cammarata <jimi@sngx.net>2014-06-30 15:59:32 -0500
committerJames Cammarata <jimi@sngx.net>2014-07-01 14:15:12 -0500
commit3761bc113295e20771544491d007f1d328f40b99 (patch)
treeeaa7450c6ba6db4f688a5f66a43101f6d0091f3f
parentd36195a355f09837ec7d38808e7f303790aad2ef (diff)
downloadansible-3761bc113295e20771544491d007f1d328f40b99.tar.gz
When parsing json from untrusted sources, remove templating tags
-rw-r--r--lib/ansible/inventory/script.py2
-rw-r--r--lib/ansible/runner/__init__.py2
-rw-r--r--lib/ansible/runner/return_data.py3
-rw-r--r--lib/ansible/utils/__init__.py42
-rw-r--r--lib/ansible/utils/template.py11
5 files changed, 41 insertions, 19 deletions
diff --git a/lib/ansible/inventory/script.py b/lib/ansible/inventory/script.py
index 05348b6839..aec52256f9 100644
--- a/lib/ansible/inventory/script.py
+++ b/lib/ansible/inventory/script.py
@@ -49,7 +49,7 @@ class InventoryScript(object):
def _parse(self, err):
all_hosts = {}
- self.raw = utils.parse_json(self.data)
+ self.raw = utils.parse_json(self.data, from_remote=True)
all = Group('all')
groups = dict(all=all)
group = None
diff --git a/lib/ansible/runner/__init__.py b/lib/ansible/runner/__init__.py
index 5f321e4729..44764cd2a5 100644
--- a/lib/ansible/runner/__init__.py
+++ b/lib/ansible/runner/__init__.py
@@ -507,7 +507,7 @@ class Runner(object):
cmd2 = "rm -rf %s >/dev/null 2>&1" % tmp
self._low_level_exec_command(conn, cmd2, tmp, sudoable=False)
- data = utils.parse_json(res['stdout'])
+ data = utils.parse_json(res['stdout'], from_remote=True)
if 'parsed' in data and data['parsed'] == False:
data['msg'] += res['stderr']
return ReturnData(conn=conn, result=data)
diff --git a/lib/ansible/runner/return_data.py b/lib/ansible/runner/return_data.py
index 8e2252d4a3..5b99c45898 100644
--- a/lib/ansible/runner/return_data.py
+++ b/lib/ansible/runner/return_data.py
@@ -43,8 +43,7 @@ class ReturnData(object):
self.diff = diff
if type(self.result) in [ str, unicode ]:
- self.result = utils.parse_json(self.result)
-
+ self.result = utils.parse_json(self.result, from_remote=True)
if self.host is None:
raise Exception("host not set")
diff --git a/lib/ansible/utils/__init__.py b/lib/ansible/utils/__init__.py
index 1f7ce46f67..a6856e5872 100644
--- a/lib/ansible/utils/__init__.py
+++ b/lib/ansible/utils/__init__.py
@@ -313,7 +313,38 @@ def json_loads(data):
return json.loads(data)
-def parse_json(raw_data):
+def _clean_data(orig_data):
+ ''' remove template tags from a string '''
+ data = orig_data
+ if isinstance(orig_data, basestring):
+ for pattern,replacement in (('{{','{#'), ('}}','#}'), ('{%','{#'), ('%}','#}')):
+ data = data.replace(pattern, replacement)
+ return data
+
+def _clean_data_struct(orig_data):
+ '''
+ walk a complex data structure, and use _clean_data() to
+ remove any template tags that may exist
+ '''
+ if isinstance(orig_data, dict):
+ data = orig_data.copy()
+ for key in data:
+ new_key = _clean_data_struct(key)
+ new_val = _clean_data_struct(data[key])
+ if key != new_key:
+ del data[key]
+ data[new_key] = new_val
+ elif isinstance(orig_data, list):
+ data = orig_data[:]
+ for i in range(0, len(data)):
+ data[i] = _clean_data_struct(data[i])
+ elif isinstance(orig_data, basestring):
+ data = _clean_data(orig_data)
+ else:
+ data = orig_data
+ return data
+
+def parse_json(raw_data, from_remote=False):
''' this version for module return data only '''
orig_data = raw_data
@@ -322,7 +353,7 @@ def parse_json(raw_data):
data = filter_leading_non_json_lines(raw_data)
try:
- return json.loads(data)
+ results = json.loads(data)
except:
# not JSON, but try "Baby JSON" which allows many of our modules to not
# require JSON and makes writing modules in bash much simpler
@@ -332,7 +363,6 @@ def parse_json(raw_data):
except:
print "failed to parse json: "+ data
raise
-
for t in tokens:
if "=" not in t:
raise errors.AnsibleError("failed to parse: %s" % orig_data)
@@ -347,7 +377,11 @@ def parse_json(raw_data):
results[key] = value
if len(results.keys()) == 0:
return { "failed" : True, "parsed" : False, "msg" : orig_data }
- return results
+
+ if from_remote:
+ results = _clean_data_struct(results)
+
+ return results
def smush_braces(data):
''' smush Jinaj2 braces so unresolved templates like {{ foo }} don't get parsed weird by key=value code '''
diff --git a/lib/ansible/utils/template.py b/lib/ansible/utils/template.py
index 8ec27ac097..7108c8d906 100644
--- a/lib/ansible/utils/template.py
+++ b/lib/ansible/utils/template.py
@@ -80,7 +80,6 @@ class Flags:
FILTER_PLUGINS = None
_LISTRE = re.compile(r"(\w+)\[(\d+)\]")
-JINJA2_OVERRIDE='#jinja2:'
def lookup(name, *args, **kwargs):
from ansible import utils
@@ -228,16 +227,6 @@ def template_from_file(basedir, path, vars, vault_password=None):
except:
raise errors.AnsibleError("unable to read %s" % realpath)
-
- # Get jinja env overrides from template
- if data.startswith(JINJA2_OVERRIDE):
- eol = data.find('\n')
- line = data[len(JINJA2_OVERRIDE):eol]
- data = data[eol+1:]
- for pair in line.split(','):
- (key,val) = pair.split(':')
- setattr(environment,key.strip(),ast.literal_eval(val.strip()))
-
environment.template_class = J2Template
try:
t = environment.from_string(data)