警告:SQL 注入攻击

Warning: SQL injection attacks

提问人: 提问时间:8/20/2020 更新时间:8/20/2020 访问量:344

问:

我一直在尝试使我的代码适应 FxCop 规则,我发现了这个警告:CA2100 查看在“WavesShaperNew.Parse(string, int)”中传递给“OleDbDataAdapter.OleDbDataAdapter(string, OleDbConnection)”的查询字符串,以了解可能的 SQL 注入攻击。如果字符串是使用任何用户输入编写的,请考虑使用存储过程或参数化 SQL 查询,而不是使用字符串连接生成查询。

我已经在Microsoft官方网站和类似的问题中搜索过,但仍然不明白这个警告是什么意思以及如何解决它。

ComboBox sheets = new ComboBox();
TextBox startRange = new TextBox();
TextBox endRange = new TextBox();

string query = string.Format("SELECT * FROM[" + sheets.SelectedItem + startRange.Text + ":" + endRange.Text + "]");
query = query.Replace("'", "");

OleDbDataAdapter adapter = new OleDbDataAdapter(query, con);
C# 互操作 FXCOP

评论

4赞 TheGeneral 8/20/2020
SELECT * FROM customers; delete from customers; blah blah blah你刚刚失去了所有的客户......当你发现自己从用户输入和原始 sql 构建参数时,你就把自己打开了一个受伤的世界。解决方法是 ALLWAYS 使用参数化查询
0赞 TheGeneral 8/20/2020
或以另一种方式显示
0赞 Johnathan Barclay 8/20/2020
@MichaelRandall 这里唯一的问题是表名不能参数化。避免SQL注入的方法是将表名列入白名单。
0赞 8/20/2020
@JohnathanBarclay,将表名列入白名单会是什么样子?

答:

0赞 Johnathan Barclay 8/20/2020 #1

通常应将所有 SQL 查询参数化以避免 SQL 注入攻击,而不是使用字符串连接/插值。

但是,不能参数化表名。

为了避免此处的 SQL 注入,您可以将有效的表名列入白名单:

var queryableTables = new HashSet<string>
{
    "table1",
    "table2",
    // etc.
};

string tableName = sheets.SelectedItem + startRange.Text;

if (!queryableTables.Contains(tableName))
{
    throw new InvalidOperationException($"{tableName} is not queryable");
}

string query = $"SELECT * FROM [{tableName}]");

评论

0赞 oerkelens 8/20/2020
这不是很有效。“表1;delete from table1;“仍然是有效的输入,因为它包含有效的表名。
0赞 Johnathan Barclay 8/20/2020
@oerkelens 不,不是。 这里不是.您的逻辑将应用于 .ContainsHashSet<T>.Containsstring.ContainsqueryableTables.Any(tableName.Contains)