我有以下代码:
SqlDataAdapter adapter = new SqlDataAdapter("SELECT TOP 0 * FROM [tableName]", conn);
DataTable dt = new DataTable();
adapter.FillSchema(dt, SchemaType.Mapped);我将使用它来构建表架构的DataTable。
通常,当人们询问SQL注入时,他们谈论的是查询参数:),我的问题是关于表名:
SELECT TOP 0 *
FROM [tableName][tableName]实际上将在运行时是动态的/确定的(这是用于框架btw)……
传入该方法的tableName是不受信任的,所以我想确保没有任何有趣的事情发生?
我必须手动擦除表名吗(我肯定我会遗漏一些东西)?或者有内置的方法可以做到这一点?或者以某种方式阻止SQL注入到表名?
发布于 2015-09-26 02:09:12
您可以使用以下查询来获取数据库中所有表的列表,并将其用作白名单:
SELECT TABLE_NAME FROM <DATABASE_NAME>.INFORMATION_SCHEMA.Tables
WHERE TABLE_TYPE='BASE TABLE'替换
<DATABASE_NAME>使用您的数据库名称。
如果有人试图输入不在该列表中的表名,则不要执行查询。
更新
对于“多连接字符串”的情况,您也可以使用一个简单的查询来检查当前的数据库名称:
SELECT db_name()因此,无论connection-string/db-name是否是动态的,您都应该能够轻松地创建一个简单地从当前数据库获取有效表名列表的方法。从总体上看,我怀疑这两个查询是否会影响应用程序的性能,就像您所说的,如果需要,您可以很容易地缓存表列表。
发布于 2015-09-26 02:23:13
发布于 2015-09-26 09:37:39
传入方法的tableName是不受信任的,所以我想确保没有任何有趣的事情发生?
一种方法是首先执行参数化查询,将表名作为参数(nvarchar max length 128)传递给QUOTENAME函数:
SELECT QUOTENAME(@TableName) AS ScrubbedTableName;然后可以在TableAdapter查询中使用返回值,而不会有SQL注入的风险。但是,如果指定的表不是预期的表,这将不会阻止元数据的泄漏。
https://stackoverflow.com/questions/32788147
复制相似问题