gpt4 book ai didi

sql - 这个 SQL 注入(inject)是如何工作的?需要解释

转载 作者:数据小太阳 更新时间:2023-10-29 07:23:46 25 4
gpt4 key购买 nike

我正在学习 RoR/数据库,这个主题让我特别困惑。在 Agile Development with 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 注入(inject)作为一个概念,但有一些细节让我感到困惑。对于初学者,SQL 注入(inject)究竟是如何作为一种语法工作的。

我知道危险在于,如果您像第一个示例那样插入外部表单参数,那么有人可能会删除表/数据库,但是怎么做呢?

假设你有这个:

name = params[:name] #DROP DATABASE database_name
pos = Order.where("name = '#{DROP DATABASE database_name}'and pay_type = 'po'")

这就是 SQL 注入(inject)的工作原理吗? SQL是一种语法,数据库中不应该有“name = 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/ 上搜索了一些教程并在谷歌上搜索,但我不明白它背后的概念。有帮助吗?

最佳答案

对于什么是 SQL 注入(inject),我可以给出最简单的解释:

这可能会产生如下所示的 SQL 查询:

SELECT * FROM Order WHERE name = 'Dan' AND pay_type = 'po'

现在好心的用户会像上面那样提供名字 Dan。

但是一个邪恶的用户(我们称他为 Bobby)会提供名称:鲍比表';删除数据库主机; --

这会创建如下查询:

SELECT * FROM Order WHERE name = 'Bobby Tables'; DROP DATABASE master; --' AND pay_type = 'po'

它有效地执行了两个查询:

SELECT *
FROM Order
WHERE name = 'Bobby Tables';

DROP DATABASE master;

现在数据库不见了。当他们从数据库中提取私有(private)信息(如用户名/密码或信用卡信息)时,会造成更严重的损害


至于为什么问号现在神奇地保护你:

使用 RoR 中的问号,使用称为参数化的模式。当您参数化 SQL 查询时,您以这样一种方式编写它以防止任何人输入成功的 SQL 注入(inject)。在所有使用问号的地方,它都被参数代替。然后通过转义任何引号将该参数安全地设置为查询顶部的值。

如果您现在将姓名 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)

现在如果邪恶的鲍比带着他的名字出现:“鲍比表”;删除数据库主机; --

如果将参数化(并转义引号)查询如下:

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)

现在这是一个非常安全的查询

希望能帮助你理解

关于sql - 这个 SQL 注入(inject)是如何工作的?需要解释,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23529183/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com