怎么用?帮助反对Rails中的SQL注入?

时间:2017-11-05 23:51:11

标签: sql ruby-on-rails

我在我的Rails应用程序中有这个代码,我不确定它是如何工作的。

@dogs = Dog.where(breed: search_breed).where(<<-SQL, search_color, search_name)
  color = ?
  AND name = ?
SQL

在SQL部分中,如何将search_color和search_name放入SQL start并使用?在SQL里面哪个/比这更好?

@dogs = Dog.where(breed: search_breed).where(<<-SQL)
 color = search_color
 AND name = search_name
SQL

谢谢。

3 个答案:

答案 0 :(得分:0)

这里没有理由使用原始SQL。该代码似乎真的很混乱,应该是:

@dogs = Dog.where(
  breed: search_breed,
  color: search_color,
  name: search_name
)

如果您正在使用AND默认情况下where的工作原理。这将为您妥善逃避一切

当您犯下错误时会发生注射:

Dog.where("breed = #{search_breed}") # WRONG!

你真的想做什么。

安全的选择是:

Dog.where("breed=?", search_breed)

在这种情况下,数据库驱动程序将?替换为具有正确转义的search_breed值的占位符值。在这里正确转义意味着&#34;避免SQL注入问题&#34;。

答案 1 :(得分:0)

因为没有占位符,您的查询字符串不会被转义。如果恶意用户向您的数据库发送drop table命令,它就会消失。

Client.where("first_name LIKE '%#{params[:first_name]}%'")

这是为sql注入打开的。来自用户的任何输入均由您的数据库获取。

'John'; DROP TABLE clients;--

使用占位符来防止注射。

答案 2 :(得分:0)

基于之前的答案,SQL注入可能由于多种原因而非常危险。注入攻击使得偷偷摸摸的用户可以通过“OR 1 ..”语句读取或操作数据库中的数据。

假设您有一个应用程序,您可以搜索许多报告。虽然某些报告应该对公众隐藏,但您允许所有用户在您的show动作中访问它:

<强> reports_controller.rb

Reports.where("id = '#{params[:id]}'")

在此格式中,'永远不会被转义。这允许用户使用OR 1语句直接在数据库中设置属性,恶意用户可以生成类似以下内容的查询:

SELECT * FROM reports WHERE name = '' OR 1--'

实际上,这会将系统中的所有记录返回给用户。包括他们不应该看到的那些!

另一个例子是绕过身份验证系统。如果您验证登录凭据,请执行以下操作:

User.find_by("login = '#{params[:name]}' AND password = '#{params[:password]}'")

如果用户输入' OR '1'='1作为登录值,并输入' OR '2'>'1作为密码,则查询将如下所示:

SELECT * FROM users WHERE login = '' OR '1'='1' AND password = '' OR '2'>'1' LIMIT 1

然后,它不仅会返回数据库中的第一个用户,还会授予对恶意用户的完全访问权限。 但是如果你使用这种格式:

User.find_by("login = ? AND password = ?", login_info, password_info).first

这样做会逃避SQL语句中的',因此用户无法利用查询。您可以使用简写散列形式:

User.find_by(login: login_info, password: password_info)

您的查询仍将受到保护。

参考:http://guides.rubyonrails.org/security.html#sql-injection这是一个非常有用的部分,其中包含有关此主题的更多示例/详细信息。