在Ruby中形成卫生shell命令或系统调用

arb*_*les 14 ruby security shell sanitization system

我正在构建一个可以帮助我管理服务器的守护进程.Webmin运行良好,就像打开服务器的shell一样,但我更喜欢能够从我设计的UI控制服务器操作,并向最终用户公开一些功能.

守护程序将从队列中获取操作并执行它们.但是,由于我将接受用户的输入,我想确保他们不被允许在特权shell命令中注入危险的东西.

这是一个例证我问题的片段:

def perform
  system "usermod -p #{@options['shadow']} #{@options['username']}"
end
Run Code Online (Sandbox Code Playgroud)

一个解释更多的要点:https://gist.github.com/773292

如果对这种情况进行典型的输入和消毒输入就足够了,我并不乐观,作为一名设计师,我没有大量与安全相关的经验.我知道这对我来说应该是显而易见的,但事实并非如此!

如何确保将创建和序列化操作的Web应用程序无法将危险文本传递到接收操作的特权进程?

谢谢你的帮助
arb

cam*_*cam 19

它看起来不像你需要一个shell来做你正在做的事情.请参阅system此处的文档:http://ruby-doc.org/core/classes/Kernel.html#M001441

你应该使用第二种形式system.上面的例子将成为:

system 'usermod', '-p', @options['shadow'], @options['username']
Run Code Online (Sandbox Code Playgroud)

一个更好的(IMO)写这个方法是:

system *%W(usermod -p #{@options['shadow']} #{@options['username']})
Run Code Online (Sandbox Code Playgroud)

这种方式的参数直接传递给execve调用,所以你不必担心偷偷摸摸的shell技巧.

  • 正确.参数直接传递给执行的程序.您可以自己验证.尝试运行`ruby -e'系统*W(ls -l foo; rm -rf /)'` (3认同)

Sim*_*ann 16

如果您不仅需要退出状态,还需要您可能想要使用的结果Open3.popen3:

require 'open3'
stdin, stdout, stderr = Open3.popen3('usermod', '-p', @options['shadow'], @options['username'])
stdout.gets
sterr.gets
Run Code Online (Sandbox Code Playgroud)

更多信息:在Ruby中获取system()调用的输出