【问题标题】:remote code execution in ruby with constantize在ruby中使用constantize远程执行代码
【发布时间】:2013-08-27 12:33:26
【问题描述】:

当使用contantize 时,我正试图解决 ruby​​/rails 中的远程代码执行漏洞。

我知道能够向服务器提供任何类名可能会有潜在的危险,但我想知道这个本身是否有危险。

例如,如果 Rails 控制器代码看起来像这样(即在实例化对象上执行硬编码方法):

klass = params[:class].classify.constantize
klass.do_something_with_id(params[:id]) if klass.respond_to?('do_something_with_id')

此代码是否易受攻击?还是仅结合指定要在类上调用的方法?

【问题讨论】:

  • 我不知道这是否容易受到攻击,但 param 中的类名看起来一点也不好看。你能发布你的真实目的吗?如果不使用这些,很有可能有更好的解决方案。
  • 我完全同意可能有更好的方法,即使它现在不脆弱,最好不要使用这样的东西。但是,我只是对现阶段的理论利用可能性(或缺乏)感到好奇,而不是如何改进代码。

标签: ruby-on-rails ruby security


【解决方案1】:

将字符串转换为常量本身并不危险,但如何使用该常量却有潜在的危险(即随后调用的方法)。

如果您确实需要这样做,那么最好提供一个允许的类列表。例如

klass = params[:class].classify
if %w(Class1 Class2 Class3).include? klass
  klass.constantize.do_something_with_id(params[:id])
else
  raise 'Forbidden'
end

不管怎样,它可以帮助你在晚上睡觉时知道输入是相当有限的。

更新

控制创建的另一种更明确但也更冗长的方法是使用 case 语句:

def create_klass(option)
  case option
  when "option1"
    Class1
  when "option2"
    Class2
  when "option3"
    Class3
  else
    raise "Unknown option"
  end
end

这样,您无需将系统的内部结构暴露给客户端。如果有很多选项,那么您可以使用带有选项映射到类的哈希。

【讨论】:

  • 好的,很高兴知道,我绝对同意白名单在这些情况下更有意义。只是想更具体地澄清一下。每当您使用 constantize 时,像 Brakeman 之类的工具似乎都会警告您,无论是否有任何白名单或对其进行检查,所以我不确定是否可以单独利用它,或者只能结合使用。跨度>
  • 是的,只能组合使用。布雷克曼(可能是正确的)过度保护。一种方法可能是拥有一种工厂方法,我将在答案中添加一个示例。
  • 我想我对解决方案很清楚,试图更清楚地理解问题。再次感谢您花时间解释这个@joonty。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多