避免sql注入的最佳方法是什么?

时间:2014-10-20 12:58:22

标签: ruby-on-rails ruby sql-injection ruby-on-rails-2

我正在使用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}")

4 个答案:

答案 0 :(得分:2)

怎么样:

User.where(id: params[:id]).delete_all

很抱歉Rails 2.x:

User.delete_all(["id = ?", params[:id]])

Check doc

顺便说一下,请确保您要使用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之外,则必须使用特定于数据库适配器的引用方法,但使用情况非常相似。

外卖:

  1. 如果您的数据具有特定格式,请使用正则表达式强制执行格式
  2. 否则,请使用数据库适配器的引用功能使数据安全"用于查询
  3. 如果您正确使用各种方法和"条件"
  4. ,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])。摧毁

相关问题