这可能会导致如下所示的SQL查询:
SELECT * FROM Order WHERE name = 'Dan' AND pay_type = 'po'
但是一个邪恶的用户(我们称他为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主站;--
if是否可以对查询进行参数化(和转义报价),例如:
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)
希望对您有所帮助