我需要在.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'附近收到错误不正确的语法。我尝试了不同的括号/无括号组合,但没有任何效果。
答案 0 :(得分:2)
CREATE CREDENTIAL
采用凭据名称,而不是字符串或表达式。
您可能想要探索Credential.Create方法。
答案 1 :(得分:1)
我认为你不能轻易实现这一目标。如果您打算创建动态脚本。
CREATE CREDENTIAL
方法旨在供受信任的管理员使用。
您动态创建它似乎很棘手,因为“制作存储过程”的典型答案不适用于此处。理想情况下,您应该在接受的答案中使用对象模型...但是,如果由于某种原因无法使用该对象模型,则需要以某种方式擦除参数。
如何限制参数的长度?这不是万无一失的,但应该让你大部分时间。
另一种可能的方法是在您的参数字符串中搜索“查询字词”,例如SELECT
或UPDATE
等......这些字词的存在可能会导致参数被拒绝。
更复杂的方法可能是尝试使用较低级别的帐户运行参数(在事务中首先没有CREATE CREDENTIAL
的权限。
如果没有注射,那么你会发现只有一次失败,如果有注射你会得到不同的结果......然后回滚事务。
我的意见是,您不应该允许此功能暴露给可能不受信任的用户。