类似查询的安全 ActiveRecord

我正在尝试编写 LIKE 查询。

我读到纯字符串查询不安全,但是我找不到任何文档来解释如何编写安全的 LIKE Hash 查询。

是否可能? 我应该手动防御 SQL 注入吗?

82198 次浏览

To ensure that your query string gets properly sanitized, use the array or the hash query syntax to describe your conditions:

Foo.where("bar LIKE ?", "%#{query}%")

or:

Foo.where("bar LIKE :query", query: "%#{query}%")

If it is possible that the query might include the % character and you do not want to allow it (this depends on your usecase) then you need to sanitize query with sanitize_sql_like first:

Foo.where("bar LIKE ?", "%#{sanitize_sql_like(query)}%")
Foo.where("bar LIKE :query", query: "%#{sanitize_sql_like(query)}%")

You can do

MyModel.where(["title LIKE ?", "%#{params[:query]}%"])

For PostgreSQL it will be

Foo.where("bar ILIKE ?", "%#{query}%")

Using Arel you can perform this safe and portable query:

title = Model.arel_table[:title]
Model.where(title.matches("%#{query}%"))

In case if anyone performing search query on nested association try this:

Model.joins(:association).where(
Association.arel_table[:attr1].matches("%#{query}%")
)

For multiple attributes try this:

Model.joins(:association).where(
AssociatedModelName.arel_table[:attr1].matches("%#{query}%")
.or(AssociatedModelName.arel_table[:attr2].matches("%#{query}%"))
.or(AssociatedModelName.arel_table[:attr3].matches("%#{query}%"))
)
 

Don't forget to replace AssociatedModelName with your model name