脚本安全

ID:script-security

必威国际有限公司Jenkins插件更改兴必威国际有限公司詹金斯插件安装

用户指导

(改编自信息CloudBees插件指南中的模板插件

各种Jenkin必威国际有限公司s插件要求用户定义自定义脚本,最常见于Groovy语言,以自定义Jenkins的行为。如果为这些脚本写的每个人都是Jenkins管理员 - 特别是如果它们具有总体/ ru必威国际有限公司nscripts权限,例如由脚本控制台链接 - 那么他们可以编写他们喜欢的任何脚本。这些脚本可以使用提供给插件的相同API直接引用内部Jenkins对象。必威国际有限公司必须完全信任此类用户,因为它们可以对Jenkins进行任何操作(甚至更改其安全设置或在服务器上运行shell命令)。必威国际有限公司

但是,如果某些脚本作者是“常规用户”,则只有更多有限的权限,例如作业/配置,则不合适地让它们运行任意脚本。为了支持这样的角色划分,脚本安全库插件可以集成到各种功能插件中。它支持两个相关系统:脚本批准和Groovy Sandboxing。

脚本的批准

第一个和更简单的安全系统是允许运行任何类型的脚本,而只使用管理员的批准。全局维护的批准脚本列表,该脚本被判断为不执行任何恶意操作。

当管理员保存某种类型的配置(例如,一个作业)时,它包含的任何脚本都会自动添加到批准的列表中。他们已经准备好在没有进一步干预的情况下运行了。(“保存”通常意味着从web UI,但也可能意味着通过REST或CLI上传新的XML配置。)

当非管理员保存模板配置时,将检查是否从已批准的文本中编辑了任何包含的脚本。(更准确地说,是指请求的内容以前是否被批准过。)如果该脚本没有被批准,则将此脚本的批准请求添加到队列中。(当脚本的当前文本当前未被批准时,配置屏幕UI中也会显示一个警告。)

管理员现在可以转到管理Jenki必威国际有限公司ns»过程脚本批准将显示批准批准的脚本列表。假设正在要求任何危险的危险,只需单击“批准”以使脚本运行于此。

如果您尝试运行未经批准的脚本,它将简单地失败,通常使用邮件解释它正在审批批准。一旦脚本获得批准,您可能会重试。此行为的细节可能根据集成此库的特征插件而有所不同。

Groovy沙盒

在跨时区的团队中或在紧迫的截止日期中,等待管理员批准对脚本的每一个更改,无论看起来多么微不足道,都是不可接受的。作为另一种选择,脚本安全系统允许Groovy脚本在未经批准的情况下运行,只要它们将自己限制在被认为天生安全的操作中。这种有限的执行环境称为沙箱。(目前还没有其他语言的沙箱实现,所以如果由非管理员配置,所有这样的脚本都必须得到批准。)

要切换到此模式,只需选中“在Groovy脚本的输入”字段下方的框使用Groovy Sandbox。沙箱脚本可以立即运行任何人。(甚至是管理员,虽然脚本符合相同的限制,但无论谁写道。)运行脚本时,将针对批准操作的白名单检查每个方法调用,对象构造和现场访问。如果尝试过帐未批准的操作,则丢包脚本,尚未使用相应的Jenkins功能。必威国际有限公司

具有小默认白名单和集成插件的脚本安全插件船舶可以将操作添加到该列表(通常是特定于该插件的方法)。

但是您不仅限于默认白名单:每次脚本在运行尚未白名单的操作之前失败,那么该操作会自动添加到另一个批准队列中。管理员可以转到上面描述的页面以获取整个脚本的批准,并查看未决操作批准的列表。如果在签名签名旁边单击批准,则立即添加到白名单中并可用于沙箱脚本。

大多数签名都是这种形式的方法class.name methodname arg1type arg2type ...,指示具有特定的“接收器”类(此),方法名称和参数(或参数)类型列表的Java方法调用。(尝试的方法调用的最常见签名都将提供批准,即使是要调用的实际对象是一种更具体的类型,也可以覆盖该方法。)您也可能看staticMethod对于静态(类)方法,新的对于构造函数,和场地用于现场访问(获取或设置)。

安全敏感环境中的管理员应仔细考虑对白名单的操作。通常应该拒绝持久对象(例如Jenkins作业)的操作。必威国际有限公司最多getSomething方法是无害的。

ACL感知方法

然而,请注意,即使某些“getter”方法旨在检查特定权限(使用ACL:访问控制列表),而脚本通常由系统伪用户运行,以授予所有权限的伪用户。例如,方法Hudson.model.AbstractItem GetParent.(获得包含作业的文件夹或jenkins根目录本身是无害的,必威国际有限公司而是可能的后续电话方法hudson.model.ItemGroup getItems(按文件夹中的名称列出作业)检查作业/读取。第二个呼叫对白名单无条件危险,因为它意味着在文件夹中授予作业/创建的用户将能够从该文件夹中的任何作业中读取一些信息,即使是那些应该隐藏的作业根据基于项目的授权策略;在包含这样的文件夹中创建作业就是足够的作业(详细信息将根据集成插件而变化):

println(“我闻$ {thisjob.getParent () .getItems()} !”);

运行时,脚本输出至少将显示备注秘密项目的名称。反而可以单击Applove假设权限检查GetItems.;这将允许作为实际用户运行调用(如果集成插件曾经这样做),而禁止作为系统用户运行调用(这是更典型的)。在这种情况下,GetItems.实际上实施了返回当前用户可以访问的那些作业,因此如果在前案例中运行(作为特定用户),则描述将显示他们可以看到的那些工作。此更高级按钮仅显示用于方法调用(和构造函数),并且应仅在您知道Jenkins正在进行权限检查时使用。必威国际有限公司

开发人员指南

完成示例集成

简单的方法

对于典型的Groovy Integration,其中您提供用户选择使用脚本批准或沙箱的选项,将可将其描述的字符串值脚本字段更改为SecureGROovyScript字段。在您的构造函数中,在存储值之前,请致电complyingwithkeyItem.(如果每个顶级项目只能有一个这样的脚本)或配置WithNonkeyItem(如果可能有几个)。配置表格应使用< f:属性字段= "…" / >获取脚本和沙箱配置。当您想要运行脚本时,只需调用评估。

(为了与旧数据的兼容性,选择不同的字段名称并弃用原始字段。然后,您可以定义一个readResolve方法,将新字段设置为SecureGROovyScript,与沙箱关闭,呼叫配置(ApprovalContext.create ())以通知系统一个未经批准的脚本已被加载,并取消旧字段。)

艰难的方式

如果您需要更多的控制,则使用比SecureGroovyScript提供更多:

将布尔沙盒字段介绍到配置中。

未设置后,您需要打电话ScriptApproval.configuring在里面@DataBoundConstructor.用approvercontext.withcurrentuser.,并且有钱适用的(每份工作只有一个脚本);否则至少在适用的地方和/或with当您可以从上下文中唯一地标识此用法时(staplerrequest.findancestorobject.是有益的。这让系统知道某个特定的人(可能)配置了一个新脚本。你还需要一个readResolve该调用配置以从磁盘加载可配置脚本的配置以通知系统(因此配置程序未知)。称呼scriptaproval.using.运行脚本并捕获UnapprovedUsageException如有必要。描述符应在脚本字段上使用表单验证并调用scriptapproval.Checking.(一般来说,你的描述符应该已经在这个字段上做了至少一次语法检查)。

设置沙箱字段时,您需要使用Groovy Shell设置GroovySandbox.createSecureCompilerConfiguration然后调用groovysandbox.run.;准备抓住RejectedAccessException并打电话scriptaproval.accessrejected.

适用于沙箱的方法

为了追加一些特定的方法调用,只需用@Whitelist注释它们(如果在您的插件中)将它们注释;否则你可以注册(与@延期)一个ProxyWhitelist委托给StaticWhitelist.from并加载一个列出白名单方法的文本文件。

评估脚本的类路径

在构建GroovyShell时评估脚本或呼叫EcuregroovyScript.evaluate.,你必须通过一个ClassLoader.它表示脚本的有效类路径。你可以使用Jenkins core的加载器,或者你的插件必威国际有限公司,或者必威国际有限公司.uberClassLoader .getPluginManager Jenkins.getInstance () ()

无论您选择什么,都不要允许无特权用户通过创建UrlclassLoader.!这使得在使用沙箱时绕过所有安全措施变得很简单。(用户只需要将这个或另一个作业归档为一个包含带有静态方法标记的类的JAR@whitelisted.做他们想做的任何事情,然后从他们的脚本调用方法。)在使用整个脚本approval-a时,还没有演示过任何攻击UrlclassLoader.常规父母 - 首先代表团不会允许通过受损的版本允许无辜的APIS琐碎的屏蔽 - 但很可能会巧妙地使用Meta-Inf / Services / Org.Codehaus.groovy.Transform.AstRansformation或类似可能导致其他安全脚本以意外和未经授权的方式行事。必威国际有限公司詹金斯- 22834建议安全的标准替代品。

单元测试

当使用脚本的插件写入测试时,您可能会在测试中遇到一些错误。

如果您的测试,直接或间接地呼叫scriptapproval.get()方法,则单元测试必须使用JenkinsRule,以便必威国际有限公司必威国际有限公司Jenkins.getInstance ()不返回null。如果您没有使用沙箱,现在正在工作的测试很可能会开始失败。这是因为他们正在排队等待批准。如果您需要执行脚本而不考虑批准,scriptapproval.get()。propprove(脚本,groovylanguage.get())将确保所有配置的脚本都得到批准。或者,您可以使用沙箱让您的测试运行脚本。在这种情况下,您可能需要为测试使用的方法设置白名单——通常是针对实际用户,或者使用@Testextension.有一个白名单只是为了测试。

版本历史记录

看到变更乐