Uploaded image for project: 'Puppet'
  1. Puppet
  2. PUP-9956

Exec logs output of Sensitive unless and onlyif checks at debug

    XMLWordPrintable

Details

    • Coremunity
    • Platform Core KANBAN
    • Needs Assessment
    • Bug Fix
    • Exec onlyif and unless checks will now have their output redacted if they are marked sensitive.
    • Needs Assessment

    Description

      Puppet Version: 6.7.2
      Puppet Server Version: N/A
      OS Name/Version: macOS 10.14, Ubuntu 18.10

      I have been working on implementing support for Sensitive in a module that contains many execs. When I use Sensitive in the command parameter it redacts the command and does not show any command output in debug mode. However, when I use Sensitive in the unless or onlyif parameters it redacts the command and logs the output at debug.

      This is problematic for me because some of the commands being used in the unless statements are leaking passwords into reports when running in debug.

      I would expect that if I mark a command as Sensitive that I wouldn't get logged output from the command as it would have a higher likelihood of containing sensitive information.

      The following manifest can reproduce the issue:

      # test.pp
      exec { 'Sensitive command':
        command => Sensitive('/bin/echo "secret0"'),
      }
       
      exec { 'Sensitive unless':
        command => '/bin/echo Pass',
        unless  => Sensitive('/bin/echo "secret1"'),
      }
       
      exec { 'Sensitive onlyif':
        command => '/bin/echo Pass',
        onlyif  => Sensitive('/bin/echo "secret2'),
      }
      

       

      When I run puppet apply test.pp --debug I get the following output:

      puppet apply test.pp --debug
      Debug: Runtime environment: puppet_version=6.7.2, ruby_version=2.4.5, run_mode=user, default_encoding=UTF-8
      ...
      Info: Applying configuration version '1565384722'
      Debug: Exec[Sensitive command](provider=posix): Executing '[redacted]'
      Debug: Executing: '[redacted]'
      Notice: /Stage[main]/Main/Exec[Sensitive command]/returns: executed successfully
      Debug: /Stage[main]/Main/Exec[Sensitive command]: The container Class[Main] will propagate my refresh event
      Debug: Exec[Sensitive unless](provider=posix): Executing check '[redacted]'
      Debug: Executing: '[redacted]'
      Debug: /Stage[main]/Main/Exec[Sensitive unless]/unless: secret1
      Debug: /Stage[main]/Main/Exec[Sensitive unless]: '[command redacted]' won't be executed because of failed check 'unless'
      Debug: Exec[Sensitive onlyif](provider=posix): Executing check '[redacted]'
      Debug: Executing: '[redacted]'
      Debug: /Stage[main]/Main/Exec[Sensitive onlyif]/onlyif: secret2
      Debug: Exec[Sensitive onlyif](provider=posix): Executing '[redacted]'
      Debug: Executing: '[redacted]'
      Notice: /Stage[main]/Main/Exec[Sensitive onlyif]/returns: executed successfully
      Debug: /Stage[main]/Main/Exec[Sensitive onlyif]: The container Class[Main] will propagate my refresh event
      Debug: Class[Main]: The container Stage[main] will propagate my refresh event
      Debug: Finishing transaction 70240057109900
      Debug: Storing state
      Debug: Pruned old state cache entries in 0.00 seconds
      Debug: Stored state in 0.01 seconds
      Notice: Applied catalog in 0.07 seconds
      

      It's a bit verbose, but you can see secret1 and secret2 leaked above on the following lines:

      Debug: /Stage[main]/Main/Exec[Sensitive unless]/unless: secret1
      Debug: /Stage[main]/Main/Exec[Sensitive onlyif]/onlyif: secret2
      

      It's worth noting that logoutput does not affect this particular behavior:

      # logoutput.pp
      exec { 'Sensitive unless':
        command => '/bin/true',
        logoutput  => false,
        unless => Sensitive('/bin/echo secret1')
      }
       
      puppet apply --debug logoutput.pp
      ...
      Info: Applying configuration version '1565385531'
      Debug: Exec[Sensitive unless](provider=posix): Executing check '[redacted]'
      Debug: Executing: '[redacted]'
      Debug: /Stage[main]/Main/Exec[Sensitive unless]/unless: secret1
      Debug: /Stage[main]/Main/Exec[Sensitive unless]: '[command redacted]' won't be executed because of failed check 'unless'
      Debug: Finishing transaction 70187444945900
      Debug: Storing state
      Debug: Pruned old state cache entries in 0.00 seconds
      Debug: Stored state in 0.01 seconds
      Notice: Applied catalog in 0.02 seconds
      

      Desired Behavior: When I run code in debug that contains an exec with Sensitive unless/onlyif commands the output of that command should be redacted or not logged.

      Actual Behavior: Sensitive unless/onlyif checks log their output at debug.

      Some minor digging shows the following code in the check methods for unless (in lib/puppet/type/exec.rb):

            # Return true if the command does not return 0.
            def check(value)
              begin
                output, status = provider.run(value, true)
              rescue Timeout::Error
                err _("Check %{value} exceeded timeout") % { value: value.inspect }
                return false
              end
       
              output.split(/\n/).each { |line|
                self.debug(line)
              }
       
              status.exitstatus != 0
            end
          end
      

      The code for onlyif is quite similar. I suspect that this is the code responsible for logging the output in debug mode. A quick git blame shows that the output.split blocks in those methods haven't been touched in a long time and probably got missed in previous passes for Sensitive.

      Attachments

        Activity

          People

            kris.bosland Kris Bosland
            smarlow Steve Marlow
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Zendesk Support