现象

jenkins pipeline中使用withCredentials来隐藏账密等敏感信息,结果用sh 方法执行命令时又把用户和密码给打印出来了, 简直了😱

原因

官方文档给出的解释1

Groovy string interpolation can leak sensitive environment variables (i.e. credentials, see: Handling credentials). This is because the sensitive environment variable will be interpolated during Groovy evaluation, and the environment variable’s value could be made available earlier than intended, resulting in sensitive data leaking in various contexts.


Should Groovy perform the interpolation, the sensitive value will be injected directly into the arguments of the sh step, which among other issues, means that the literal value will be visible as an argument to the shprocess on the agent in OS process listings. Using single-quotes instead of double-quotes when referencing these sensitive environment variables prevents this type of leaking.

大致意思就是 Groovy字符串插入可能会泄漏含有敏感信息的环境变量, 比如说凭据中的用户密码等信息, 这是因为环境变量将在Groovy求值期间内插入, 并且环境变量的值可能比预期更早可用, 从而导致敏感信息泄露.
当Groovy进行字符串插入操作时, 环境变量的值会直接插入sh的参数中, 在操作系统的进程列表中含有敏感信息的环境变量值将作为sh进程参数明文可见. 预防措施就是在使用这些环境变量时应该使用单引号而不是双引号
文档还给了个错误用法和正确用法的例子

  • 错误用法:

Jenkinsfile (Declarative Pipeline)

pipeline {
    agent any
    environment {
        EXAMPLE_CREDS = credentials('example-credentials-id')
    }
    stages {
        stage('Example') {
            steps {
                /* WRONG! */
                sh("curl -u ${EXAMPLE_CREDS_USR}:${EXAMPLE_CREDS_PSW} https://example.com/")
            }
        }
    }
}

  • 正确用法 :

Jenkinsfile (Declarative Pipeline)

pipeline {
    agent any
    environment {
        EXAMPLE_CREDS = credentials('example-credentials-id')
    }
    stages {
        stage('Example') {
            steps {
                /* CORRECT */
                sh('curl -u $EXAMPLE_CREDS_USR:$EXAMPLE_CREDS_PSW https://example.com/')
            }
        }
    }
}


其他方法

通过set +x可以关闭日志输出避免敏感信息泄露,注意使用的是单引号 2

node {
  withCredentials([usernameColonPassword(credentialsId: 'mylogin', variable: 'USERPASS')]) {
    sh '''
      set +x
      curl -u "$USERPASS" https://private.server/ > output
    '''
  }
}

set -xset +x命令的作用实际是用于输出详细日志,是Shell脚本中使用echo命令输出的替代方案。更适用于输出大量日志的场景使用
set -x 是开启,set +x是关闭,set -o是查看 (xtrace,追踪一段代码的显示情况)

使用双引号时可能会泄露敏感信息, 下面给一个错误的例子

错误用法:

node {
  withCredentials([string(credentialsId: 'mytoken', variable: 'TOKEN')]) {
    sh /* WRONG! */ """
      set +x
      curl -H 'Token: $TOKEN' https://some.api/
    """
  }
}

参考


  1. https://www.jenkins.io/doc/book/pipeline/jenkinsfile/#string-interpolation ↩︎

  2. https://www.jenkins.io/doc/pipeline/steps/credentials-binding ↩︎

Logo

技术共进,成长同行——讯飞AI开发者社区

更多推荐