Security fixes:

* Strip lookup calls out of inventory variables and clean unsafe data
  returned from lookup plugins (CVE-2014-4966)
* Make sure vars don't insert extra parameters into module args and prevent
  duplicate params from superseding previous params (CVE-2014-4967)
This commit is contained in:
James Cammarata 2014-07-21 11:20:49 -05:00
parent 9f294530e9
commit 274e1f4106

View file

@ -184,38 +184,45 @@ class CommandModule(AnsibleModule):
''' read the input and return a dictionary and the arguments string ''' ''' read the input and return a dictionary and the arguments string '''
args = MODULE_ARGS args = MODULE_ARGS
params = {} params = {}
params['chdir'] = None params['chdir'] = None
params['creates'] = None params['creates'] = None
params['removes'] = None params['removes'] = None
params['shell'] = False params['shell'] = False
params['executable'] = None params['executable'] = None
if "#USE_SHELL" in args: if "#USE_SHELL" in args:
args = args.replace("#USE_SHELL", "") args = args.replace("#USE_SHELL", "")
params['shell'] = True params['shell'] = True
r = re.compile(r'(^|\s)(creates|removes|chdir|executable|NO_LOG)=(?P<quote>[\'"])?(.*?)(?(quote)(?<!\\)(?P=quote))((?<!\\)(?=\s)|$)') # use shlex to split up the args, while being careful to preserve
for m in r.finditer(args): # single quotes so they're not removed accidentally
v = m.group(4).replace("\\", "") lexer = shlex.shlex(args, posix=True)
if m.group(2) == "creates": lexer.whitespace_split = True
params['creates'] = v lexer.quotes = '"'
elif m.group(2) == "removes": lexer.ignore_quotes = "'"
params['removes'] = v items = list(lexer)
elif m.group(2) == "chdir":
v = os.path.expanduser(v) command_args = ''
v = os.path.abspath(v) for x in items:
if not (os.path.exists(v) and os.path.isdir(v)): if '=' in x:
self.fail_json(rc=258, msg="cannot change to directory '%s': path does not exist" % v) # check to see if this is a special parameter for the command
params['chdir'] = v k, v = x.split('=', 1)
elif m.group(2) == "executable": if k in ('creates', 'removes', 'chdir', 'executable', 'NO_LOG'):
v = os.path.expanduser(v) if k == "chdir":
v = os.path.abspath(v) v = os.path.abspath(os.path.expanduser(v))
if not (os.path.exists(v)): if not (os.path.exists(v) and os.path.isdir(v)):
self.fail_json(rc=258, msg="cannot use executable '%s': file does not exist" % v) self.fail_json(rc=258, msg="cannot change to directory '%s': path does not exist" % v)
params['executable'] = v elif k == "executable":
elif m.group(2) == "NO_LOG": v = os.path.abspath(os.path.expanduser(v))
params['NO_LOG'] = self.boolean(v) if not (os.path.exists(v)):
args = r.sub("", args) self.fail_json(rc=258, msg="cannot use executable '%s': file does not exist" % v)
params['args'] = args params[k] = v
else:
# this isn't a valid parameter, so just append it back to the list of arguments
command_args = "%s %s" % (command_args, x)
else:
# not a param, so just append it to the list of arguments
command_args = "%s %s" % (command_args, x)
params['args'] = command_args.strip()
return (params, params['args']) return (params, params['args'])
main() main()