SQL注入和ActiveRecord

0xS*_*ina 9 ruby activerecord ruby-on-rails

从SQL注入是否安全:

Guest.where(:event_id => params[:id])
Run Code Online (Sandbox Code Playgroud)

params[:id]没有做任何类型的消毒就送来了.

一般来说,所有那些主动记录方法都安全吗?(如where,joins等.)

如果没有,安全的最佳做法是什么?另外,请注意是否有任何警告/边缘情况?

谢谢

Ale*_*x D 16

所有的ActiveRecord的查询构建方法,如where,group,order,等,都是针对SQL注入安全的,只要你不通过他们原始的SQL字符串.这很容易受到SQL注入:

 Model.where("event_id = #{params[:id]}")
Run Code Online (Sandbox Code Playgroud)

将字符串传递给类似的查询构建方法时,字符串将直接插入生成的SQL查询中.这有时很有用,但确实会增加注射漏洞的危险.另一方面,当您传递值的哈希值时,如下所示:

 Model.where(event_id: params[:id])
Run Code Online (Sandbox Code Playgroud)

...然后AR自动为您引用值,保护您免受SQL注入.


Jos*_*osh 10

是的,您的代码在数据库上运行之前会被安全地清理.Rails通过自动清理输入来保护您免受sql注入.

EXCEPTION是字符串插值:

Guest.where("event_id = #{params[:id]}") # NEVER do this
Run Code Online (Sandbox Code Playgroud)

请改用以下两个选项之一:

Guest.where(:event_id => params[:id]) # if you want pure ruby, use this
# OR
Guest.where("event_id = ?", params[:id]) # if you prefer raw SQL, use this
Run Code Online (Sandbox Code Playgroud)

有关sql注入以及其他常见攻击的更多信息,请查看Rails安全指南.


Zhe*_*nya 6

如果你确实需要使用原始sql,你可以使用quote来防止SQL注入

这是从此处复制的示例

conn = ActiveRecord::Base.connection
name = conn.quote("John O'Neil")
title = conn.quote(nil)
query = "INSERT INTO users (name,title) VALUES (#{name}, #{title})"
conn.execute(query)
Run Code Online (Sandbox Code Playgroud)