需要在 Rails3 中避免 SQL 注入

Need to avoid SQL Injection in Rails3

我需要通过避免 Rails 中的 SQL 注入来重写以下代码 3.

some_table_name.joins("inner join #{table_name} on linked_config_items.linked_type = '#{class_name}' and linked_config_items.linked_id = #{table_name}.id").
        where("#{table_name}.saved is true and #{table_name}.deleted_at is null")

这里,table_name是动态的,会变化。

SQL像table名称和列名这样的标识符不能用绑定参数替换,这是更常见的确保防止SQL注入漏洞的方法。

确保 table_name 安全的最佳解决方案是将其列入白名单。

也就是说,在将其插入查询之前,使用代码验证它是否与数据库中存在的 table 名称相匹配。许多应用保留 table 个名称的缓存,或以某种方式将它们的元数据映射到代码中。

此外,您应该在反引号中分隔动态标识符,因此如果 table 是合法的但恰好是 reserved word,它仍然有效。

some_table_name.joins("inner join `#{table_name}` as t1 ...

使用上面显示的 table 别名 (as t1) 也很方便,因此您不必在查询中多次重复 Ruby 变量。

最后,我不得不像这样重写上面的查询

some_table_name.joins(self.class.superclass.send(:sanitize_sql_array,"inner join #{table_name} as t1 on linked_config_items.linked_type = '#{class_name}' and linked_config_items.linked_id = t1.id")).
          where("t1.saved is true and t1.deleted_at is null")

在这里,'self.class.superclass'是'ActiveRecord::Base'