【问题标题】:What's the best way in Ruby to clean up a user-provided url string so that it's safe to interpolate into a shell command?Ruby 中清理用户提供的 url 字符串以便安全地插入 shell 命令的最佳方法是什么?
【发布时间】:2009-12-20 19:02:44
【问题描述】:

我想让 Web 应用程序的用户输入一个 URL,然后将该 URL 传递给 curl。我宁愿使用 curl 而不是 Net::HTTP 或 open-uri。但这会带来安全风险。检查 URL 字符串并防止任何注入攻击的最佳方法是什么?

我正在考虑只使用这样的正则表达式来检查注入攻击:

raise "possible injection attack" if url =~ /[\s']/ 

如果检查成功,则像这样调用 curl

html = `curl '#{url}'`

这样够安全吗?

【问题讨论】:

  • 这似乎是个坏主意 (tm) ...您对使用 ruby​​ 下载 HTML 有什么反感?如果您正在寻找简单性,请查看curb.rubyforge.org
  • 与 curl 的手册页相比,我发现 Net::HTTP 的文档很难导航和理解。尝试将工作从 Ruby 程序委托给另一个 unix 程序有什么问题吗?
  • 我也知道open-uri,但我经常想做http响应和请求头的事情,使用curl比使用Net::HTTP更容易。

标签: ruby curl code-injection


【解决方案1】:
system("curl", url)

这是安全的,因为参数直接传递给命令的main(argv),而不是由命令行处理器解析。例如system("echo", "* && echo shenanigan") 字面上输出* && echo shenanigan

【讨论】:

  • 谢谢。我认为system(cmd [, arg, ...]) 更符合我的要求,但您为我指明了正确的方向。
  • 确实,我一直混淆这两者:exec 用命令替换当前脚本,而system 之后继续脚本。已修复。
  • 这似乎可以阻止注入攻击,但如果我错了,请纠正我。例如ruby -e 'exec("echo", "* && echo \"test\" ")' 按字面意思输出: * && echo "test"
  • 命令是直接调用的,想象一下用字符串数组调用main(argv),而不是将命令行传递给命令行处理器。实际上,@dan 的示例按字面意思输出参数。
【解决方案2】:

也许你最好使用像 libcurl 这样的库(以避免使用 shell 命令)?

【讨论】:

  • 谢谢。我会研究一下,但我仍然对作为一般技术问题的原始问题的答案感兴趣,因为有很多我可以从 Ruby 中重用的 unix 工具。
  • 我猜可以假设大多数流行的 unix 工具都会为它们提供 Ruby 绑定(我知道 Python 肯定就是这种情况)。
  • 希望使用 Ruby(或 Python)作为通过 shell 调用和编排小型外部程序的胶水代码是否存在严重问题?尽管 Unix 哲学曾经鼓励这种风格,但这里似乎存在强烈的偏见。
猜你喜欢
  • 2013-02-03
  • 2010-11-02
  • 2012-07-02
  • 2017-09-03
  • 2017-02-09
  • 2014-09-04
  • 2010-10-17
  • 2016-06-18
  • 1970-01-01
相关资源
最近更新 更多