在我的 Rails 控制器中,我获取用户输入的 URL 并运行系统命令wget
:
system("wget #{url}")
恐怕用户可能会输入类似的东西www.google.com && rm -rf .
,这会使控制器执行命令
system("wget www.google.com && rm -rf .")
这会删除所有内容。我应该如何防止这种攻击?我不确定用户还可以放入哪些其他东西来损害我的系统。
在我的 Rails 控制器中,我获取用户输入的 URL 并运行系统命令wget
:
system("wget #{url}")
恐怕用户可能会输入类似的东西www.google.com && rm -rf .
,这会使控制器执行命令
system("wget www.google.com && rm -rf .")
这会删除所有内容。我应该如何防止这种攻击?我不确定用户还可以放入哪些其他东西来损害我的系统。
根据这个线程:
您可以通过单独将参数传递给脚本来避免 shell 扩展:
system("/bin/wget", params[:url])
根据Kernel#system上的文档,此表单不会调用 shell。像这样&&
的构造是 shell 构造,所以如果你使用这种形式,那么参数将/bin/wget
作为参数传递给字面意思。
也就是说,仍然对输入持怀疑态度,在可能的情况下进行清理,如果可行,以非特权(或者更好的是,被监禁的)用户身份运行它。
将命令与&&
(or ;
, or |
) 连接在一起是一个 shell 功能,而不是它wget
本身可以理解的东西。如果您正在使用将命令行传递给 shell 的函数(例如system()
许多语言中的函数),那么您将处于危险之中。如果您wget
直接执行程序(而不是执行 shell 并给它一个命令行),您将不会面临这种特定攻击的风险。
然而,攻击者仍然可以做其他事情,比如滥用覆盖文件wget
的选项。-O
你最好不要使用wget
——如果你的目标是下载一个文件,为什么不直接在你自己的程序代码中使用一个 HTTP 库呢?
如果您只想检索 URL 的内容,最好完全避免使用“系统”或任何其他在服务器上运行命令的方式。
您可以使用 http 客户端(例如 Httparty)来获取 URL 内容。
response = HTTParty.get("#{url}")