diff --git a/changelogs/fragments/avoid_cwd_vars.yml b/changelogs/fragments/avoid_cwd_vars.yml new file mode 100644 index 00000000000..58ee6846d9f --- /dev/null +++ b/changelogs/fragments/avoid_cwd_vars.yml @@ -0,0 +1,2 @@ +bugfixes: + - '**Security Fix** - avoid loading host/group vars from cwd when not specifying a playbook or playbook base dir' diff --git a/lib/ansible/cli/__init__.py b/lib/ansible/cli/__init__.py index 177990776df..380ddc4e2a4 100644 --- a/lib/ansible/cli/__init__.py +++ b/lib/ansible/cli/__init__.py @@ -664,7 +664,7 @@ class CLI(with_metaclass(ABCMeta, object)): ansible_versions[counter] = 0 try: ansible_versions[counter] = int(ansible_versions[counter]) - except: + except Exception: pass if len(ansible_versions) < 3: for counter in range(len(ansible_versions), 3): @@ -809,6 +809,12 @@ class CLI(with_metaclass(ABCMeta, object)): # the code, ensuring a consistent view of global variables variable_manager = VariableManager(loader=loader, inventory=inventory) + if hasattr(options, 'basedir'): + if options.basedir: + variable_manager.safe_basedir = True + else: + variable_manager.safe_basedir = True + # load vars from cli options variable_manager.extra_vars = load_extra_vars(loader=loader, options=options) variable_manager.options_vars = load_options_vars(options, CLI.version_info(gitinfo=False)) diff --git a/lib/ansible/vars/manager.py b/lib/ansible/vars/manager.py index 6aa3cd6397c..b78ba2938f8 100644 --- a/lib/ansible/vars/manager.py +++ b/lib/ansible/vars/manager.py @@ -90,6 +90,7 @@ class VariableManager: self._hostvars = None self._omit_token = '__omit_place_holder__%s' % sha1(os.urandom(64)).hexdigest() self._options_vars = defaultdict(dict) + self.safe_basedir = False # bad cache plugin is not fatal error try: @@ -110,6 +111,7 @@ class VariableManager: omit_token=self._omit_token, options_vars=self._options_vars, inventory=self._inventory, + safe_basedir=self.safe_basedir, ) return data @@ -123,6 +125,7 @@ class VariableManager: self._omit_token = data.get('omit_token', '__omit_place_holder__%s' % sha1(os.urandom(64)).hexdigest()) self._inventory = data.get('inventory', None) self._options_vars = data.get('options_vars', dict()) + self.safe_basedir = data.get('safe_basedir', False) @property def extra_vars(self): @@ -183,7 +186,9 @@ class VariableManager: ) # default for all cases - basedirs = [self._loader.get_basedir()] + basedirs = [] + if self.safe_basedir: # avoid adhoc/console loading cwd + basedirs = [self._loader.get_basedir()] if play: # first we compile any vars specified in defaults/main.yml