我正在学习RoR /数据库,这个话题让我特别困惑。在《用Rails开发敏捷4》一书中,他们给出了一个示例,该示例查找名为Dave的条目的所有订单的列表:
pos = Order.where("name = 'Dave' and pay_type = 'po")
这本书接着说,您永远都不想做这样的事情:
name = params[:name]
pos = Order.where("name = '#{name}'and pay_type = 'po'")
相反,您应该这样做:
name = params[:name]
pos = Order.where(["name = ? and pay_type = 'po'",name])
我了解什么是SQL注入概念,但是有一些细节使我感到困惑。对于初学者来说,SQL注入作为一种语法到底是如何工作的。
我得到的危险是,如果像第一个示例那样插入外部表单参数,则有人可以删除表/数据库。
可以说你有这个:
name = params[:name] #DROP DATABASE database_name
pos = Order.where("name = '#{DROP DATABASE database_name}'and pay_type = 'po'")
这是SQL注入的工作方式吗?SQL是一种语法,数据库中应该没有字段“名称= DROP DATABASE database_name”,这不会返回错误而不是删除数据库吗?
此外,问号版本将如何防止这种情况。同样,假设您有这种情况。
name = params[:name] #DROP DATABASE database_name
pos = Order.where(["name = ? and pay_type = 'po'", DROP DATABASE database_name])
这不会用DROP DATABASE database_name语法替换问号,然后我们不会遇到与第一个示例相同的问题吗?这究竟如何保护应用程序免受SQL影响?我在http://hub.tutsplus.com/上搜索了一些教程,并在Google上进行了搜索,但是我没有得到这个概念的支持。有什么帮助吗?
对于SQL注入,我可以给出最简单的解释:
这可能会导致如下所示的SQL查询:
SELECT * FROM Order WHERE name = 'Dan' AND pay_type = 'po'
现在,一个不错的用户会像上面那样提供Dan的名称。
但是邪恶的用户(我们称他为Bobby)会提供名称: Bobby Tables'; DROP DATABASE master; --
这将创建一个查询,例如:
SELECT * FROM Order WHERE name = 'Bobby Tables'; DROP DATABASE master; --' AND pay_type = 'po'
有效执行两个查询:
SELECT *
FROM Order
WHERE name = 'Bobby Tables';
DROP DATABASE master;
现在数据库不见了。当他们从数据库中拉出私人信息(例如用户名/密码或信用卡信息)时,会造成更严重的损失
至于为什么问号现在可以神奇地保护您:
在RoR中使用问号,使用称为参数化的模式。在对SQL查询进行参数化时,应以防止任何人输入成功的SQL注入的方式编写该查询。在任何使用问号的地方,它都会被参数替换。然后,通过转义任何引号,将该参数安全地设置为查询顶部的值。
如果现在将Dan的名称提供给:
Order.where(["name = ? and pay_type = 'po'", params[:name])
该查询看起来像:(RoR在内部对参数的设置可能略有不同,但是效果是相同的)
DECLARE @p0 nvarchar(4000) = N'po',
@p1 nvarchar(4000) = N'Dan';
SELECT [t0].[ID], [t0].[name], [t0].[pay_type]
FROM Order AS [t0]
WHERE ([t0].[name] = @p1) AND ([t0].[pay_type] = @p1)
现在,如果邪恶的鲍比(Bobby)带有他的名字:`Bobby Tables; DROP DATABASE主数据库;-
如果将参数化(和转义引号)查询,例如:
DECLARE @p0 nvarchar(4000) = N'po',
@p1 nvarchar(4000) = N'Bobby Tables''; DROP DATABASE master; --';
SELECT [t0].[ID], [t0].[name], [t0].[pay_type]
FROM Order AS [t0]
WHERE ([t0].[name] = @p1) AND ([t0].[pay_type] = @p1)
现在,这是一个非常安全的查询
希望对您有所帮助
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句