gpt4 book ai didi

jenkins - 绕过代码中的脚本安全插件

转载 作者:行者123 更新时间:2023-12-03 02:14:41 40 4
gpt4 key购买 nike

我编写了一些在 Jenkins Pipelines 中使用的常规实用方法。一个简单的例子是:

// src/org/package/utils.groovy
def remove_file(String file) {
new File(file).delete()
}

但是,正如预期的那样,这会在 Jenkins Pipeline 中引发以下异常:

org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException: Scripts not permitted to use new java.io.File java.lang.String

根据Script Security Plugin documentation ,我可以使用 @Whitelisted 方法注释绕过这个:

@Whitelisted
def remove_file(String file) {
new File(file).delete()
}

根据这个question ,我可以使用 @NonCPS 注释绕过这个问题(并且此方法中的代码当然不必是可序列化的):

@NonCPS
def remove_file(String file) {
new File(file).delete()
}

共享库正在全局变量中使用,如下所示:

// vars/var.groovy
import org.package.utils

def method(body) {
...
new utils().remove_file('file')
...
}

正在 Jenkinsfile 中导入和使用库/var,如下所示:

library identifier: 'lib@master', retriever: modernSCM(
[$class: 'GitSCMSource',
remote: 'https://github.com/org/repo.git'])

pipeline {
...
script {
var.method {
// body
}
}
...
}

在列出的基于代码的导入 Pipeline 共享库的方法中,我上面使用的方法似乎是唯一真正适用于标准 Jenkins Pipeline 插件集的方法,因此这就是我采用的方法。

这两个都未能绕过 Jenkins Pipeline 抛出的安全异常。使用代码绕过脚本安全插件并避免手动/人为错误解决方案(例如修改 GUI 中的白名单)的最佳解决方案是什么?

最佳答案

根据您最后的评论以及您对原始问题的更新,我想我了解发生了什么。我将尝试澄清全局共享库和“常规”共享库之间的差异。

<小时/>

注册库

(在撰写本文时)有几种不同的方法可以向 Jenkins 实例注册共享库

  1. Globally to the Jenkins installation - 可用于所有管道执行。
  2. For a Folder - 文件夹中的所有项目都有可用的管道库
  3. Automatic libraries - 文档中提供的示例是 GitHub Branch Source Plugin

库注册需要一些设置:

  • Name - 与 library 步骤和 @Library 注释一起使用的库名称
  • 默认版本 - 提交、分支、标签或其他标识符
  • 隐式加载 - 是否应该隐式加载库(即消费者不需要使用 @Librarylibrary)
  • 检索方法 - 如何检索 SCM(如使用 Git 或 Mercurial)
    • 允许覆盖默认版本 - 如果消费者可以使用与默认版本不同的版本

Global Shared Libraries上面提到的绕过安全沙箱,这意味着他们可以做任何事情。这是一些相关的documentation :

Since these libraries will be globally usable, any Pipeline in the system can utilize functionality implemented in these libraries.

These libraries are considered "trusted:" they can run any methods in Java, Groovy, Jenkins internal APIs, Jenkins plugins, or third-party libraries. This allows you to define libraries which encapsulate individually unsafe APIs in a higher-level wrapper safe for use from any Pipeline. Beware that anyone able to push commits to this SCM repository could obtain unlimited access to Jenkins. You need the Overall/RunScripts permission to configure these libraries (normally this will be granted to Jenkins administrators).

这些是唯一绕过安全沙箱检查的管道库。其他类型(例如 Folder 库)经过安全检查,这意味着您无法执行诸如 new File(file).delete() 之类的操作。

<小时/>

消费

在管道中,用户可以访问所有可用的共享库。从安装或文件夹隐式加载的库(上面注明为隐式加载选项)在脚本类路径上自动可用。必须使用 @Library 注释或 library 步骤引入其他库。

例如,假设您有一个包含以下选项的库:

  • 名称 - my-shared-lib
  • 默认版本 - master
  • 隐式加载 - false
  • 检索方法 - 现代 Git SCM 设置到某个存储库
    • 允许覆盖默认版本 - true

从管道中提取此特定库的几种方法是:

  • @Library('my-shared-lib') - 与默认版本一起使用
  • @Library('my-shared-lib@develop') - 与 develop 的覆盖版本一起使用
  • `def myLib = library('my-shared-lib') - 与默认版本一起使用
  • def myLib = library('my-shared-lib@develop') - 与 develop 的重写版本一起使用

这些都将使用之前配置的库。

在您的示例中,您使用的是 library 步骤,但从远程存储库动态加载,而不是使用注册版本。这也是您指定 retriever 参数的原因。请记住,任何不是全局共享库的库都无法绕过安全沙箱

如果您想让您的库绕过沙箱,您需要在 Jenkins 安装中将其注册为全局共享库

关于 new File(file).delete() 的旁注 - 在 Jenkins 管道内编写“正常”Groovy 时要小心(请参阅此 answer 了解一些详细原因)。

关于jenkins - 绕过代码中的脚本安全插件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48170958/

40 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com