在寻找解决问题的方法时,我发现了以下主题:
Rails and Arel and Scopes - simplify multiple OR's on the same table/field match
答案之一是:
fields = ["name", "email", "phone", "business_name", "doc_id"]
filter = fields.map { |field| "lower(#{field}) LIKE '#{term.downcase}'" }.join(' OR ')
@customers = Customer.where(filter)但是,如果术语是来自用户输入的param,这不是很普通的sql注入吗?如果是这样,我如何使它成为sql注入的证明?sanitize_sql_like将修复sql注入问题吗?就像这样:
filter = fields.map { |field| "lower(#{field}) LIKE '#{sanitize_sql_like(term.downcase)}'" }.join(' OR ')
@customers = Customer.where(filter)更新:这是一个解决方案吗?
fields = ["name", "email", "phone", "business_name", "doc_id"]
filter = fields.map { |field| "lower(#{field}) LIKE :query" }.join(' OR ')
@customers = Customer.where(filter, query: "%#{sanitize_sql_like(term.downcase)}%")发布于 2022-04-06 12:52:21
将用户输入插入SQL字符串的任何情况都是潜在的SQL注入漏洞。转义输入(这就是sanitize_sql_like所做的)可以在某种程度上减轻输入,但使用绑定变量将用户输入单独传递给数据库,这样就不会被误解为实际的命令。
# bad
User.where("email like %#{params[:email]}%")
# good
User.where("email like ?", "%#{params[:email]}%")您也不需要手动构造这个庞大的SQL字符串。相反,只需创建ActiveRecord::关系的数组,并将它们与.or方法连接起来。
fields = %w{ name email phone business_name doc_id }
filters = fields.map do |field|
Customer.where("lower(#{field}) LIKE :term", term: term.downcase)
end
@customers = filters.drop(1).inject(filters.first) do |memo, scope|
memo.or(scope)
end 这看起来有些令人望而生畏,但它实际上只是一个漂亮的裤子版本:
Customer.where("lower(name) LIKE :term", term: term.downcase)
.or(
Customer.where("lower(email) LIKE :term", term: term.downcase)
)
.or(
Customer.where("lower(phone) LIKE :term", term: term.downcase)
)
# ...https://stackoverflow.com/questions/71766223
复制相似问题