如何保护注入动态“创建凭证”语句?

时间:2012-05-04 17:49:39

标签: .net tsql sql-injection

我需要在.NET中创建一个CREATE CREDENTIAL语句,其中包含从用户界面传入的凭据名称,标识和密码。一个天真的实现看起来像这样(请原谅VB):

Dim cmd As SqlClient.SqlCommand = c.CreateCommand
cmd.CommandText = "CREATE CREDENTIAL [" & credentialName & "] WITH IDENTITY = N'" & identityName & "', SECRET = N'" & password & "'"

它可以工作,但它很容易受到SQL注入的攻击。我试图使用这样的参数:

cmd.CommandText = "CREATE CREDENTIAL [@CREDENTIALNAME] WITH IDENTITY = @IDENTITYNAME, SECRET = @PASSWORD"
cmd.Parameters.AddWithValue("@CREDENTIALNAME", "myCred")
cmd.Parameters.AddWithValue("@IDENTITYNAME", "Tyler")
cmd.Parameters.AddWithValue("@PASSWORD", "SecretPassword")

但我在'@IDENTITYNAME'附近收到错误不正确的语法。我尝试了不同的括号/无括号组合,但没有任何效果。

2 个答案:

答案 0 :(得分:2)

CREATE CREDENTIAL采用凭据名称,而不是字符串或表达式。

您可能想要探索Credential.Create方法。

答案 1 :(得分:1)

我认为你不能轻易实现这一目标。如果您打算创建动态脚本。
CREATE CREDENTIAL方法旨在供受信任的管理员使用。

您动态创建它似乎很棘手,因为“制作存储过程”的典型答案不适用于此处。理想情况下,您应该在接受的答案中使用对象模型...但是,如果由于某种原因无法使用该对象模型,则需要以某种方式擦除参数。

如何限制参数的长度?这不是万无一失的,但应该让你大部分时间。 另一种可能的方法是在您的参数字符串中搜索“查询字词”,例如SELECTUPDATE等......这些字词的存在可能会导致参数被拒绝。

更复杂的方法可能是尝试使用较低级别的帐户运行参数(在事务中首先没有CREATE CREDENTIAL的权限。 如果没有注射,那么你会发现只有一次失败,如果有注射你会得到不同的结果......然后回滚事务。

我的意见是,您不应该允许此功能暴露给可能不受信任的用户。