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

Mask password plugin fails to mask password with $ character in the middle of the password

      Jenkins instance is running on a linux and i use Invoke Ant build step.
      The build job is parameterized and one of the parameter is password
      Ant targets are written in an xml called run.xml so I pass the arg -file run.xml -Dserver.password=apr20$1 to the ant build.

      The password contains $ in the middle - like apr20$1.
      The $ in the password is referenced as $1 command argument and password parameter is now changed to apr20-file ( -file is my first parameter)

      The password is getting logged when i turn on the -d trace in Ant.
      Setting ro property server.password=apr20-file is what i see in the console

      The mask property should somehow try to address masking this information being logged. I have written my own script to introduce escape sequence in the passwords.

          [JENKINS-22770] Mask password plugin fails to mask password with $ character in the middle of the password

          Alex LeDonne added a comment -

          Confirming that password masking fails also if the dollar sign is the last character in the password.

          Alex LeDonne added a comment - Confirming that password masking fails also if the dollar sign is the last character in the password.

          Daniel Beck added a comment -

          The issue description is a bit weird, but it seems to boil down to passwords participating in variable placeholder resolution.

          Usually, you'd escape a dollar char using another dollar char (foo$$bar becomes foo$bar), but that means the raw value does not match the script output, and the password is shown plain.

          Only workaround seems to be to not use passwords that don't contain a dollar char.

          Daniel Beck added a comment - The issue description is a bit weird, but it seems to boil down to passwords participating in variable placeholder resolution. Usually, you'd escape a dollar char using another dollar char ( foo$$bar becomes foo$bar ), but that means the raw value does not match the script output, and the password is shown plain. Only workaround seems to be to not use passwords that don't contain a dollar char.

          Jakub Krysl added a comment -

          This is still an issue in 2022, but only through Groovy.

          Using global credentials and sh step directly (in bash script) correctly masks passwords even with $ sign:

           

          sh "echo ${PASSWORD}"
          

          ->

          echo *****
          *****
          

           

          But using Groovy pipeline leaks part of the password. Using pass=test$pass123%456test:

           

           

          pipeline {
              agent { label '!master' }
              stages {
                  stage('Run python script') {
                      steps {
                          script {
                              withCredentials([string(credentialsId: 'test-secret-pass', variable: 'PASSWORD')]) {
                                  sh "echo ${PASSWORD}"
                              }
                          }
                      }
                  }
              }
          } 

          ->

          echo test%456test
          test%456test 

           

           

          This is because using "" makes Groovy resolve the password string and than it goes to bash which resolves part of the password string as variable, which is empty. Than masking plugin cannot match the string because it is missing the resolved part.

           

          The workaround is to use '' (with "" if there are local variables):

          script {
              def test_var = "x"
              withCredentials([string(credentialsId: 'test-secret-pass', variable: 'PASSWORD')]) {
                  sh 'echo ${PASSWORD}' + " ${test_var}"
              }
          } 

           

          There is quite easy way to fix this: Check the actual string for any $ signs and mask not only the password itself but also string missing $ + alfanumeric chars (greedy). Just make sure the password does not start with $, we don't want to mask everything

           

          Jakub Krysl added a comment - This is still an issue in 2022, but only through Groovy. Using global credentials and sh step directly (in bash script) correctly masks passwords even with $ sign:   sh "echo ${PASSWORD}" -> echo ***** *****   But using Groovy pipeline leaks part of the password. Using pass=test$pass123%456test:     pipeline {     agent { label '!master' }     stages {         stage( 'Run python script' ) {             steps {                 script {                   withCredentials([string(credentialsId: 'test-secret-pass' , variable: 'PASSWORD' )]) {                         sh "echo ${PASSWORD}"                     } } } } } } -> echo test%456test test%456test     This is because using "" makes Groovy resolve the password string and than it goes to bash which resolves part of the password string as variable, which is empty. Than masking plugin cannot match the string because it is missing the resolved part.   The workaround is to use '' (with "" if there are local variables): script { def test_var = "x" withCredentials([string(credentialsId: 'test-secret-pass' , variable: 'PASSWORD' )]) {       sh 'echo ${PASSWORD}' + " ${test_var}" } }   There is quite easy way to fix this: Check the actual string for any $ signs and mask not only the password itself but also string missing $ + alfanumeric chars (greedy). Just make sure the password does not start with $, we don't want to mask everything  

          Daniel Beck added a comment -

          global credentials

          Please note that Mask Passwords and Credentials Plugin are entirely different things. So there's no evidence for your claim of

          only through Groovy


          Anyway, re what you're pointing out, the docs for this are https://www.jenkins.io/doc/book/pipeline/jenkinsfile/#string-interpolation which also point out an injection vulnerability: If someone's able to provide credentials in your double-quoted example, a password of

          "deleting the French language pack lol" ; rm -fr /* ; 

          will cause trouble.

          Daniel Beck added a comment - global credentials Please note that Mask Passwords and Credentials Plugin are entirely different things. So there's no evidence for your claim of only through Groovy Anyway, re what you're pointing out, the docs for this are https://www.jenkins.io/doc/book/pipeline/jenkinsfile/#string-interpolation which also point out an injection vulnerability: If someone's able to provide credentials in your double-quoted example, a password of "deleting the French language pack lol" ; rm -fr /* ; will cause trouble.

          Tony Bridges added a comment -

          Another variation of this issue - if a password contains a character that requires escapement, the mask fails to detect it.   My guess is that the explicit value (with escapement) is being searched for, but the resolved value (without escapement) is what occurs in the output.   
          i.e.  'password&' fails when used on a command line because the '&' is identified as a command operator, and breaks up the processes.   'password^&'  works in the command, but fails to mask, likely because the masker is still expecting to see the caret in the output.   

          Tony Bridges added a comment - Another variation of this issue - if a password contains a character that requires escapement, the mask fails to detect it.   My guess is that the explicit value (with escapement) is being searched for, but the resolved value (without escapement) is what occurs in the output.    i.e.  'password&' fails when used on a command line because the '&' is identified as a command operator, and breaks up the processes.   'password^&'  works in the command, but fails to mask, likely because the masker is still expecting to see the caret in the output.   

            danielpetisme Daniel Petisme
            raghav4192 Raghav Vaidhyanathan
            Votes:
            6 Vote for this issue
            Watchers:
            8 Start watching this issue

              Created:
              Updated: