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

Special characters in password are not escaped properly in git plugin's withCredentials

    XMLWordPrintable

Details

    • Bug
    • Status: Open (View Workflow)
    • Minor
    • Resolution: Unresolved
    • git-client-plugin
    • None
    • Jenkins: 2.46.3
      git-client-plugin: 2.4.6

    Description

      When using a username/password credential with the git plugin on an agent where /bin/sh is dash, and either the username or the password contains echo special characters sequences (see below), those character sequences are interpreted by the echo command used to pass the credentials to git. For example, given a password of anExampleWithA\newline the password output will actually be:

      anExampleWithA
      ewline

      The character sequences that need to be escaped are:

      \b A backspace character is output.
      \c Subsequent output is suppressed. This is normally used at the end of the last argument to suppress the trailing newline that echo would otherwise output.
      \f Output a form feed.
      \n Output a newline character.
      \r Output a carriage return.
      \t Output a (horizontal) tab character.
      \v Output a vertical tab.
      \0digits
      Output the character whose value is given by zero to three octal digits. If there are zero digits, a nul character is output.
      \\ Output a backslash.

      The issue can be worked around by changing /bin/sh on the executing agents to a shell that does not do character sequence interpretation by default (e.g. bash).

      Attachments

        Activity

          danielbeck Daniel Beck added a comment - - edited

          It would seem password string in credentials after ";" is running as shell command as jenkins user arbitrarily.

          Never double-quote arguments to sh unless you intend to have this behavior. The command interpreter cannot distinguish ; in the script from ; in variables if Pipeline/Groovy is doing the interpolation and the variables are never seen by the command interpreter.

          Documentation: https://www.jenkins.io/doc/book/pipeline/jenkinsfile/#injection-via-interpolation

          security risks of echoing partial passwords in plain text

          While Credentials Plugin has a fairly flexible masking rule taking care of the common shells' accidental output, there are limits to what can be identified as a secret to be masked. Just skip the punctuation and add a few more chars.

          GitHub and GitLab similarly tell you to keep your passwords simple if you want masking/redaction to be successful.

          Will just leave it here https://gist.github.com/Faheetah/e11bd0315c34ed32e681616e41279ef4

          Specifically regarding lines 15-16, use https://www.jenkins.io/doc/pipeline/steps/workflow-basic-steps/#withenv-set-environment-variables

          withEnv(["foo=$foo"]) {
            sh 'echo $foo'
          } 

          looks a bit silly, but it works.

          danielbeck Daniel Beck added a comment - - edited It would seem password string in credentials after ";" is running as shell command as jenkins user arbitrarily. Never double-quote arguments to sh unless you intend to have this behavior. The command interpreter cannot distinguish ; in the script from ; in variables if Pipeline/Groovy is doing the interpolation and the variables are never seen by the command interpreter. Documentation: https://www.jenkins.io/doc/book/pipeline/jenkinsfile/#injection-via-interpolation security risks of echoing partial passwords in plain text While Credentials Plugin has a fairly flexible masking rule taking care of the common shells' accidental output, there are limits to what can be identified as a secret to be masked. Just skip the punctuation and add a few more chars. GitHub and GitLab similarly tell you to keep your passwords simple if you want masking/redaction to be successful. Will just leave it here https://gist.github.com/Faheetah/e11bd0315c34ed32e681616e41279ef4 Specifically regarding lines 15-16, use https://www.jenkins.io/doc/pipeline/steps/workflow-basic-steps/#withenv-set-environment-variables withEnv(["foo=$foo"]) { sh 'echo $foo' } looks a bit silly, but it works.
          robross0606 rross added a comment - - edited

          Agreed yechenqiao, at this point it is more than just a minor annoyance. We're now into the security risks of echoing partial passwords in plain text and potential arbitrary command injection.

          robross0606 rross added a comment - - edited Agreed yechenqiao , at this point it is more than just a minor annoyance. We're now into the security risks of echoing partial passwords in plain text and potential arbitrary command injection.
          yechenqiao Yechen Qiao added a comment - - edited

          The character ";" (semicolon) also needs to be escaped.

           

          If your password is of the form "a;b"

          Then you will get the following error
          + git push origin --tags
          ****: 3: b: not found
          error: unable to read askpass response from ****
          fatal: could not read Password for '*****': terminal prompts disabled

           

          EDIT: I would also raise this concern that this may be viewed a security issue. 

          It would seem password string in credentials after ";" is running as shell command as jenkins user arbitrarily.

          yechenqiao Yechen Qiao added a comment - - edited The character ";" (semicolon) also needs to be escaped.   If your password is of the form "a;b" Then you will get the following error + git push origin --tags ****: 3: b: not found error: unable to read askpass response from **** fatal: could not read Password for '*****': terminal prompts disabled   EDIT: I would also raise this concern that this may be viewed a security issue.  It would seem password string in credentials after ";" is running as shell command as jenkins user arbitrarily.
          markewaite Mark Waite added a comment -

          I've confirmed that the "Use secret text(s)" in Freestyle jobs will not accept a password with a single quote character. Using the checkout scm or git steps in Pipeline work with a credential that contains a single quote character.

          I don't plan to work on this issue in the near future. You'll need to change the password to not use an embedded single quote or use a different method to pass the credentials to command line git.

          markewaite Mark Waite added a comment - I've confirmed that the "Use secret text(s)" in Freestyle jobs will not accept a password with a single quote character. Using the checkout scm or git steps in Pipeline work with a credential that contains a single quote character. I don't plan to work on this issue in the near future. You'll need to change the password to not use an embedded single quote or use a different method to pass the credentials to command line git.
          robross0606 rross added a comment - - edited

          I am having this issue with the most recent version of git and credential-helper plugins and a password that contains a single quote ('). If we set up the username/password credentials in Jenkins and then use them like this:

            withCredentials([gitUsernamePassword(credentialsId: 'dee304ba-153c-4a5f-b232-4baf326ac14f')]) {
              sh("""
                  git branch -u origin/${GIT_BRANCH}
                  git push origin :refs/tags/${tag}
                  git tag ${gitTagAnnotation} ${tag}
                  git push origin ${tag}
              """)
            }
          

          We get the following error:

          [Pipeline] echo
          [2022-01-31T22:11:19.820Z] Pushing git tag 'v0.1.1' to origin...
          [Pipeline] withCredentials
          [2022-01-31T22:11:19.835Z]  > git --version # timeout=10
          [2022-01-31T22:11:19.841Z]  > git --version # 'git version 2.18.5'
          [2022-01-31T22:11:19.842Z] Masking supported pattern matches of $GIT_ASKPASS
          [Pipeline] {
          [Pipeline] sh
          [2022-01-31T22:11:20.135Z] + git branch -u origin/master
          [2022-01-31T22:11:20.135Z] Branch 'master' set up to track remote branch 'master' from 'origin'.
          [2022-01-31T22:11:20.135Z] + git push origin :refs/tags/v0.1.1
          [2022-01-31T22:11:20.135Z] ****: line 3: unexpected EOF while looking for matching `''
          [2022-01-31T22:11:20.135Z] ****: line 5: syntax error: unexpected end of file
          [2022-01-31T22:11:20.135Z] error: unable to read askpass response from ****
          [2022-01-31T22:11:20.135Z] fatal: could not read Username for 'https://my.server.com': terminal prompts disabled
          [Pipeline] }
          [Pipeline] // withCredentials
          [Pipeline] }
          [Pipeline] // script
          [Pipeline] }
          
          robross0606 rross added a comment - - edited I am having this issue with the most recent version of git and credential-helper plugins and a password that contains a single quote ( ' ). If we set up the username/password credentials in Jenkins and then use them like this: withCredentials([gitUsernamePassword(credentialsId: 'dee304ba-153c-4a5f-b232-4baf326ac14f' )]) { sh(""" git branch -u origin/${GIT_BRANCH} git push origin :refs/tags/${tag} git tag ${gitTagAnnotation} ${tag} git push origin ${tag} """) } We get the following error: [Pipeline] echo [2022-01-31T22:11:19.820Z] Pushing git tag 'v0.1.1' to origin... [Pipeline] withCredentials [2022-01-31T22:11:19.835Z] > git --version # timeout=10 [2022-01-31T22:11:19.841Z] > git --version # 'git version 2.18.5' [2022-01-31T22:11:19.842Z] Masking supported pattern matches of $GIT_ASKPASS [Pipeline] { [Pipeline] sh [2022-01-31T22:11:20.135Z] + git branch -u origin/master [2022-01-31T22:11:20.135Z] Branch 'master' set up to track remote branch 'master' from 'origin'. [2022-01-31T22:11:20.135Z] + git push origin :refs/tags/v0.1.1 [2022-01-31T22:11:20.135Z] ****: line 3: unexpected EOF while looking for matching `'' [2022-01-31T22:11:20.135Z] ****: line 5: syntax error: unexpected end of file [2022-01-31T22:11:20.135Z] error: unable to read askpass response from **** [2022-01-31T22:11:20.135Z] fatal: could not read Username for 'https://my.server.com': terminal prompts disabled [Pipeline] } [Pipeline] // withCredentials [Pipeline] } [Pipeline] // script [Pipeline] }

          People

            Unassigned Unassigned
            greg_symons Gregory Symons
            Votes:
            3 Vote for this issue
            Watchers:
            10 Start watching this issue

            Dates

              Created:
              Updated: