我有一个问题:
@results = the_db.where('name LIKE ?', '%#{input}%').paginate(
:page => params[:page],
:per_page => 50,
:group => "name",
:order => [
"CASE WHEN name like '#{input}%' THEN 0
WHEN name like '% %#{input}% %' THEN 1
END, name"
]
)
问题是这很容易受到注射。 (订单条款)我该如何解决这个问题?是否有可能以某种方式消除用户的输入以消除任何攻击?
答案 0 :(得分:1)
使用参数化查询。
@results = the_db.where('name LIKE ?', "%#{input}%").paginate(
:page => params[:page],
:per_page => 50,
:group => "name",
:order => [
"CASE WHEN name like ? THEN 0
WHEN name like ? THEN 1
END, name",
'#{input}%',
'% %#{input}% %'
]
)
虽然是#39;如果你在字符串中有%
,我不确定它的表现。
答案 1 :(得分:1)
您可以在嵌入之前或之后使用input
字符串上的sanitize
方法。这基本上是Rails参数化为您所做的。
请注意,清理会添加一个前导和尾随单引号'
,您可以根据需要使用以下内容删除:
sanitize(something)[1..-2]
在您的示例中,您可以执行以下操作:
:order => [
"CASE WHEN name like #{sanitize "#{input}%")} THEN 0
WHEN name like #{sanitize "% %#{input}% %")} THEN 1
END, name"
]
请注意,您需要在类方法或范围内调用sanitize
,或使用有权访问它的命名空间(例如ModelName.sanitize
或ActiveRecord::Base.sanitize
)。
答案 2 :(得分:1)
您可以使用sanitize_sql_array
方法。不幸的是,它是一种私有方法,因此您必须使用send
调用它。
query = <<-QUERY
CASE WHEN name like ? THEN 0
WHEN name like ? THEN 1
END, name
QUERY
sanitized_order = ActiveRecord::Base.send :sanitize_sql_array, [query, "'#{input}%'", "'% %#{input}% %'"]
@results = the_db.where('name LIKE ?', '%#{input}%').paginate(
:page => params[:page],
:per_page => 50,
:group => "name",
:order => sanitized_order)
答案 3 :(得分:1)