CVE-2017-1000469
Description
Cobbler version up to 2.8.2 is vulnerable to a command injection vulnerability in the "add repo" component resulting in arbitrary code execution as root user.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
Cobbler up to 2.8.2 contains a command injection in the repo add component, allowing unauthenticated remote code execution as root.
Vulnerability
A command injection vulnerability exists in Cobbler versions up to 2.8.2, specifically in the 'add repo' component. The reposync action does not sanitize user-supplied input for repository mirror fields, allowing an attacker to inject arbitrary shell commands. The affected code paths are found in the wget_sync, rsync_sync, rhn_sync, and createrepo_walker functions, where parameters like dest_path, repo_mirror, and dirname are passed directly to shell commands without proper escaping [1][3].
Exploitation
An attacker needs access to the Cobbler web interface or API to create or edit a repository with a malicious mirror string. No authentication is required if the Cobbler service is exposed. The attack sequence involves: (1) creating a new repo and entering a crafted payload (e.g., backticks or semicolons) in the Mirror field, and (2) triggering a reposync action via the web UI, CLI, or scheduler. The unsanitized input is then executed as part of shell commands like wget, rsync, or createrepo [1][3].
Impact
Successful exploitation allows arbitrary command execution with root privileges, as Cobbler runs as root. An attacker can execute any system command, leading to full compromise of the server, including data exfiltration, installation of backdoors, or lateral movement within the network [2][3].
Mitigation
The fix was committed in commit 4b20397425a5d42a2d8927233654f4d7435bd4c2, which uses pipes.quote() to escape shell parameters [1]. Users should upgrade to a patched version (>= 2.8.3) or apply the commit manually. As a workaround, restrict access to the Cobbler interface and avoid exposing it to untrusted networks. The issue is not listed in CISA's Known Exploited Vulnerabilities catalog as of this writing.
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 |
|---|---|---|
cobblerPyPI | < 3.0.0 | 3.0.0 |
Affected products
29- ghsa-coords29 versionspkg:pypi/cobblerpkg:rpm/opensuse/cobbler&distro=openSUSE%20Leap%2015.2pkg:rpm/opensuse/cobbler&distro=openSUSE%20Tumbleweedpkg:rpm/suse/cobbler&distro=HPE%20Helion%20OpenStack%208pkg:rpm/suse/cobbler&distro=SUSE%20Linux%20Enterprise%20Server%2011%20SP3-CLIENT-TOOLSpkg:rpm/suse/cobbler&distro=SUSE%20Linux%20Enterprise%20Server%2011%20SP4-CLIENT-TOOLSpkg:rpm/suse/cobbler&distro=SUSE%20Manager%20Client%20Tools%2012pkg:rpm/suse/cobbler&distro=SUSE%20Manager%20Server%203.0pkg:rpm/suse/cobbler&distro=SUSE%20Manager%20Server%203.1pkg:rpm/suse/cobbler&distro=SUSE%20OpenStack%20Cloud%208pkg:rpm/suse/cobbler&distro=SUSE%20Package%20Hub%2015%20SP2pkg:rpm/suse/google-gson&distro=SUSE%20Manager%20Server%203.1pkg:rpm/suse/patterns-suse-manager&distro=SUSE%20Manager%20Server%203.1pkg:rpm/suse/prometheus-client-java&distro=SUSE%20Manager%20Server%203.1pkg:rpm/suse/py26-compat-salt&distro=SUSE%20Manager%20Server%203.1pkg:rpm/suse/salt-netapi-client&distro=SUSE%20Manager%20Server%203.1pkg:rpm/suse/spacewalk-backend&distro=SUSE%20Manager%20Server%203.1pkg:rpm/suse/spacewalk-branding&distro=SUSE%20Manager%20Server%203.1pkg:rpm/suse/spacewalk-certs-tools&distro=SUSE%20Manager%20Server%203.1pkg:rpm/suse/spacewalk-java&distro=SUSE%20Manager%20Server%203.1pkg:rpm/suse/spacewalk-utils&distro=SUSE%20Manager%20Server%203.1pkg:rpm/suse/spacewalk-web&distro=SUSE%20Manager%20Server%203.1pkg:rpm/suse/susemanager&distro=SUSE%20Manager%20Server%203.1pkg:rpm/suse/susemanager-docs_en&distro=SUSE%20Manager%20Server%203.1pkg:rpm/suse/susemanager-frontend-libs&distro=SUSE%20Manager%20Server%203.1pkg:rpm/suse/susemanager-schema&distro=SUSE%20Manager%20Server%203.1pkg:rpm/suse/susemanager-sls&distro=SUSE%20Manager%20Server%203.1pkg:rpm/suse/susemanager-sync-data&distro=SUSE%20Manager%20Server%203.1pkg:rpm/suse/susemanager-tftpsync&distro=SUSE%20Manager%20Server%203.1
< 3.0.0+ 28 more
- (no CPE)range: < 3.0.0
- (no CPE)range: < 3.1.2-lp152.6.3.1
- (no CPE)range: < 3.2.1.336+git.5639a3af-1.1
- (no CPE)range: < 2.6.6-49.9.1
- (no CPE)range: < 2.2.2-0.68.3.1
- (no CPE)range: < 2.2.2-0.68.3.1
- (no CPE)range: < 2.6.6-49.9.1
- (no CPE)range: < 2.6.6-49.9.1
- (no CPE)range: < 2.6.6-5.10.4
- (no CPE)range: < 2.6.6-49.9.1
- (no CPE)range: < 3.1.2-bp152.4.3.1
- (no CPE)range: < 2.8.2-3.3.6
- (no CPE)range: < 3.1-3.3.2
- (no CPE)range: < 0.3.0-1.3.5
- (no CPE)range: < 2016.11.4-1.7.2
- (no CPE)range: < 0.14.0-3.9.5
- (no CPE)range: < 2.7.73.13-2.19.5
- (no CPE)range: < 2.7.2.13-2.19.5
- (no CPE)range: < 2.7.0.10-2.12.4
- (no CPE)range: < 2.7.46.14-2.25.1
- (no CPE)range: < 2.7.10.7-2.10.4
- (no CPE)range: < 2.7.1.16-2.19.5
- (no CPE)range: < 3.1.14-2.19.5
- (no CPE)range: < 3.1-10.20.7
- (no CPE)range: < 3.1.1-3.3.2
- (no CPE)range: < 3.1.17-2.23.3
- (no CPE)range: < 3.1.17-2.23.2
- (no CPE)range: < 3.1.14-2.23.2
- (no CPE)range: < 3.1.3-3.6.2
Patches
14b20397425a5Escape shell parameters provided by user on reposync action (CVE-2017-1000469)
1 file changed · +9 −7
cobbler/action_reposync.py+9 −7 modified@@ -23,6 +23,7 @@ import os import os.path +import pipes import urlgrabber HAS_YUM = True @@ -201,7 +202,7 @@ def createrepo_walker(self, repo, dirname, fnames): flags = blended.get("createrepo_flags", "(ERROR: FLAGS)") try: # BOOKMARK - cmd = "createrepo %s %s %s" % (" ".join(mdoptions), flags, dirname) + cmd = "createrepo %s %s %s" % (" ".join(mdoptions), flags, pipes.quote(dirname)) utils.subprocess_call(self.logger, cmd) except: utils.log_exc(self.logger) @@ -225,7 +226,7 @@ def wget_sync(self, repo): dest_path = os.path.join(self.settings.webdir + "/repo_mirror", repo.name) # FIXME: wrapper for subprocess that logs to logger - cmd = "wget -N -np -r -l inf -nd -P %s %s" % (dest_path, repo_mirror) + cmd = "wget -N -np -r -l inf -nd -P %s %s" % (pipes.quote(dest_path), pipes.quote(repo_mirror)) rc = utils.subprocess_call(self.logger, cmd) if rc != 0: @@ -257,7 +258,7 @@ def rsync_sync(self, repo): repo.mirror = "%s/" % repo.mirror # FIXME: wrapper for subprocess that logs to logger - cmd = "rsync -rltDv --copy-unsafe-links --delete-after %s --delete --exclude-from=/etc/cobbler/rsync.exclude %s %s" % (spacer, repo.mirror, dest_path) + cmd = "rsync -rltDv --copy-unsafe-links --delete-after %s --delete --exclude-from=/etc/cobbler/rsync.exclude %s %s" % (spacer, pipes.quote(repo.mirror), pipes.quote(dest_path)) rc = utils.subprocess_call(self.logger, cmd) if rc != 0: @@ -321,7 +322,7 @@ def rhn_sync(self, repo): if has_rpm_list: self.logger.warning("warning: --rpm-list is not supported for RHN content") rest = repo.mirror[6:] # everything after rhn:// - cmd = "%s %s --repo=%s --download_path=%s" % (cmd, self.rflags, rest, self.settings.webdir + "/repo_mirror") + cmd = "%s %s --repo=%s --download_path=%s" % (cmd, self.rflags, pipes.quote(rest), pipes.quote(self.settings.webdir + "/repo_mirror")) if repo.name != rest: args = {"name": repo.name, "rest": rest} utils.die(self.logger, "ERROR: repository %(name)s needs to be renamed %(rest)s as the name of the cobbler repository must match the name of the RHN channel" % args) @@ -415,7 +416,7 @@ def yum_sync(self, repo): if not has_rpm_list: # if we have not requested only certain RPMs, use reposync - cmd = "%s %s --config=%s --repoid=%s --download_path=%s" % (cmd, self.rflags, temp_file, repo.name, self.settings.webdir + "/repo_mirror") + cmd = "%s %s --config=%s --repoid=%s --download_path=%s" % (cmd, self.rflags, temp_file, pipes.quote(repo.name), pipes.quote(self.settings.webdir + "/repo_mirror")) if repo.arch != "": if repo.arch == "x86": repo.arch = "i386" # FIX potential arch errors @@ -443,7 +444,7 @@ def yum_sync(self, repo): cmd = "/usr/bin/dnf download" else: cmd = "/usr/bin/yumdownloader" - cmd = "%s %s %s --disablerepo=* --enablerepo=%s -c %s --destdir=%s %s" % (cmd, extra_flags, use_source, repo.name, temp_file, dest_path, " ".join(repo.rpm_list)) + cmd = "%s %s %s --disablerepo=* --enablerepo=%s -c %s --destdir=%s %s" % (cmd, extra_flags, use_source, pipes.quote(repo.name), temp_file, pipes.quote(dest_path), " ".join(repo.rpm_list)) # now regardless of whether we're doing yumdownloader or reposync # or whether the repo was http://, ftp://, or rhn://, execute all queued @@ -534,7 +535,7 @@ def apt_sync(self, repo): dists = ",".join(repo.apt_dists) components = ",".join(repo.apt_components) - mirror_data = "--method=%s --host=%s --root=%s --dist=%s --section=%s" % (method, host, mirror, dists, components) + mirror_data = "--method=%s --host=%s --root=%s --dist=%s --section=%s" % (pipes.quote(method), pipes.quote(host), pipes.quote(mirror), pipes.quote(dists), pipes.quote(components)) rflags = "--nocleanup" for x in repo.yumopts: @@ -543,6 +544,7 @@ def apt_sync(self, repo): else: rflags += " %s" % x cmd = "%s %s %s %s" % (mirror_program, rflags, mirror_data, dest_path) + cmd = "%s %s %s %s" % (mirror_program, rflags, mirror_data, pipes.quote(dest_path)) if repo.arch == "src": cmd = "%s --source" % cmd else:
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
4- github.com/advisories/GHSA-96hw-v598-jvghghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2017-1000469ghsaADVISORY
- github.com/cobbler/cobbler/commit/4b20397425a5d42a2d8927233654f4d7435bd4c2ghsaWEB
- github.com/cobbler/cobbler/issues/1845ghsax_refsource_CONFIRMWEB
News mentions
0No linked articles in our index yet.