【问题标题】:SQL Injection issue with the query in C#C# 中查询的 SQL 注入问题
【发布时间】: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 为什么在您可能知道表名无法参数化时建议重复参数?
  • 您应该始终使用参数化查询,搜索参数化查询以获得更多详细信息
  • @jimmi94 显示示例比建议无法完成的事情要有用得多...stackoverflow.com/questions/3128582/… 可能是您可以为表名做的最好的事情,如果您必须插入它们。 .
  • @LahiruD, SELECT table_name FROM INFORMATION_SCHEMA.TABLES WHERE table_name=@Param 现在你很确定没有 sql 注入。来自@Tia dupe target 的评论。

标签: c# sql-injection veracode


【解决方案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";
    

    还有更好的解决方案,但对于您提供的代码,这是最简单的解决方案。

    【讨论】:

      猜你喜欢
      • 2023-02-03
      • 2015-03-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-07-20
      • 1970-01-01
      • 2021-12-02
      相关资源
      最近更新 更多