CVE-2018-10874
Description
In ansible it was found that inventory variables are loaded from current working directory when running ad-hoc command which are under attacker's control, allowing to run arbitrary code as a result.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
Ansible ad-hoc commands load inventory variables from the current working directory, allowing an attacker to run arbitrary code by placing a crafted file.
Vulnerability
Ansible versions prior to the fix are affected by a vulnerability where ansible.cfg and inventory variables are loaded from the current working directory when running ad-hoc commands. This behavior allows an attacker to control the configuration file or inventory variables if they can place a crafted file in the directory where the command is executed [1][2][3][4].
Exploitation
A local attacker with the ability to write or place a malicious ansible.cfg or inventory file in the current working directory can influence the behavior of an ad-hoc command. When a user runs an ad-hoc command from that directory, the system loads the attacker-controlled configuration or variables, referencing arbitrary plugin or module paths, leading to code execution [1][4].
Impact
Successful exploitation allows the attacker to run arbitrary code with the privileges of the user running the ad-hoc command, resulting in local privilege escalation and potential system compromise [1][4].
Mitigation
The vulnerability is fixed in Ansible versions released after the disclosure. Red Hat has issued fixes via RHSA-2018:2321, and Ubuntu has released updates as part of USN-4072-1 [3][4]. Users should update to the latest patched version. No workaround is documented; the recommended mitigation is to apply the patch or ensure ad-hoc commands are not run from untrusted directories.
AI Insight generated on May 22, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
ansiblePyPI | < 2.4.6.0 | 2.4.6.0 |
ansiblePyPI | >= 2.5, < 2.5.6 | 2.5.6 |
ansiblePyPI | >= 2.6, < 2.6.1 | 2.6.1 |
Affected products
37- ghsa-coords37 versionspkg:pypi/ansiblepkg:rpm/opensuse/ansible&distro=openSUSE%20Leap%2015.5pkg:rpm/opensuse/dracut-saltboot&distro=openSUSE%20Leap%2015.5pkg:rpm/opensuse/golang-github-prometheus-promu&distro=openSUSE%20Leap%2015.5pkg:rpm/opensuse/POS_Image-Graphical7&distro=openSUSE%20Leap%2015.5pkg:rpm/opensuse/POS_Image-JeOS7&distro=openSUSE%20Leap%2015.5pkg:rpm/opensuse/spacecmd&distro=openSUSE%20Leap%2015.5pkg:rpm/suse/ansible&distro=HPE%20Helion%20OpenStack%208pkg:rpm/suse/ansible&distro=SUSE%20Manager%20Client%20Tools%2015pkg:rpm/suse/ansible&distro=SUSE%20Manager%20Client%20Tools%2015-BETApkg:rpm/suse/ansible&distro=SUSE%20Manager%20Proxy%20Module%204.3pkg:rpm/suse/ansible&distro=SUSE%20OpenStack%20Cloud%208pkg:rpm/suse/ansible&distro=SUSE%20OpenStack%20Cloud%20Crowbar%208pkg:rpm/suse/dracut-saltboot&distro=SUSE%20Manager%20Client%20Tools%2015pkg:rpm/suse/dracut-saltboot&distro=SUSE%20Manager%20Client%20Tools%2015-BETApkg:rpm/suse/dracut-saltboot&distro=SUSE%20Manager%20Client%20Tools%20for%20SLE%20Micro%205pkg:rpm/suse/golang-github-prometheus-node_exporter&distro=SUSE%20Manager%20Client%20Tools%20Beta%20for%20SLE%20Micro%205pkg:rpm/suse/golang-github-prometheus-promu&distro=SUSE%20Linux%20Enterprise%20Module%20for%20Package%20Hub%2015%20SP5pkg:rpm/suse/grafana&distro=SUSE%20Manager%20Client%20Tools%2015pkg:rpm/suse/grafana&distro=SUSE%20Manager%20Client%20Tools%2015-BETApkg:rpm/suse/mgr-daemon&distro=SUSE%20Manager%20Client%20Tools%2015pkg:rpm/suse/POS_Image-Graphical7&distro=SUSE%20Manager%20Client%20Tools%2015pkg:rpm/suse/POS_Image-Graphical7&distro=SUSE%20Manager%20Client%20Tools%2015-BETApkg:rpm/suse/POS_Image-JeOS7&distro=SUSE%20Manager%20Client%20Tools%2015pkg:rpm/suse/POS_Image-JeOS7&distro=SUSE%20Manager%20Client%20Tools%2015-BETApkg:rpm/suse/spacecmd&distro=SUSE%20Manager%20Client%20Tools%2015pkg:rpm/suse/spacecmd&distro=SUSE%20Manager%20Client%20Tools%2015-BETApkg:rpm/suse/spacewalk-client-tools&distro=SUSE%20Manager%20Client%20Tools%2015pkg:rpm/suse/spacewalk-client-tools&distro=SUSE%20Manager%20Client%20Tools%2015-BETApkg:rpm/suse/spacewalk-koan&distro=SUSE%20Manager%20Client%20Tools%2015pkg:rpm/suse/supportutils-plugin-susemanager-client&distro=SUSE%20Manager%20Client%20Tools%2015-BETApkg:rpm/suse/uyuni-common-libs&distro=SUSE%20Manager%20Client%20Tools%2015pkg:rpm/suse/uyuni-proxy-systemd-services&distro=SUSE%20Manager%20Client%20Tools%2015pkg:rpm/suse/uyuni-proxy-systemd-services&distro=SUSE%20Manager%20Client%20Tools%20for%20SLE%20Micro%205pkg:rpm/suse/uyuni-proxy-systemd-services&distro=SUSE%20Manager%20Proxy%20Module%204.3pkg:rpm/suse/uyuni-tools&distro=SUSE%20Manager%20Client%20Tools%2015-BETApkg:rpm/suse/uyuni-tools&distro=SUSE%20Manager%20Client%20Tools%20Beta%20for%20SLE%20Micro%205
< 2.4.6.0+ 36 more
- (no CPE)range: < 2.4.6.0
- (no CPE)range: < 2.9.27-150000.1.17.2
- (no CPE)range: < 0.1.1710765237.46af599-150000.1.53.2
- (no CPE)range: < 0.14.0-150000.3.18.2
- (no CPE)range: < 0.1.1710765237.46af599-150000.1.21.2
- (no CPE)range: < 0.1.1710765237.46af599-150000.1.21.2
- (no CPE)range: < 4.3.27-150000.3.116.2
- (no CPE)range: < 2.4.6.0-3.3.1
- (no CPE)range: < 2.9.27-150000.1.17.2
- (no CPE)range: < 2.9.27-159000.3.12.2
- (no CPE)range: < 2.9.27-150000.1.17.2
- (no CPE)range: < 2.4.6.0-3.3.1
- (no CPE)range: < 2.4.6.0-3.3.1
- (no CPE)range: < 0.1.1710765237.46af599-150000.1.53.2
- (no CPE)range: < 0.1.1710765237.46af599-159000.3.33.2
- (no CPE)range: < 0.1.1710765237.46af599-150000.1.53.2
- (no CPE)range: < 1.5.0-159000.6.2.1
- (no CPE)range: < 0.14.0-150000.3.18.2
- (no CPE)range: < 9.5.18-150000.1.63.2
- (no CPE)range: < 9.5.16-159000.4.30.2
- (no CPE)range: < 4.3.9-150000.1.47.2
- (no CPE)range: < 0.1.1710765237.46af599-150000.1.21.2
- (no CPE)range: < 0.1.1710765237.46af599-159000.3.24.2
- (no CPE)range: < 0.1.1710765237.46af599-150000.1.21.2
- (no CPE)range: < 0.1.1710765237.46af599-159000.3.24.2
- (no CPE)range: < 4.3.27-150000.3.116.2
- (no CPE)range: < 5.0.5-159000.6.48.2
- (no CPE)range: < 4.3.19-150000.3.89.2
- (no CPE)range: < 5.0.4-159000.6.54.2
- (no CPE)range: < 4.3.6-150000.3.33.2
- (no CPE)range: < 5.0.3-159000.6.21.2
- (no CPE)range: < 4.3.10-150000.1.39.2
- (no CPE)range: < 4.3.12-150000.1.21.2
- (no CPE)range: < 4.3.12-150000.1.21.2
- (no CPE)range: < 4.3.12-150000.1.21.2
- (no CPE)range: < 0.1.7-159000.3.8.1
- (no CPE)range: < 0.1.7-159000.3.8.1
Patches
310d6fe6c98cf[stable-2.5] avoid loading vars on unspecified basedir (cwd) (#42067) (#42139)
3 files changed · +15 −2
changelogs/fragments/avoid_cwd_vars.yml+2 −0 added@@ -0,0 +1,2 @@ +bugfixes: + - '**Security Fix** - avoid loading host/group vars from cwd when not specifying a playbook or playbook base dir'
lib/ansible/cli/__init__.py+7 −1 modified@@ -662,7 +662,7 @@ def version_info(gitinfo=False): 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): @@ -807,6 +807,12 @@ def _play_prereqs(options): # 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))
lib/ansible/vars/manager.py+6 −1 modified@@ -90,6 +90,7 @@ def __init__(self, loader=None, inventory=None): 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 @@ def __getstate__(self): omit_token=self._omit_token, options_vars=self._options_vars, inventory=self._inventory, + safe_basedir=self.safe_basedir, ) return data @@ -123,6 +125,7 @@ def __setstate__(self, data): 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 @@ def get_vars(self, play=None, host=None, task=None, include_hostvars=True, inclu ) # 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
44874addc7ea[stable-2.4] avoid loading vars on unspecified basedir (cwd) (#42067)
3 files changed · +16 −3
CHANGELOG.md+3 −1 modified@@ -3,9 +3,11 @@ Ansible Changes By Release <a id="2.4.6"></a> -## 2.4.5 "Dancing Days" - TBD +## 2.4.6 "Dancing Days" - TBD ### Bugfixes +* **Security Fix** - avoid using ansible.cfg in a world readable dir + https://github.com/ansible/ansible/pull/42070 <a id="2.4.5"></a>
lib/ansible/cli/__init__.py+7 −1 modified@@ -652,7 +652,7 @@ def version_info(gitinfo=False): 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): @@ -793,6 +793,12 @@ def _play_prereqs(options): # 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))
lib/ansible/vars/manager.py+6 −1 modified@@ -122,6 +122,7 @@ def __init__(self, loader=None, inventory=None): 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: @@ -142,6 +143,7 @@ def __getstate__(self): omit_token=self._omit_token, options_vars=self._options_vars, inventory=self._inventory, + safe_basedir=self.safe_basedir, ) return data @@ -155,6 +157,7 @@ def __setstate__(self, data): 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): @@ -233,7 +236,9 @@ def get_vars(self, play=None, host=None, task=None, include_hostvars=True, inclu ) # 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
1f80949f964a[stable-2.6] avoid loading vars on unspecified basedir (cwd) (#42067)
3 files changed · +15 −2
changelogs/fragments/avoid_cwd_vars.yml+2 −0 added@@ -0,0 +1,2 @@ +bugfixes: + - '**Security Fix** - avoid loading host/group vars from cwd when not specifying a playbook or playbook base dir'
lib/ansible/cli/__init__.py+7 −1 modified@@ -664,7 +664,7 @@ def version_info(gitinfo=False): 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 @@ def _play_prereqs(options): # 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))
lib/ansible/vars/manager.py+6 −1 modified@@ -90,6 +90,7 @@ def __init__(self, loader=None, inventory=None): 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 @@ def __getstate__(self): omit_token=self._omit_token, options_vars=self._options_vars, inventory=self._inventory, + safe_basedir=self.safe_basedir, ) return data @@ -123,6 +125,7 @@ def __setstate__(self, data): 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 @@ def get_vars(self, play=None, host=None, task=None, include_hostvars=True, inclu ) # 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
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
22- access.redhat.com/errata/RHBA-2018:3788ghsavendor-advisoryx_refsource_REDHATWEB
- access.redhat.com/errata/RHSA-2018:2150ghsavendor-advisoryx_refsource_REDHATWEB
- access.redhat.com/errata/RHSA-2018:2151ghsavendor-advisoryx_refsource_REDHATWEB
- access.redhat.com/errata/RHSA-2018:2152ghsavendor-advisoryx_refsource_REDHATWEB
- access.redhat.com/errata/RHSA-2018:2166ghsavendor-advisoryx_refsource_REDHATWEB
- access.redhat.com/errata/RHSA-2018:2321ghsavendor-advisoryx_refsource_REDHATWEB
- access.redhat.com/errata/RHSA-2018:2585ghsavendor-advisoryx_refsource_REDHATWEB
- access.redhat.com/errata/RHSA-2019:0054ghsavendor-advisoryx_refsource_REDHATWEB
- github.com/advisories/GHSA-3xvg-x47j-x75wghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2018-10874ghsaADVISORY
- usn.ubuntu.com/4072-1/mitrevendor-advisoryx_refsource_UBUNTU
- www.securitytracker.com/id/1041396mitrevdb-entryx_refsource_SECTRACK
- access.redhat.com/security/cve/CVE-2018-10874ghsaWEB
- bugzilla.redhat.com/show_bug.cgighsaWEB
- bugzilla.redhat.com/show_bug.cgighsax_refsource_CONFIRMWEB
- github.com/ansible/ansible/commit/10d6fe6c98cfee9a7be0fea6102ba5dec951aec7ghsaWEB
- github.com/ansible/ansible/commit/1f80949f964a946773f9d3ac1899535bd2cc2b8eghsaWEB
- github.com/ansible/ansible/commit/44874addc7ea136f83c67d5869047ece02645fdbghsaWEB
- github.com/ansible/ansible/pull/42067ghsaWEB
- github.com/pypa/advisory-database/tree/main/vulns/ansible/PYSEC-2018-81.yamlghsaWEB
- usn.ubuntu.com/4072-1ghsaWEB
- web.archive.org/web/20201130165946/http://www.securitytracker.com/id/1041396ghsaWEB
News mentions
0No linked articles in our index yet.