C# 中查询的 SQL 注入问题
Posted
技术标签:
【中文标题】C# 中查询的 SQL 注入问题【英文标题】:SQL Injection issue with the query in C# 【发布时间】:2018-03-29 22:51:09 【问题描述】:我有一些用我的 C# 代码编写的 SQL 查询。表名称使用枚举传递给构造函数。然后它分配给全局变量并附加到字符串,
const string ADD_SQL = "INSERT INTO 0 (ColumnOne) VALUES (@valueOne)";
const string CLEAR_SQL = "DELETE FROM 0";
var commandText = string.Format(ADD_SQL , _tableName);
但是当我运行 Veracode 工具时,它显示该查询在执行时可能存在 SQL 注入。
command.ExecuteNonQuery();
从代码中避免这种 SQL 注入场景的任何可能的解决方案。需要对上述 const 进行重构。我尝试添加标签 (@tablename) 并尝试过。但没有成功。
const string ADD_SQL = "INSERT INTO @tablename (Data) VALUES (@valueOne)";
var commandText = ADD_MESSAGE_SQL.Replace("@tablename", _tableName);
还有其他可能的解决方案来避免这种情况吗?
【问题讨论】:
@DragandDrop 为什么在您可能知道表名无法参数化时建议重复参数? 您应该始终使用参数化查询,搜索参数化查询以获得更多详细信息 SqlParameter does not allows Table name - other options without sql injection attack?的可能重复 @jimmi94 显示示例比建议无法完成的事情要有用得多...***.com/questions/3128582/… 可能是您可以为表名做的最好的事情,如果您必须插入它们。 . @LahiruD,SELECT table_name FROM INFORMATION_SCHEMA.TABLES WHERE table_name=@Param
现在你很确定没有 sql 注入。来自@Tia dupe target 的评论。
【参考方案1】:
很有可能 Veracode 不喜欢您将 SQL 查询像您当前的语句那样放置,而是希望使用它规定的方式来编写此代码。正如documentation in the Repair section 中可见的那样,它希望您使用准备好的语句来创建参数化查询。
现在取决于您的选择。我对此的看法是存储过程会更好,但如果您必须保留query in C#,请不要尝试让一个查询对所有场景和表格都过于通用。
【讨论】:
【参考方案2】:如果您的字符串来自用户输入,那么将字符串连接到 SQL 语句中是有风险的。 虽然您描述的情况并非如此,但我猜 Veracode 工具不知道字符串的来源,它只会看到字符串连接并发出警告。
更好的方法是为每个表编写完整的 SQL 语句(通常我更喜欢使用存储过程,但这是另一个主题 [您可以搜索存储过程与内联 SQL])并使用参数作为值(标识符不能正如您已经发现的那样,在 SQL 中进行参数化)。
所以不是
const string ADD_SQL = "INSERT INTO 0 (ColumnOne) VALUES (@valueOne)";
const string CLEAR_SQL = "DELETE FROM 0";
并在运行时添加表名,这是一个更好的解决方案:
const string ADD_tableName = "INSERT INTO TableName (ColumnOne) VALUES(@ValueOne)"
const string CLEAR_tableName = "DELETE FROM TableName";
还有更好的解决方案,但对于您提供的代码,这是最简单的解决方案。
【讨论】:
以上是关于C# 中查询的 SQL 注入问题的主要内容,如果未能解决你的问题,请参考以下文章