我试图理解SQL注入。看起来人们可以变得非常有创意。这让我想知道我正在制作的基于搜索的rails webapp。
假设我只是将用户输入的信息直接输入"其中"我的SQL查询的声明。允许这个可以对我的数据库造成多大的伤害?
def self.search(search)
if search
includes(:hobbies, :addresses).where(search)
else
self.all
end
所以基本上,无论用户在主页上的搜索栏中输入的内容是什么,都可以直接输入到'其中'言。
有效搜索的示例'将是:
"hobby LIKE ? OR (gender LIKE ? AND hobby LIKE ?)", "golf", "male", "polo"
它是否仅限于'其中'声明提供任何形式的辩护?他们还能以某种方式执行删除或创建操作吗?
编辑:
当我查看this教程时,我没有看到一种直接的方法来执行where子句中的删除或创建操作。如果我的数据库中没有我不愿意从有效搜索结果中显示的信息,并且没有用户帐户或管理员权限这样的信息,那么这里的危险真的是什么?
答案 0 :(得分:0)
我从另一篇文章中获取了这个:Best way to go about sanitizing user input in rails
TL; DR 关于用户输入和查询:确保始终使用活动记录查询方法(例如.where),并避免使用字符串插值传递参数;将它们作为哈希参数值传递,或作为参数化语句传递。
关于渲染可能不安全的用户生成的html / javascript内容:从Rails 3开始,html / javascript文本会自动正确转义,以便在页面上显示为纯文本,而不是解释为html / javascript,所以你不要#39; t需要明确清理(或使用<%= h(potential_unsafe_user_generated_content)%>
如果我理解正确,只要您正确使用活动记录查询方法,就不必担心以这种方式清理数据。例如:
假设恶意用户将以下字符串输入user_name字段,我们的参数映射如下所示:
:user_name => "(从用户限制1中选择user_name)" 糟糕的方式(不要这样做):
Users.where(" user_name =#{params [:id}")#string interpolation is bad here 生成的查询看起来像:
SELECT users
。* FROM users
WHERE(user_name =(从用户限制1中选择user_name))
以这种方式直接字符串插值将使用key:user_name将参数值的文字内容放入查询中而不进行清理。您可能知道,恶意用户的输入被视为普通的SQL,危险非常明显。
好方法(这样做):
Users.where(id:params [:id])#hash参数 OR
Users.where(" id =?",params [:id])#参数化语句 生成的查询看起来像:
SELECT users
。* FROM users
WHERE user_name ='(从用户限制1中选择user_name)'
正如您所看到的,Rails实际上为您清理它,只要您将参数作为哈希或方法参数传递(取决于您使用的查询方法)。
创建新模型记录的数据清理的情况并不真正适用,因为new或create方法期望值的哈希值。即使您尝试将不安全的SQL代码注入到散列中,散列的值也会被视为纯字符串,例如:
User.create(:user_name =>" bobby tables);删除表用户;") 结果在查询中:
INSERT INTO users
(user_name
)VALUES(' bobby tables);删除表用户;')
所以,和上面的情况一样。
我希望有所帮助。如果我错过或误解了任何内容,请告诉我。
编辑关于转义html和javascript,简短版本是ERB"转义"您的字符串内容,以便将其视为纯文本。通过执行your_string_content.html_safe,您可以将它视为html,如果您真的需要。
但是,只需执行类似<%= your_string_content%>的操作即可。非常安全。内容在页面上被视为字符串。事实上,如果您使用Chrome开发者工具或Firebug检查DOM,您实际上应该看到该字符串周围的引号。