Rails在活动记录查询中清理用户输入

时间:2018-04-04 12:43:02

标签: sql ruby-on-rails postgresql ruby-on-rails-4 activerecord

我们说我有以下数据:

models/supplier.rb

| -- | ---------------- |
| id | name             |
| -- | ---------------- |
| 1  | John Doe's Store |
| 2  | Jane             |
| -- | ---------------- | 

我有以下查询未能清除用户在搜索字段中输入的内容:

@term = "John Doe's"

查询1

Supplier.order("case when name LIKE :term 1 else 2 end, name asc", term: "#{@term}%")

ArgumentError: Direction "one's%" is invalid. Valid directions are: [:asc, :desc, :ASC, :DESC, "asc", "desc", "ASC", "DESC"]
from /Users/przbadu/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/activerecord-4.2.7/lib/active_record/relation/query_methods.rb:1113:in `block (2 levels) in validate_order_args'

查询2

  

易受SQL注入攻击

Supplier.order("case when name LIKE '#{@term}%' then 1 else 2 end, name ASC").first

Supplier Load (2.6ms)  SELECT  "suppliers".* FROM "suppliers"  ORDER BY case when name LIKE 'John Doe's%' then 1 else 2 end LIMIT 1
ActiveRecord::StatementInvalid: PG::SyntaxError: ERROR:  syntax error at or near "s"
LINE 1: ...uppliers"  ORDER BY case when name LIKE 'John Doe's%' then 1..

查询3

  

对于没有'(特殊字符)的普通输入会成功,但此查询仍然容易受到SQL注入攻击

@term = "John"

Supplier.order("case when name LIKE '#{@term}%' then 1 else 2 end, name ASC").first

#<Supplier:0x007fe4bfd8d758
 id: 188,
 name: "John Doe's Store">

我无法找到解决此问题的方法,请帮我安全地完成此查询。

2 个答案:

答案 0 :(得分:1)

您只需使用

即可逃避输入
ActiveRecord::Base.connection.quote(value)

这适用于所有类型,并且是rails使用的。

@term =  ActiveRecord::Base.connection.quote("John Doe's" + "%" )

Supplier.order("case when name LIKE #{@term} then 1 else 2 end, name ASC").first

答案 1 :(得分:1)

您可以使用基本连接引用来清理输入

@term = "John Doe's"

like_value = ActiveRecord::Base.connection.quote(@term + '%') 

Supplier.order("case when name LIKE #{like_value} 1 else 2 end, name asc")

在这里阅读...

http://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/Quoting.html#method-i-quote