我在我的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
谢谢。
答案 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这是一个非常有用的部分,其中包含有关此主题的更多示例/详细信息。