Runtime.exec() 的安全问题

Posted

技术标签:

【中文标题】Runtime.exec() 的安全问题【英文标题】:Security Concerns with Runtime.exec() 【发布时间】:2012-07-01 08:42:52 【问题描述】:

我正在使用 Runtime.exec() 来运行一个可执行文件。我一直在研究并发现在应用程序中使用它时可能存在安全问题。使用 Runtime.exec() 运行可执行文件时是否存在任何安全问题?

【问题讨论】:

该区域“棘手”。我强烈建议不要将任何不受信任的数据放在命令行上,即使您已尝试“清理”它。 支持安全意识。做得很好。 【参考方案1】:

我能想到的最大的是Command Injection。您想将运行的内容列入白名单,这样某人就无法通过您的 Runtime.exec 运行“rm /”。发生这种情况的方法比您想象的要多。例如,如果“目录”名称作为“foo; rm -r ; ls”传入会怎样。

另一个问题 - 如果这是一个 Web 应用程序 - 是应用程序的权限(因此您的 Runtime.exec() 命令行与访问网页的人所拥有的权限不同。这意味着该人可以删除您的 Tomcat 或将数据插入数据库或...

【讨论】:

嗯,我明白了,这是一个 Web 应用程序,但用户不会输入除目录/文件名之外的任何命令。在这种情况下,我需要清理输入。您知道 Runtime.exec 的任何其他大小安全问题吗?感谢您的信息! 经过更多研究,这似乎是唯一的主要问题。详情请见:***.com/questions/5301485/… 为了更明确,您必须清理文件名。我的文件名可以是“/etc/passwd”或“../../../WEB-INF/web.xml”。 如果它是一个应该已经存在的目录/文件名,您可以先创建一个java.io.File 对象并检查file.exists() 作为您的清理检查的一部分。 @DNA:这还不够。在我的示例中,存在 web.xml 文件,但它不是您希望用户读取/写入/删除的文件。约束将是商业约束。【参考方案2】:

@Jeanne Boyarsky:显然你不能以你提到的方式注入 Runtime.exec(),除非 Runtime.exec() 首先产生一个 shell(Windows 上的 cmd.exe 或 Linux 上的 sh/bash/csh/ksh)运行命令。 Here 是一个很好的链接,可以讨论这个问题。

我写了一个小程序来测试一下。它将命令作为用户输入。因此,如果我输入 'pwd'(Linux 系统),它会将当前目录打印到系统控制台。这非常有效。

但是,如果我尝试运行两个命令,这在 Linux 中是允许的,例如 pwd;id,它会立即抛出异常。抛出的异常如下。

javax.faces.el.E​​valuationException: java.io.IOException: Cannot run program "pwd;ls": error=2, No such file or directory

话虽如此,但在某些情况下这可能是个问题。如果我有一段代码如下:

进程 proc = runtime.exec(cmd);

...用户可以提供 sh -c pwd;id 的输入,从而导致 shell 运行,然后在其中链接命令。

简而言之,如果您能提供帮助,最好不要使用 Runtime.exec()。如果您必须使用它,请确保规范化所有用户输入并仅允许特定字符和命令。

Here 是一本关于如何编写安全代码的好书。

【讨论】:

实际上,恕我直言,“用户可以提供 sh -c pwd;id 的输入”,这并不完全正确。您会看到,runtime.exec() 采用不同的形式,例如 runtime.exec(String cmd)、runtime.exec(String[] cmds) 等。对于第一个,执行 sh -c 和命令真的很困难。但我完全同意您和其他人回答中的其他建议。干杯。

以上是关于Runtime.exec() 的安全问题的主要内容,如果未能解决你的问题,请参考以下文章

使用 Process.runtime.exec 记录到 syslog

调用 Runtime.exec 时捕获标准输出

Runtime.exec()

无法在 Opensuse 上运行 Java Runtime.exec()

Runtime.exec() sucks!!!!

带有 Weka 命令行的 ProcessBuilder/Runtime.exec() 演示特殊行为