在Java中如何转义Shell命令?

19

我有一个Web服务,可以接收来自经过身份验证的计算机发送的XML输入(这是用于我正在将其集成到其他软件中的网络管理系统),并使用一些XML数据作为参数执行shell脚本。

在Java(/Linux)中,如何最好地转义Shell命令以确保没有人可以向我的Web服务传递恶意参数?

基本上,在一个极其简化的示例中,我通过WS获取了一些输入。

<foo>
<bar>ABCDEF</bar>
</foo>

then running somescript.pl <<data in <bar> field>> here

我需要确保这不能被用于执行任意的shell命令等。

谢谢!


哪个 Shell?不同的 Shell 有不同的转义约定。 - Mike Samuel
1
问题说明是在Linux上使用Java。 - Jesse Webb
1
@Gweebz,这并没有回答“哪个shell?”的问题。Linux有许多不同的shell。 - Kaj
公平的问题,我想这并不重要!我将调查ProcessBuilder,并查看它是否可以更安全地处理数据。如果必须指定,我猜我通常在这些情况下使用bash! - Yablargo
3个回答

15

我建议使用ProcessBuilder或者Runtime.exec方法之一,它们不会通过shell运行,因此不需要进行shell转义以避免注入攻击(这里)。

考虑使用进程的STDIN管道传输XML数据也可能是有益的--Perl可以轻松处理从STDIN读取的数据。通常存在命令行参数的限制。

祝编码愉快。


1
真的是一个明智的回答。如果你之前没有写过,我会逐字逐句地写下去。+1 - gd1

3

如果代码使用ProcessBuilder和Runtime#exec显式地执行命令解释器,这可能会很有用。Java文档似乎并没有强调现有的shell转义安全性,但其他来源指出Java不会隐式地调用任何解释器。 - eel ghEEz
阅读IDS07-J和David Svoboda的评论后,似乎通过rt.exec()在POSIX中执行字符串将失败,如果该字符串与文件名不匹配。数组参数原型将直接转换为数组参数POSIX exec()调用,当执行sh或其他shell时可能会出现问题。在Windows上使用rt.exec()会冒着C运行时将“固定”参数解析为意外多个参数的风险,但这取决于字符串开头是否有cmd - eel ghEEz

3

谢谢。使用旧项目时,我花了一些时间才意识到这之前在commons.lang3中,现在已被commons.text取代。escapeXSI不是commons.lang3版本的一部分,想提醒其他人。 :) - tresf

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