我正在生成一些动态SQL,并希望确保我的代码是安全的SQL注入.
为了争论,这里是一个如何生成它的最小例子:
var sql = string.Format("INSERT INTO {0} ({1}) VALUES (@value)",
tableName, columnName);
Run Code Online (Sandbox Code Playgroud)
在上面,tableName和columnName,以及@value来自不受信任来源的任何内容.由于占位符的使用@value是安全的SQL注入攻击,可以忽略.(该命令通过SqlCommand执行.)
但是,tableName并且columnName 不能作为占位符绑定,因此容易受到注入攻击.由于这是一个"真正动态"的场景,因此没有白名单tableName或columnName可用.
问题是:
是否有一个标准的,内置的方式来检查和/或消毒tableName和columnName?(SqlConnection,或帮助程序类等)如果没有,在不使用第三方库的情况下执行此任务的好方法是什么?
笔记:
[schema].[My Table].column,就像"安全"一样table1.更新:
刚发现这个,并认为它有点有趣:.NET4中有一个SqlFunctions.QuoteName函数(EF4?).好的,这对我来说真的没有帮助......
该方法为查询提供了一个字符串,并Object []为参数提供了一个数组,可能是为了避免SQL注入.
然而,地球上没有任何地方记录您应该放入对象数组中的内容.
关于SO的另一个问题就是问这个完全相同的东西,但是接受的答案不起作用:当使用DbSet <T> .SqlQuery()时,如何使用命名参数?
我已经尝试过所有可以考虑的参数替换形式,所有这些都会引发异常.有任何想法吗?
它会如此简单:
SqlQuery("SELECT * FROM @table", "Users")
编辑:以下是我尝试过的一些事情(例外情况是SqlException):
var result = context.Users.SqlQuery<T>("SELECT * FROM @p0 WHERE @p1 = '@p2'",
new SqlParameter("p0", tableName),
new SqlParameter("p1", propertyName),
new SqlParameter("p2", searchQuery));
Run Code Online (Sandbox Code Playgroud)
这给了 Must declare the table variable "@p0".
var result = context.Users.SqlQuery<T>("SELECT * FROM {0} WHERE {1} = '{2}'", tableName, propertyName, searchQuery);
Run Code Online (Sandbox Code Playgroud)
这给了 Must declare the table variable "@p0".