SQL中的SQLI。这可能吗?

时间:2016-10-13 15:12:38

标签: ruby-on-rails ruby-on-rails-5

在rails 5中,我有一个显示页面,然后我用以下内容查询@client:

<% for client in @client.nearbys(500, :units => :km).where("(membertype_id = 3) OR (membertype_id = 4)")

..问题是关于.where语句。 .where语句是否可以防止SQL注入或其他攻击?如果没有,你会用其他什么方式写这个?

编辑:我的路线和控制器中只有一个节目动作。

2 个答案:

答案 0 :(得分:1)

视图中的这种逻辑在某种意义上是错误的,视图层不负责从数据库查询数据 - 它是呈现数据的任务。

将其移至控制器,然后在视图中使用@clients实例变量:

def show
  # equal to @client.nearbys(500, units: :km).where(membertype_id: [3,4])
  @client = @client.nearbys(500, :units => :km).where("(membertype_id = 3) OR (membertype_id = 4)")
end

这种方式无需担心安全问题。

修改

正如我在评论中所说的那样,硬编码(就像你一样)就像在模型或控制器中硬编码一样安全 - 没有区别。

答案 1 :(得分:1)

首先,您似乎并不了解SQL注入的内容:

Credit xkcd.com

当您从用户那里获取输入并使用它构造SQL查询字符串时,会发生SQL注入漏洞。

User.where("foo = #{params[:bar]}")

因此,如果用户通过"'foo'); DROP TABLE 'users';--",您就会被搞砸。

User.where("foo = ?", params[:bar])

另一方面,没有此漏洞,因为数据库将?替换为单独提供的值。因此,它会引用"'foo'); DROP TABLE 'users'",以便它仅作为值插入。

中没有SQLI漏洞
@client.nearbys(500, :units => :km).where("(membertype_id = 3) OR (membertype_id = 4)")

因为您没有插入任何用户输入。

但它还是错的。

在MVC中,您应该避免在视图中进行数据库查询。您的视图应该只从控制器获取数据并使用它来生成HTML。

在您的视图中进行查询会导致代码重复,数据库优化不佳等。