如何在Rails 4中清理原始SQL

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在Rails 4中清理原始SQL相关的知识,希望对你有一定的参考价值。

在Rails 3中,我可以使用sanitize_sql_array来清理那些需要原始SQL查询的偶然时刻的原始SQL。但是这似乎已经在Rails 4中删除了,或者没有那么多删除,但转移到ActiveRecord :: Sanitization。但是,我现在无法弄清楚如何调用sanitize_sql_array,那么在Rails 4中清理原始SQL的最佳方法是什么?

我想澄清一下,我在这里讨论完整的原始SQL查询,而不是使用Rail的模型。我知道这不是最佳实践,这正是我必须为此特定查询所做的事情,因为它无法用Rails的漂亮的ActiveRecord接口来表示(相信我,我已经尝试过了)。

这是一个示例调用,它明显比我的查询实际上看起来更简单:

query = "SELECT * FROM users 
LEFT OUTER JOIN posts ON users.id=posts.user_id
AND posts.topic_id = '#{topic.id}'" 
# ^- Obviously bad and very vulnerable, this is what we're trying to fix
ActiveRecord::Base.connection.select_all(query)
答案

如果你真的需要编写原始SQL,你可以使用quote来清理它:

conn = ActiveRecord::Base.connection
name = conn.quote("John O'Neil")
title = conn.quote(nil)
query = "INSERT INTO users (name,title) VALUES (#{name}, #{title})"
conn.execute(query)
另一答案

Active Record docs中,清理SQL查询的最佳方法是避免将自己的条件构建为纯字符串,换句话说,将参数直接插入查询中,如下所示:

User.find_by("user_name = '#{user_name}' AND password = '#{password}'")

而是使用数组或散列条件。

数组条件:

Client.where("orders_count = ? AND locked = ?", params[:orders], false)

哈希条件:

Client.where(is_active: true)

一个澄清的例子:

class User < ActiveRecord::Base
  # UNSAFE - susceptible to SQL-injection attacks
  def self.authenticate_unsafely(user_name, password)
    where("user_name = '#{user_name}' AND password = '#{password}'").first
  end

  # SAFE
  def self.authenticate_safely(user_name, password)
    where("user_name = ? AND password = ?", user_name, password).first
  end

  # SAFE
  def self.authenticate_safely_simply(user_name, password)
    where(user_name: user_name, password: password).first
  end
end

以下是一些参考:

另一答案

引用方法和其他ActiveRecord::Base清理方法已被弃用,并且从未成为公共API的一部分。

https://github.com/rails/rails/issues/28947

官方的消毒方法是

http://api.rubyonrails.org/classes/ActiveRecord/Sanitization/ClassMethods.html

以上是关于如何在Rails 4中清理原始SQL的主要内容,如果未能解决你的问题,请参考以下文章

以下代码片段是不是容易受到 Rails 5 中 SQL 注入的影响?

如何在 Rails 中链接原始 SQL 查询或如何从 Rails 中的原始 SQL 查询返回 ActiveRecord_Relation?

如何在rails中使用动态绑定执行原始更新sql

Rails 4 清理用户输入

在 Rails 上为连接、限制、选择等(不是条件)的 SQL 片段安全地转义字符串

Rails 4:使用内置 HTML 清理时禁用自动 CSS 清理