VYPR
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.

PackageAffected versionsPatched versions
puppetRubyGems
>= 2.7.0, < 2.7.52.7.5
puppetRubyGems
< 2.6.112.6.11

Affected products

23
  • Puppetlabs/Puppet2 versions
    cpe: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

2
88512e880bd2

Drop privileges before creating and chmodding SSH keys.

https://github.com/puppetlabs/puppetRicky ZhouAug 29, 2011via ghsa
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
     
    
b29b1785d543

Drop privileges before creating and chmodding SSH keys.

https://github.com/puppetlabs/puppetRicky ZhouAug 29, 2011via ghsa
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

News mentions

0

No linked articles in our index yet.