Jenkinsfile:Bitbucket REST API 的明文用户名:密码/PAT 是不是有更安全的替代方案?
Posted
技术标签:
【中文标题】Jenkinsfile:Bitbucket REST API 的明文用户名:密码/PAT 是不是有更安全的替代方案?【英文标题】:Jenkinsfile: Is there a more secure alternative to cleartext username:password/PAT for Bitbucket REST API?Jenkinsfile:Bitbucket REST API 的明文用户名:密码/PAT 是否有更安全的替代方案? 【发布时间】:2021-10-06 19:07:21 【问题描述】:我使用 Jenkinsfile 进行 Bitbucket REST API 调用。
Jenkinsfile 的原始版本使用超级用户的用户名:密码作为 curl 的 -u
参数。例如
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)
我不认为def CRED = "super_user:super_password"
是安全的——即用户名/密码以明文形式存在。所以我四处寻找替代品。
建议我使用个人访问令牌 (PAT) 而不是用户名/密码。
我recently learned 认为 PAT 实际上是现有用户的“另一个密码”。 IE。如果上面提到的super_user
在 Bitbucket Web UI 中创建了一个 PAT——以“00000000000000000000000000000000000000000000”为例——那么对上述 Jenkinsfile 的唯一更改是:
def CRED = "super_user:00000000000000000000000000000000000000000000"
为什么认为这更安全? 明文super_user:00000000000000000000000000000000000000000000
的存在与明文super_user:super_password
的存在不一样是安全漏洞吗?
This Bitbucket REST API documentation 提供了 curl
命令的示例来调用 REST API 来更新提交的构建状态,这是上面的 Jenkinsfile 实现的。
由于调用 REST API 最终归结为 curl
命令——即在 shell 提示符下调用的东西,无论是通过人类还是 Jenkinsfile 脚本——保护用户名:密码/PAT 的流行约定是什么所以它不是 Jenkinsfile 中的明文(或通过调用readFile()
等读取的文件)?
【问题讨论】:
首先,将身份验证添加到 Jenkins Credentials 中,然后参考凭证并通过MaskPasswordsBuildWrapper
屏蔽密码。 jenkins.io/doc/book/using/using-credentials
【参考方案1】:
您需要使用 Jenkins 凭证存储,并且不要在 curl
命令中为凭证变量使用双引号,以避免字符串插值。
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(' '))
【讨论】:
抱歉响应缓慢 - 其他优先事项阻止了我早点尝试。我认为这个解决方案让我更接近,但是由于我认为错误的字符串插值导致sh(script: command.join(' '))
的调用失败。我已经在以下新问题中发布了详细信息,因为它是一个稍微不同的主题——我想知道你是否能洞察出什么是错的? ***.com/questions/68764855/…
这是一个字符串转义问题。我希望你已经得到了答案。
已确认 - 是的,这确实是一个字符串转义问题!我会用我的发现更新另一篇文章。以上是关于Jenkinsfile:Bitbucket REST API 的明文用户名:密码/PAT 是不是有更安全的替代方案?的主要内容,如果未能解决你的问题,请参考以下文章
Jenkinsfile:在 Jenkinsfile 中设置/更新一个全局变量并在构建中使用它
Jenkinsfile/Groovy:为啥 curl 命令会导致“错误请求”
Jenkinsfile,“查找”,忽略一些隐藏目录和其他文件夹
Jenkinsfile。Jenkinsfile: "RejectedAccessException: No such field found" in catch block: No