避免使用connection.execute进行sql注入

时间:2015-02-06 14:03:30

标签: ruby-on-rails security ruby-on-rails-4

如果无法使用ActiveRecord高效表达查询,那么在插入传递ActiveRecord::Base.connection.execute属性时如何安全地使用params

connection.execute "... #{params[:search]} ..."

3 个答案:

答案 0 :(得分:11)

您可以使用ActiveRecord::Sanitization::ClassMethods中的方法。

您必须要小心谨慎,因为它们受到保护,因此只能用于ActiveRecord::Base子类。

在模型类中,您可以执行以下操作:

class MyModel < ActiveRecord::Base

  def bespoke_query(params)
    query = sanitize_sql(['select * from somewhere where a = ?', params[:search]])
    connection.execute(query)
  end

end

您也可以send方法在控制台上试用它:

> MyModel.send(:sanitize_sql, ["Evening Officer ?", "'Dibble'"])
=> "Evening Officer '\\'Dibble\\''"

答案 1 :(得分:2)

ActiveRecord有一个清理方法,允许您先清理查询。 也许你可以研究一下:http://apidock.com/rails/v4.1.8/ActiveRecord/Sanitization/ClassMethods/sanitize

我要非常小心地直接插入参数。 你遇到什么问题,你不能使用ActiveRecord?

答案 2 :(得分:0)

您可以使用ActiveRecord::Base中的函数来清理SQL查询。例如。 sanitize_sql_array。如其他答案中所述,它们受到保护,但无需处理继承就可以解决。

sanitize_sql_array接受一个字符串数组,其中第一个元素是查询,随后的元素将替换查询中的?个字符。

query = 'SELECT * FROM users WHERE id = ? OR first_name = ?'
id = 1
name = 'Alice'

sanitized_query = ActiveRecord::Base.send(:sanitize_sql_array, [query, id, name])
response = ActiveRecord::Base.connection.execute(sanitized_query)