如何避免 Jenkins shell 调用中的代码注入?

发布于 2025-01-16 21:00:14 字数 960 浏览 3 评论 0原文

考虑以下代码,它使用一些参数调用程序 (echo):

String malicious_input = '""; rm -rf / #yikes'
sh "echo Hello ${malicious_input}!"

生成的 shell 脚本是

echo Hello ""; rm -rf / #yikes!

简单、经典的代码注入。没有什么闻所未闻的。我一直在努力寻找妥善处理此案的方法。解决此问题的第一种方法是:

  • 只需在 shell 调用中的字符串周围添加单引号,例如 sh "echo Hello '${malicious_input}'!"。是的,但不是,我只需要切换到 malicious_input = "'; rm -rf / #yikes" 即可避免这种情况。
  • 那么只需添加双引号即可!仍然不,这些不仅很容易规避,而且甚至容易发生路径通配/扩展。
  • 然后在调用 Groovy 字符串插值之前在输入字符串周围添加引号。同样的事情,shell 命令行没有改变。
  • 然后,添加单引号,但在字符串内的每个单引号前面加上反斜杠,以防止 shell 将其解释为元字符。是的,如果我也用第二个反斜杠来转义每个现有的反斜杠,那么这种方法就有效。尽管如此,如何防止这种扩展的细节在一定程度上取决于 shell(POSIX-ish、Windows bat,不确定 powershell)。此外,每个参数都需要三行代码。另外,如果没有明确的 shebang 行,我什至无法确定使用的是哪个 shell。

所以,我的问题是:Groovy 中以可移植、与 shell 无关的方式为我执行此操作的内置函数在哪里?我很难相信这不存在,但我找不到它。另外,我是第一个遇到这个问题的人,这让我很困惑......

Consider the following code, which invokes a program (echo) with some arguments:

String malicious_input = '""; rm -rf / #yikes'
sh "echo Hello ${malicious_input}!"

The resulting shell script is then

echo Hello ""; rm -rf / #yikes!

Simple, classic code injection. Nothing unheard. What I have been struggling to find is a way to properly handle this case. First approaches to fix this are:

  • Just add single quotes around the string in the shell call, like sh "echo Hello '${malicious_input}'!". Yes, but no, I only need to switch to malicious_input = "'; rm -rf / #yikes" to circumvent that.
  • Just add double quotes then! Still no, not only are these just as simple to circumvent but those are even prone to path globbing/expansion.
  • Then add the quotes around the input string before invoking Groovy string interpolation. Same thing, the shell commandline is unchanged.
  • Then, add single quotes but prefix every single quote inside the string with a backslash to prevent its interpretation as meta character by the shell. Yes, that kind-of works, if I also escape every existing backslash with a second one. Still, the details of how to prevent this expansion depend a bit on the shell (POSIX-ish, Windows bat, not sure about powershell). Also, this takes three lines of code for every argument. Plus, without an explicit shebang line, I can't even be sure which shell is taken.

So, my question is this: Where is the built-in function in Groovy that does this for me in a portable, shell-agnostic way? I find it hard to believe that this doesn't exist, yet I can't find it. Also, quite puzzling for me that I'm the first one to come across this issue...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

又爬满兰若 2025-01-23 21:00:14

您所描述的称为参数注入,引用为CWE-88 是命令注入的子类,引用为 CWE-77

这些 CWE 中描述的一些潜在缓解措施包括:

  • 如果可能,请使用库调用而不是外部进程来重新创建所需的功能。
  • (参数化)尽可能避免构建包含命令及其参数的单个字符串。
  • (输入验证)假设所有输入都是恶意的。使用“接受已知良好”的输入验证策略,即使用严格符合规范的可接受输入列表。拒绝任何不严格符合规范的输入,或将其转换为严格符合规范的内容。

你的问题的答案:

Groovy 中以可移植、与 shell 无关的方式为我执行此操作的内置函数在哪里?

是: 没有这样的内置 Groovy 函数。

您应该做的是:

  1. 尽可能避免使用带有用户输入数据的 shell 脚本,而改用 Groovy 函数。
  2. 通过仅允许字母数字字符来使用输入验证。
  3. 使用如何防止通过命令选项进行命令注入? 。这是不太安全的选项,因为 sh Jenkins 命令使用系统默认 shell(可以是任何东西),并且不能 100% 保证不存在绕过此引用的技巧。

What you are describing is called Argument Injection referenced as CWE-88 which is a subclass of Command Injection referenced as CWE-77:

Some potential mitigations described in these CWEs are:

  • If at all possible, use library calls rather than external processes to recreate the desired functionality.
  • (Parameterization) Where possible, avoid building a single string that contains the command and its arguments.
  • (Input Validation) Assume all input is malicious. Use an "accept known good" input validation strategy, i.e., use a list of acceptable inputs that strictly conform to specifications. Reject any input that does not strictly conform to specifications, or transform it into something that does.

The answer to your question:

Where is the built-in function in Groovy that does this for me in a portable, shell-agnostic way?

is : there is no such built-in Groovy function.

What you should do is:

  1. Avoid, when possible, using shell scripts with user input data and use instead Groovy functions.
  2. Use input validation by allowing only alphanumerical characters.
  3. Use quoting as discussed in How to prevent command injection through command options?. This is the less safe option, because the sh Jenkins command use the the system default shell (which can be anything) and there is no 100% guarantee that there is no tricks to bypass this quoting.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文