ActiveSupport :: CoreExtensions :: String :: Inflections.constantize可以安全地与用户提供的数据一起使用吗?

时间:2009-10-26 23:39:49

标签: ruby-on-rails

背景

目前,我正在开发Rails应用程序。我有不同的产品可以通过不同的供应商进行处理。所有供应商都需要特定格式的文本文件才能处理订单。

我决定使用Factory类生成Formatter类的实例,这些实例将以正确的格式呈现订单信息。

在工厂类中,我正在考虑使用以下代码:

class ExportFactory
  def self.exporter_class_for_vendor(vendor_name)
    class_name = "ProductExporter#{vendor_name}".gsub(' ','').camelize
    class_name.constantize
  end
end

问题

使用ActiveSupport::CoreExtensions::String::Inflections.constantize对用户提交的数据进行保存吗?或者,我应该只对类名进行硬编码。

注意:在此特定应用程序中,唯一能够更改给定数据的用户将是在整个系统中具有完全控制权的管理员用户。

1 个答案:

答案 0 :(得分:5)

它应该是安全的,但这取决于你之后用它做什么。

例如,如果您稍后在课堂上调用#deleteFile的输入将会很危险。

我首选的方法是将所有用户可访问的类保留在模块中,然后根据该模块的#constants验证用户输入。这可以确保您只为用户打开ruby命名空间的一个小子部分,并且还允许您创建下拉菜单,以便用户可以选择模块,而不仅仅是猜测名称。

提供相同安全级别的另一种方法是在用户输入的开头为该模块的名称添加前缀为完整的可用类。

module AvailableClasses
  Foo = ::Foo
  Bar = ::Bar
end

validates_inclusion_of :user_input, :in => AvailableClasses.constants

AvailableClasses.const_get(user_input)

"AvailableClasses::#{user_input}".constantize