我正在使用ruby 1.8.7和rails 2.3.2
以下代码容易出现sql注入
params[:id] = "1) OR 1=1--"
User.delete_all("id = #{params[:id]}")
我的问题是通过以下操作将是避免sql注入的最佳解决方案。如果没有,那么最好的方法是什么?
User.delete_all("id = #{params[:id].to_i}")
答案 0 :(得分:2)
怎么样:
User.where(id: params[:id]).delete_all
很抱歉Rails 2.x:
User.delete_all(["id = ?", params[:id]])
顺便说一下,请确保您要使用delete_all
而不是destroy_all
,前者不会触发回调。
答案 1 :(得分:1)
您也可以使用
User.delete(params[:id])
答案 2 :(得分:1)
其他答案对Rails的回答很好,如果你按照他们的建议,它会正常工作。在更通用的设置中,当您必须自己处理此问题时,通常可以使用正则表达式来提取预期格式的值。这对于整数id非常简单。可以这样想:
if params[:id] =~ /(\d+)/
safe_id = $1.to_i
# do something with safe_id now
end
当你处理字符串和任意数据时,这会变得有点复杂。如果必须处理此类数据,则可以使用数据库适配器可用的引用方法。在Rails中,这最终会转变为一致的界面:
safe_string = ActiveRecord::Base.connection.quote(unsafe_string)
对于大多数数据库系统,它将以特殊方式处理单引号和反斜杠。
如果您不在Rails之外,则必须使用特定于数据库适配器的引用方法,但使用情况非常相似。
外卖:
答案 3 :(得分:0)
使用rails方法传递where
个选项。您可以随时对它们进行硬编码,如您给出的示例中所示,但通常的方式如下:
User.where(:id => params[:id]).delete_all
User.where("id = ?", params[:id]).delete_all
User.where("id = :id", :id => params[:id]).delete_all
它们经过了充分测试,如果检测到新的漏洞,更新将解决问题并且您的代码不需要更改。
顺便说一句,如果您只想根据其ID删除1条记录,我会做的是:
User.find(PARAMS [:ID])。摧毁