SqlCommand

时间:2018-04-20 23:44:50

标签: c# sql-server stored-procedures sql-injection

我使用以下代码创建SqlCommand,其中包含用户在UserStoredProcedureName中指定的存储过程的名称:

new SqlCommand(UserStoredProcedureName, connection)
               { CommandType = CommandType.StoredProcedure }

用户在UserStoredProcedureName中提供的字符串未进行验证。用户是否只能在数据库中指定存储过程的名称?用户是否能够通过制作恶意存储过程名称来执行SQL注入攻击?

例如:

UserStoredProcedureName = "SELECT * FROM USERS";

2 个答案:

答案 0 :(得分:4)

sql注入攻击不会发生在存储过程本身,但它可能发生在提供的参数/参数上。 There's a good article that explains it a bit

例如,您可以调用SP_MYPROC,这很好,但我可以注入第一个参数:

;drop table users

不,如果找不到它们,除了失败之外,每个存储过程的说法都没有“验证”。

一般来说,我认为允许某人用文本编写然后作为语句执行,这是一个非常糟糕的想法,特别是如果登录具有写访问权限。如果您想要更安全,可以通过查询可用的存储过程来构建下拉菜单,然后当您运行一个时,您可以验证要求运行的内容与可用的过程名称之间的1 = 1匹配。

但是为了允许参数方面的自由格式文本,这就是它快速向南移动的地方。

我只熟悉明确指定参数,例如:

sqlcommand.parameters.addwithvalue(x,y);

但在这种情况下,程序的名称和参数是硬编码的。

答案 1 :(得分:4)

您不应该让外部代码提供存储过程名称。理由:存储过程可以是sp_executesql,它可以运行您作为第一个参数提供的任何内容。它也可以是xp_cmdshell或类似的。

所以:您仍应通过白名单控制输入存储过程名称。如果名称来自您自己的代码,则不应该是一个问题,并且在该方案中对于white-list是不正常的。

注意:如果存储过程在内部使用EXEC (@sql)EXEC sp_executesql @sql,那么它仍然可以呈现SQL注入攻击,具体取决于@sql是否包含恶意的非参数化SQL。请注意,sp_executesql设计的,以允许您完全参数化动态SQL,以避免SQL注入攻击甚至在SQL内部生成的SQL内。