apache commons CommandLine 对象是否可以防止命令行注入?
我想使用 org.apache.commons.exec Java 库来调用可执行文件。 CommandLine
对象防止命令行注入?例如,如果我调用:
String singleStringArgument = "-whatever;rm -rf ~/*"; // evil looking argument!
CommandLine cl = new CommandLine(new File(pathToExe,exeName));
cl.addArgument(singleStringArgument); // oh no!
Executor exe = new DefaultExecutor();
exe.execute(cl);
除了预期的命令之外,还会运行 rm -rf ~/* 吗?如果确实如此,防止这种情况的最佳方法是什么?
API 说 addArgument()
“处理引用”,但我不确定这在这种情况下意味着什么。我可以编写一个测试用例来看看我的 Linux 机器上会发生什么,但我想确保它在其他平台上也是安全的。
I want to use the org.apache.commons.exec
Java library to call an executable. Does the CommandLine
object protect against command line injection? For example, if I call:
String singleStringArgument = "-whatever;rm -rf ~/*"; // evil looking argument!
CommandLine cl = new CommandLine(new File(pathToExe,exeName));
cl.addArgument(singleStringArgument); // oh no!
Executor exe = new DefaultExecutor();
exe.execute(cl);
would rm -rf ~/*
also run in addition to the intended command? If it does, what is the best way to protect against this?
The API says addArgument()
"handles quoting" but I'm not sure what that means in this context. I could whip up a test case to see what happens on my linux box, but I want to be sure that it's safe on other platforms too.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
;
是 shell 的一项功能。如果您没有围绕sh -c
或类似的东西创建命令行,则无法注入。这并不是说公共资源是安全的,而是你甚至没有运行带有漏洞的程序。Commons CLI 正在包装 Process 类。没有记录 Process 类来启动 shell。据记录,它可以使用您告诉它的指定参数执行
exec
。根据评论,开源的奇迹之一是您可以阅读源代码。如果 commons-CLI 版本 X 可以满足您的需求,请依赖它,并且在未重新检查的情况下不要升级。
;
is a feature of the shell. If you don't create a command line aroundsh -c
or something like it, you can't get injected into. It's not that commons is safe, its that you aren't even running the program with the vunerability.Commons CLI is wrapping the Process class. The Process class is not documented to fire up the shell. It is documented to do an
exec
with specified arguments of what you tell it to.As per a comment, one of the wonders of open source is that you can read the source. If version X of commons-CLI does what you like, depend on it, and don't upgrade without rechecking.
那么您控制命令 (pathToExe) 并且只担心参数?您对该命令的了解程度如何?它有可能执行另一个程序吗?即使不调用辅助命令,它是否有可能做一些破坏性的事情?该程序是否存在其他漏洞(缓冲区溢出等)?
作为一般答案,这种方法对我来说似乎不太确定,特别是如果您希望它能够跨平台工作。如果您知道要执行的命令并且可以限制输入,那么您可能可以勉强通过,但就我个人而言,我不会使用这种方法,除非有充分的理由这样做。
So you control the command (pathToExe) and are worried only about the argument? How well do you know the command? Is there any chance that it could exec another program? Is there any chance it could do something damaging even without invoking a secondary command? Does the program have any other vulnerabilities (buffer overflow, etc)?
As a general answer, this approach seems iffy to me, especially if you want this to work cross platform. If you know the command to be executed and can constrain the input, then you might be able to squeak by, but personally I wouldn't use this approach unless there was a really good reason to do so.
我的建议是,如果可能的话,让程序在安全方面犯错误,并且只发出命令本身,而不是愚蠢地执行命令片段或传递最终用户发出的参数。注射有多种变化。
;
是已经讨论过的一个。您还可以使用反引号(在反引号中包裹rm -rf ~/*
会使 shell 首先解释它)用户还可以无意或有意调用别名。可能出错的事情不胜枚举。My suggestion is to make the program err on the side of safety if possible and only issue commands itself and not dumbly execute command fragments or pass on arguments issued by an end user. There are many variations of injection.
;
is one already discussed. You can also use backticks (wrappingrm -rf ~/*
in backticks makes the shell interpret it first)The user can also accidently or intentionally invoke aliases. The list of things that can go wrong is endless.