此SQL注入如何工作?需要说明

和卢比奥

我正在学习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上进行了搜索,但是我没有得到这个概念的支持。有什么帮助吗?

阿瑟宾3

对于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] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

ORACLE PL / SQL变量功能范围-需要说明

来自分类Dev

奇怪的Makefile,需要说明

来自分类Dev

Excel公式需要说明

来自分类Dev

需要说明“ +(x> 180)”或“ +()”

来自分类Dev

ObjectOutputStream混乱,需要说明

来自分类Dev

需要说明C程序输出

来自分类Dev

Python中的装饰器-需要说明

来自分类Dev

需要说明角向载荷

来自分类Dev

双尾递归需要说明

来自分类Dev

需要说明jQuery .Show()效果闪烁

来自分类Dev

WCF和隔离存储-需要说明

来自分类Dev

C-比较功能-需要说明

来自分类Dev

PHP动态链接问题-需要说明

来自分类Dev

Java BigDecimal-需要说明

来自分类Dev

需要说明随机函数快速

来自分类Dev

需要说明Docpad的持久性

来自分类Dev

导轨大量使用哈希...需要说明

来自分类Dev

背包1/0的实现需要说明

来自分类Dev

Python中的装饰器-需要说明

来自分类Dev

需要说明jQuery .Show()效果闪烁

来自分类Dev

需要说明角向载荷

来自分类Dev

JavaScript中的简单if语句需要说明

来自分类Dev

ListNode解决方案需要说明

来自分类Dev

SQL添加Order By子句会使查询运行速度明显加快。需要说明

来自分类Dev

需要说明如何将声音传递到视频卡的HDMI

来自分类Dev

需要说明如何在Java-8中为lambda创建接口对象

来自分类Dev

如何减少或注入此代码中的工作

来自分类Dev

Java中的矩阵转置(需要说明)

来自分类Dev

“对于列表中的项目”循环,需要说明