Uploaded image for project: 'Jenkins'
  1. Jenkins
  2. JENKINS-43814

Password parameters should be hidden in pipeline logs by default

      In a pipeline script when a developer uses `withCredentials` credentials are hidden in logs to reduces the chance of accidental disclosure (see JENKINS-38181)

      When using a password parameter in a job the same concept should be applied to it and it should be impossible to display its value in logs

      A work-around is to use the MaskPasswordsBuildWrapper but it has to be manually done (and it's a bit crappy)

      node {
        wrap([$class: 'MaskPasswordsBuildWrapper', varPasswordPairs: [[password: "${myPassword}", var: 'PASSWORD']]]) {
         println myPassword
         sh 'echo "Hello World ${myPassword}"'
        }
      }

       

       

      .

          [JENKINS-43814] Password parameters should be hidden in pipeline logs by default

          jglick, abayer I understand your position but what you don't want to understand is that some companies want to have this option by default (and potentially with no possibility to deactivate it) = security first / by default

          Arnaud Héritier added a comment - jglick , abayer  I understand your position but what you don't want to understand is that some companies want to have this option by default (and potentially with no possibility to deactivate it) = security first / by default

          Jesse Glick added a comment -

          do you mean MaskPasswordsBuildWrapper could be replicated in Declarative?

          No, just to have Declarative notice that you have a password parameter and automatically do the boilerplate to mask its value.

          Jesse Glick added a comment - do you mean  MaskPasswordsBuildWrapper  could be replicated in Declarative? No, just to have Declarative notice that you have a password parameter and automatically do the boilerplate to mask its value.

          Jesse Glick added a comment -

          do you mean MaskPasswordsBuildWrapper could be replicated in Declarative?

          No, just to have Declarative notice that you have a password parameter and automatically do the boilerplate to mask its value.

          Jesse Glick added a comment - do you mean  MaskPasswordsBuildWrapper  could be replicated in Declarative? No, just to have Declarative notice that you have a password parameter and automatically do the boilerplate to mask its value.

          Cosmin Stroe added a comment - - edited

          Any reason why the contents of a password parameter aren't automatically filtered out from console logs? That is, is there a technical reason? or is it just that noone's implemented the feature yet?

          Cosmin Stroe added a comment - - edited Any reason why the contents of a password parameter aren't automatically filtered out from console logs? That is, is there a technical reason? or is it just that noone's implemented the feature yet?

          Jesse Glick added a comment -

          No one has implemented such a feature (or proposed a mechanism by which it could be implemented).

          Jesse Glick added a comment - No one has implemented such a feature (or proposed a mechanism by which it could be implemented).

          Jesse Glick added a comment -

          HOSTING-679 claims to implement something like this.

          Jesse Glick added a comment - HOSTING-679 claims to implement something like this.

          Jesse Glick added a comment -

          proposed a mechanism by which it could be implemented

          This is actually possible now via TaskListenerDecorator, I think.

          Jesse Glick added a comment - proposed a mechanism by which it could be implemented This is actually possible now via TaskListenerDecorator , I think.

          Olivier Lamy added a comment -

          Olivier Lamy added a comment - this plugin exists https://github.com/jenkinsci/redacted-password-parameters-plugin

          Jesse Glick added a comment -

          Indeed it looks that way.

          The design of the password parameter type built into core is just not ideal. Just as we needed to create a new plugin to handle file parameters sanely, it may be time for a redesigned password & credentials parameter type aligned with JENKINS-27398 and solving things like JENKINS-36007. For example, submitting a secret to a build (as a parameter, or via input) would cause a StringCredentials to be temporarily available only in that build (or at least job), with the environment variable being set to the (random) id, so if you had a parameter named DEPLOY_KEY you could write something like

          withCredentials([string(credentialsId: DEPLOY_KEY, variable: 'DEPLOY_KEY_VAL')]) {
            sh './deploy --key=$DEPLOY_KEY_VAL'
          }
          

          binding the secret just where you actually need it and getting masking for free; or the credentials could be passed to a step without needing the awkward idiom used by credentials parameters:

          deploy server: '…', credentialsId: DEPLOY_KEY
          

          Ideally you could also pass the secret along to a downstream build with the build step, etc., all without ever having the plaintext be present in logs, build metadata, or the like. (Even exposing a Secret.encryptedValue is not necessarily safe: SECURITY-266.)

          Jesse Glick added a comment - Indeed it looks that way. The design of the password parameter type built into core is just not ideal. Just as we needed to create a new plugin to handle file parameters sanely, it may be time for a redesigned password & credentials parameter type aligned with JENKINS-27398 and solving things like JENKINS-36007 . For example, submitting a secret to a build (as a parameter, or via input ) would cause a StringCredentials to be temporarily available only in that build (or at least job), with the environment variable being set to the (random) id, so if you had a parameter named DEPLOY_KEY you could write something like withCredentials([string(credentialsId: DEPLOY_KEY, variable: 'DEPLOY_KEY_VAL' )]) { sh './deploy --key=$DEPLOY_KEY_VAL' } binding the secret just where you actually need it and getting masking for free; or the credentials could be passed to a step without needing the awkward idiom used by credentials parameters: deploy server: '…' , credentialsId: DEPLOY_KEY Ideally you could also pass the secret along to a downstream build with the build step, etc., all without ever having the plaintext be present in logs, build metadata, or the like. (Even exposing a Secret.encryptedValue is not necessarily safe: SECURITY-266.)

          Matt Sicker added a comment - - edited

          I've been meaning to comment on a cryptographic design for this, but I was refraining until I had a more succinct way to describe it. Then I remembered that GitHub Actions implement this almost exactly the way I'd recommend doing it (but integrated with Jenkins APIs instead):

          Matt Sicker added a comment - - edited I've been meaning to comment on a cryptographic design for this, but I was refraining until I had a more succinct way to describe it. Then I remembered that GitHub Actions implement this almost exactly the way I'd recommend doing it (but integrated with Jenkins APIs instead): https://docs.github.com/en/actions/reference/encrypted-secrets https://libsodium.gitbook.io/doc/public-key_cryptography/sealed_boxes Unfortunately, this is a native library. Looking at their third party bindings, this project looks the most active: https://github.com/muquit/libsodium-jna Alternatively, the algorithms needed to implement this are all in Bouncycastle, but not as a unified API. See https://stackoverflow.com/a/42456750 for a similar glue idea with smaller libraries. Or a sealed box can be created using ECDH, SHA-2, and AES/GCM if FIPS compliance is necessary.

            Unassigned Unassigned
            aheritier Arnaud Héritier
            Votes:
            6 Vote for this issue
            Watchers:
            11 Start watching this issue

              Created:
              Updated: