Moderate severityNVD Advisory· Published Oct 27, 2011· Updated Apr 29, 2026
CVE-2011-3870
CVE-2011-3870
Description
Puppet 2.7.x before 2.7.5, 2.6.x before 2.6.11, and 0.25.x allows local users to modify the permissions of arbitrary files via a symlink attack on the SSH authorized_keys file.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
puppetRubyGems | >= 2.7.0, < 2.7.5 | 2.7.5 |
puppetRubyGems | < 2.6.11 | 2.6.11 |
Affected products
23cpe:2.3:a:puppetlabs:puppet:2.7.0:*:*:*:*:*:*:*+ 1 more
- cpe:2.3:a:puppetlabs:puppet:2.7.0:*:*:*:*:*:*:*
- cpe:2.3:a:puppetlabs:puppet:2.7.1:*:*:*:*:*:*:*
cpe:2.3:a:puppet:puppet:0.25.0:*:*:*:*:*:*:*+ 20 more
- cpe:2.3:a:puppet:puppet:0.25.0:*:*:*:*:*:*:*
- cpe:2.3:a:puppet:puppet:0.25.1:*:*:*:*:*:*:*
- cpe:2.3:a:puppet:puppet:0.25.2:*:*:*:*:*:*:*
- cpe:2.3:a:puppet:puppet:0.25.3:*:*:*:*:*:*:*
- cpe:2.3:a:puppet:puppet:0.25.4:*:*:*:*:*:*:*
- cpe:2.3:a:puppet:puppet:0.25.5:*:*:*:*:*:*:*
- cpe:2.3:a:puppet:puppet:0.25.6:*:*:*:*:*:*:*
- cpe:2.3:a:puppet:puppet:2.6.0:*:*:*:*:*:*:*
- cpe:2.3:a:puppet:puppet:2.6.1:*:*:*:*:*:*:*
- cpe:2.3:a:puppet:puppet:2.6.10:*:*:*:*:*:*:*
- cpe:2.3:a:puppet:puppet:2.6.2:*:*:*:*:*:*:*
- cpe:2.3:a:puppet:puppet:2.6.3:*:*:*:*:*:*:*
- cpe:2.3:a:puppet:puppet:2.6.4:*:*:*:*:*:*:*
- cpe:2.3:a:puppet:puppet:2.6.5:*:*:*:*:*:*:*
- cpe:2.3:a:puppet:puppet:2.6.6:*:*:*:*:*:*:*
- cpe:2.3:a:puppet:puppet:2.6.7:*:*:*:*:*:*:*
- cpe:2.3:a:puppet:puppet:2.6.8:*:*:*:*:*:*:*
- cpe:2.3:a:puppet:puppet:2.6.9:*:*:*:*:*:*:*
- cpe:2.3:a:puppet:puppet:2.7.2:*:*:*:*:*:*:*
- cpe:2.3:a:puppet:puppet:2.7.3:*:*:*:*:*:*:*
- cpe:2.3:a:puppet:puppet:2.7.4:*:*:*:*:*:*:*
Patches
288512e880bd2Drop privileges before creating and chmodding SSH keys.
2 files changed · +18 −17
lib/puppet/provider/ssh_authorized_key/parsed.rb+10 −9 modified@@ -56,21 +56,22 @@ def user def flush raise Puppet::Error, "Cannot write SSH authorized keys without user" unless @resource.should(:user) raise Puppet::Error, "User '#{@resource.should(:user)}' does not exist" unless uid = Puppet::Util.uid(@resource.should(:user)) - unless File.exist?(dir = File.dirname(target)) - Puppet.debug "Creating #{dir}" - Dir.mkdir(dir, dir_perm) - File.chown(uid, nil, dir) - end - # ParsedFile usually calls backup_target much later in the flush process, # but our SUID makes that fail to open filebucket files for writing. # Fortunately, there's already logic to make sure it only ever happens once, # so calling it here supresses the later attempt by our superclass's flush method. self.class.backup_target(target) - Puppet::Util::SUIDManager.asuser(@resource.should(:user)) { super } - File.chown(uid, nil, target) - File.chmod(file_perm, target) + Puppet::Util::SUIDManager.asuser(@resource.should(:user)) do + unless File.exist?(dir = File.dirname(target)) + Puppet.debug "Creating #{dir}" + Dir.mkdir(dir, dir_perm) + end + + super + + File.chmod(file_perm, target) + end end # parse sshv2 option strings, wich is a comma separated list of
spec/unit/provider/ssh_authorized_key/parsed_spec.rb+8 −8 modified@@ -133,15 +133,15 @@ def genkey(key) @provider.flush end - it "should chown the directory to the user" do + it "should absolutely not chown the directory to the user" do uid = Puppet::Util.uid("random_bob") - File.expects(:chown).with(uid, nil, "/tmp/.ssh_dir") + File.expects(:chown).never @provider.flush end - it "should chown the key file to the user" do + it "should absolutely not chown the key file to the user" do uid = Puppet::Util.uid("random_bob") - File.expects(:chown).with(uid, nil, "/tmp/.ssh_dir/place_to_put_authorized_keys") + File.expects(:chown).never @provider.flush end @@ -177,11 +177,11 @@ def genkey(key) @provider.flush end - it "should chown the directory to the user if it creates it" do + it "should absolutely not chown the directory to the user if it creates it" do File.stubs(:exist?).with(@dir).returns false Dir.stubs(:mkdir).with(@dir,0700) uid = Puppet::Util.uid("nobody") - File.expects(:chown).with(uid, nil, @dir) + File.expects(:chown).never @provider.flush end @@ -192,9 +192,9 @@ def genkey(key) @provider.flush end - it "should chown the key file to the user" do + it "should absolutely not chown the key file to the user" do uid = Puppet::Util.uid("nobody") - File.expects(:chown).with(uid, nil, File.expand_path("~nobody/.ssh/authorized_keys")) + File.expects(:chown).never @provider.flush end
b29b1785d543Drop privileges before creating and chmodding SSH keys.
2 files changed · +18 −17
lib/puppet/provider/ssh_authorized_key/parsed.rb+10 −9 modified@@ -50,21 +50,22 @@ def user def flush raise Puppet::Error, "Cannot write SSH authorized keys without user" unless @resource.should(:user) raise Puppet::Error, "User '#{@resource.should(:user)}' does not exist" unless uid = Puppet::Util.uid(@resource.should(:user)) - unless File.exist?(dir = File.dirname(target)) - Puppet.debug "Creating #{dir}" - Dir.mkdir(dir, dir_perm) - File.chown(uid, nil, dir) - end - # ParsedFile usually calls backup_target much later in the flush process, # but our SUID makes that fail to open filebucket files for writing. # Fortunately, there's already logic to make sure it only ever happens once, # so calling it here supresses the later attempt by our superclass's flush method. self.class.backup_target(target) - Puppet::Util::SUIDManager.asuser(@resource.should(:user)) { super } - File.chown(uid, nil, target) - File.chmod(file_perm, target) + Puppet::Util::SUIDManager.asuser(@resource.should(:user)) do + unless File.exist?(dir = File.dirname(target)) + Puppet.debug "Creating #{dir}" + Dir.mkdir(dir, dir_perm) + end + + super + + File.chmod(file_perm, target) + end end # parse sshv2 option strings, wich is a comma separated list of
spec/unit/provider/ssh_authorized_key/parsed_spec.rb+8 −8 modified@@ -110,15 +110,15 @@ def genkey(key) @provider.flush end - it "should chown the directory to the user" do + it "should absolutely not chown the directory to the user" do uid = Puppet::Util.uid("random_bob") - File.expects(:chown).with(uid, nil, "/tmp/.ssh_dir") + File.expects(:chown).never @provider.flush end - it "should chown the key file to the user" do + it "should absolutely not chown the key file to the user" do uid = Puppet::Util.uid("random_bob") - File.expects(:chown).with(uid, nil, "/tmp/.ssh_dir/place_to_put_authorized_keys") + File.expects(:chown).never @provider.flush end @@ -153,11 +153,11 @@ def genkey(key) @provider.flush end - it "should chown the directory to the user if it creates it" do + it "should absolutely not chown the directory to the user if it creates it" do File.stubs(:exist?).with(@dir).returns false Dir.stubs(:mkdir).with(@dir,0700) uid = Puppet::Util.uid("nobody") - File.expects(:chown).with(uid, nil, @dir) + File.expects(:chown).never @provider.flush end @@ -168,9 +168,9 @@ def genkey(key) @provider.flush end - it "should chown the key file to the user" do + it "should absolutely not chown the key file to the user" do uid = Puppet::Util.uid("nobody") - File.expects(:chown).with(uid, nil, File.expand_path("~nobody/.ssh/authorized_keys")) + File.expects(:chown).never @provider.flush end
Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
14- groups.google.com/group/puppet-announce/browse_thread/thread/91e3b46d2328a1cbnvdPatchWEB
- lists.fedoraproject.org/pipermail/package-announce/2011-October/068053.htmlnvdPatchWEB
- lists.fedoraproject.org/pipermail/package-announce/2011-October/068061.htmlnvdPatchWEB
- lists.fedoraproject.org/pipermail/package-announce/2011-October/068093.htmlnvdPatchWEB
- secunia.com/advisories/46458nvdVendor Advisory
- github.com/advisories/GHSA-qh3g-27jf-3j54ghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2011-3870ghsaADVISORY
- www.debian.org/security/2011/dsa-2314nvdWEB
- www.ubuntu.com/usn/USN-1223-1nvdWEB
- www.ubuntu.com/usn/USN-1223-2nvdWEB
- github.com/puppetlabs/puppet/commit/88512e880bd2a03694b5fef42540dc7b3da05d30ghsaWEB
- github.com/puppetlabs/puppet/commit/b29b1785d543a3cea961fffa9b3c15f14ab7cce0ghsaWEB
- github.com/rubysec/ruby-advisory-db/blob/master/gems/puppet/CVE-2011-3870.ymlghsaWEB
- puppet.com/security/cve/cve-2011-3870nvdWEB
News mentions
0No linked articles in our index yet.