用户在 SqlCommand 中指定的存储过程名称

User Specified Stored Procedure Name in SqlCommand

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

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

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

例如:

UserStoredProcedureName = "SELECT * FROM USERS";

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

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

;drop table users

不,没有 "validation" 每个存储过程的说法,如果找不到它们就会失败。

总的来说,我认为允许某人在文本中写入然后您将其作为语句执行是一个非常糟糕的想法,尤其是在登录名具有写入权限的情况下。如果你想更安全,你可以通过查询可用的存储过程来构建一个下拉菜单,然后当你转到 运行 时,你可以验证请求 运行 的内容与程序名称可用。

但是要在参数端允许自由格式的文本,这就是它要快速向南发展的地方。

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

sqlcommand.parameters.addwithvalue(x,y);

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

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

所以:您仍然应该通过白名单来控制输入的存储过程名称。如果名称来自您自己的代码,那应该不是问题,并且在这种情况下加入白名单是不正常的。

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