0

I work with a Jenkinsfile that makes Bitbucket REST API calls.

The original version of the Jenkinsfile used a super-user's username:password as the -u argument to curl. E.g.

pipeline {
  agent any
  stages {
    stage( "1" ) {
      steps {
        script {
          def CRED = "super_user:super_password"
          def url = "https://bitbucket.company.com/rest/build-status/1.0/commits"
          def commit = 0000000000000000000000000000000000000001
          def dict = [:]
          dict.state = "INPROGRESS"
          dict.key = "foo_002"
          dict.url = "http://server:8080/blue/organizations/jenkins/job/detail/job/002/pipeline"
          def cmd = "curl " +
                    "-f " +
                    "-L " +
                    "-u ${CRED} " +
                    "-H \\\"Content-Type: application/json\\\" " +
                    "-X POST ${url}/${commit} " +
                    "-d \\\''${JsonOutput.toJson(dict)}'\\\'"
          sh(script: cmd)
        }
      }
    }
  }
}

I don't think that def CRED = "super_user:super_password" is secure -- i.e. the presence of the username/password in plaintext. So I went around trying to find alternatives.

It was recommended to me to use a personal access token (PAT) instead of a username/password.

I recently learned that the PAT is effectively "another password" for an existing user. I.e. if the noted super_user creates a PAT in the Bitbucket web UI -- "00000000000000000000000000000000000000000000" as an example -- then the only change to the above Jenkinsfile is:

def CRED = "super_user:00000000000000000000000000000000000000000000"

Why is this considered any more secure? Isn't the presence of the cleartext super_user:00000000000000000000000000000000000000000000 as much of a security vulnerability as the presence of the cleartext super_user:super_password?

This Bitbucket REST API documentation offers the example of the curl command to invoke the REST API that updates a commit's build status, which is what the above Jenkinsfile implements.

Since invoking the REST API ultimately comes down to a curl command -- i.e. something invoked in a shell prompt, whether by human or Jenkinsfile script -- what are prevailing conventions to secure that username:password/PAT so that it's not cleartext in the Jenkinsfile (or a file read by calling readFile(), etc.)?

StoneThrow
  • 5,314
  • 4
  • 44
  • 86
  • 2
    first, you add the auth into Jenkins Credentials, second refer the credential and mask the password by `MaskPasswordsBuildWrapper`. https://www.jenkins.io/doc/book/using/using-credentials/ – yong Aug 01 '21 at 00:48

1 Answers1

1

You need to use Jenkins credentials store and do not use double quotes for the credentials variable in your curl command to avoid the string interpolation.

pipeline {
agent any
stages {
stage( "1" ) {
  steps {
    script {
     withCredentials([usernamePassword(credentialsId: 'bitBucketCreds', passwordVariable: 'password', usernameVariable: 'username')]) {
      String url = "https://bitbucket.company.com/rest/build-status/1.0/commits"
      String commit = '0000000000000000000000000000000000000001'
      Map dict = [:]
      dict.state = "INPROGRESS"
      dict.key = "foo_002"
      dict.url = "http://server:8080/blue/organizations/jenkins/job/detail/job/002/pipeline"
      List command = []
      command.add("curl -f -L")
      command.add('-u ${username}:${password}')
      command.add("-H \\\"Content-Type: application/json\\\"")
      command.add("-X POST ${url}/${commit}")
      command.add("-d \\\''${JsonOutput.toJson(dict)}'\\\'")
                         
      sh(script: command.join(' '))
     }
    }
   }
  }
 }
}
Ram
  • 1,154
  • 6
  • 22
  • Sorry for slow response - other priorities prevented me from trying this sooner. I think this solution has gotten me _closer_, however the resulting invocation of `sh(script: command.join(' '))` fails because of what I _think_ is faulty string interpolation. I've posted details at the following new question, since it is a slightly different topic -- I wonder if you might have insight what is wrong? https://stackoverflow.com/questions/68764855/jenkinsfile-groovy-why-does-curl-command-result-in-bad-request – StoneThrow Aug 12 '21 at 22:38
  • 1
    It’s an string escape issue. I hope you have already got the answer. – Ram Aug 13 '21 at 04:40
  • Confirmed - yes, it was a string escape issue indeed! I'll update the other post with my findings. – StoneThrow Aug 13 '21 at 12:46