Jenkins Pipeline中Groovy工具类如何通过代码绕过Script Security插件限制?
首先得明确:你之前尝试的@Whitelisted和@NonCPS没生效的原因很关键——这两个注解并不能绕过沙箱对方法内部调用未授权Java API的限制。@Whitelisted是用来让你的工具方法能被其他脚本调用,但方法里的new File(file).delete()属于直接调用Java的java.io.File类,这是沙箱默认禁止的;@NonCPS只是避免CPS序列化,不影响沙箱的权限检查。
下面是无需手动GUI配置白名单、纯代码层面的最佳解决方案:
方案1:使用Pipeline内置的安全文件操作步骤
Jenkins的Pipeline Utility Steps插件(属于标准插件集,你提到的"标准插件集"应该包含它)提供了deleteFile步骤,这是沙箱完全允许的官方方法,直接替代你自己的remove_file实现:
修改你的共享库工具类:
// src/org/package/utils.groovy def remove_file(String file) { // 直接调用Pipeline内置的deleteFile步骤 deleteFile file: file }
或者在全局变量里直接使用:
// vars/var.groovy import org.package.utils def method(body) { // ... deleteFile file: 'file' // ... }
这个方案是最推荐的,因为它完全符合Jenkins Pipeline的安全规范,不需要任何额外配置。
方案2:使用系统命令跨平台删除文件
如果因为某些原因无法使用Pipeline Utility Steps插件,可以通过执行系统命令来删除文件,这也是沙箱允许的:
// src/org/package/utils.groovy def remove_file(String file) { // 判断当前操作系统,执行对应命令 if (isUnix()) { sh "rm -f '${file}'" } else { bat "del /f \"${file}\"" } }
注意:给文件名加上引号是为了兼容包含空格或特殊字符的场景,避免命令执行出错。
方案3:使用FileOperations插件的批量文件操作
如果你需要更复杂的文件操作(比如删除多个文件、匹配通配符),可以使用File Operations插件提供的deleteFileOperation步骤,这个插件也是常用的标准插件之一:
// src/org/package/utils.groovy def remove_file(String file) { fileOperations([ deleteFileOperation( includes: file, failIfNotFound: false // 如果文件不存在不报错,可选配置 ) ]) }
为什么不推荐继续用Java File API?
如果一定要坚持用java.io.File,唯一的代码层面绕开方式是使用Approval Scripts,但这需要在共享库中定义全局批准脚本,且首次运行时仍需手动批准一次(后续可自动),不符合你"无需手动操作"的要求。所以更建议采用上面的官方安全步骤。
内容的提问来源于stack exchange,提问作者Matthew Schuchard

