Runtime.getRuntime().exec(String[]) 安全性

3

我正在使用Runtime.getRuntime().exec(String[])来运行一些由用户定义的String数组元素的进程。

这个安全吗?或者它会允许向终端注入代码吗?

如果不安全,我该怎么避免代码注入呢?(必须是平台无关的)

5个回答

3

正如我在另一个答案的评论中提到的(也许可以添加我的答案),只要您控制第一个参数,这就应该是安全的。


谢谢您的答复。看起来您是正确的,只要第一个参数受到控制,就应该是安全的。我需要进一步调查这个问题。 - Jose Antonio

2

一般来说,这不安全,因为可以执行可能是恶意的shell脚本。

我建议允许预定义的命令集合,并让用户从中选择一个(带有可选参数,这些参数可能已被转义),而不是完全允许输入命令。


@Thomas 谢谢你的回答。我已经在做类似的事情了。数组的第一个元素总是由我定义的,但我仍然不确定用户是否可以在任何操作系统中执行 ["MyProcess", "expected parameter & rm -Rf *"] 或其他命令。 - Jose Antonio
@Jose - 如果你控制第一个参数并使用String[] exec方法,则应该是安全的(假设你运行的程序不会对其接收到的参数执行任何不安全的操作)。 - jtahlborn
你不能确定任何操作系统,但你可以尝试使用引号来转义参数,例如 expected parameter & rm -Rf * -> "expected parameter & -RF *"(从shell的角度看)。也就是说,使用平台相关的转义表达式替换所有现有的引号,然后再用额外的引号包装参数。转义可能与平台有关,但如果你为最常见的平台添加支持,应该就没问题了。 - Thomas
你并不确切知道特定JVM实现如何实际调用进程。但是你是正确的,通常shell不用于执行命令,也不应该让用户选择实际命令作为参数。另外,你可以重写SecurityManager#checkExec()来只允许一组特定的命令被执行。 - Thomas
@jtahlborn 很不幸,我不知道它是如何工作的,它不允许用户使用像"&"这样的命令吗?我正在进行一些测试,似乎不允许,但我相信用户比我更有想象力。例如,它似乎允许每个数组元素有多个参数,我无法想象恶意用户可以做什么... - Jose Antonio
显示剩余3条评论

2

谢谢你的回答。这很有趣,我需要更深入地研究一下。我已经在不同的线程中执行命令,但这个解决方案值得探究。谢谢。 - Jose Antonio

1

我认为在这种情况下,安全性是由底层操作系统访问控制定义的。如果您正在使用unix并将脚本作为受限用户运行,则应该没有问题。只要访问控制被正确定义并且脚本以具有正确权限的用户身份运行,那么就没问题了。(但是是什么用例促使您编写这样的程序呢。)


谢谢你的回答。我正在使用Unix测试项目,但当我的部分完成后,它将不在我的掌控之中,因此它可以在Windows或其他操作系统上部署。我无法控制它是否会正确地部署并获得正确的权限,这就是我担心的。如果我能够控制从我的代码中进行的代码注入,我会更加放心。 - Jose Antonio

1
所有这些评论似乎都忽略了一个重要事实。命令注入只是使用带有exec的用户定义参数可能面临的危险之一。另一个可能的攻击是参数注入。您需要了解用户调用的命令的所有可能参数。

find命令是一个危险的例子。用户可以添加选项-exec作为参数来获得任意命令执行能力。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接