首页 > 解决方案 > 如何使用条件集合构建 SELECT * WHERE

问题描述

我想使用来自 REST api 的查询字符串的条件列表构建一个 SELECT 语句。我写了这个函数,但它可能容易受到 SQL 注入的攻击。有人可以告诉我这是否易受攻击如何解决?也许我应该使用某种 SQLBuilder 包?或者有没有办法只用 dotNet 来做到这一点。我正在使用 dotNet 4.6.1

    string BuildSelect(NameValueCollection query)
    {
        var result = "SELECT * FROM MYTABLE";
        if (query.Count == 0) return result;
        var logic = " WHERE ";
        foreach (string key in query)
            foreach (string v in query.GetValues(key))
            {
                result += logic + key + " = " + v;
                logic = " AND ";
            }
        return result;
    }

标签: asp.net-web-api2sql-injection

解决方案


是的,它容易受到 SQL 注入攻击。您可以构建查询以改用参数(您只是使用 = 仅检查)。

由于您知道表名,这意味着您也知道列(键)可以是什么。因此,您可以循环您的列,如果集合具有该键,然后将其作为参数化语句添加到 where 但值部分未作为字符串传递,您将其解析为应为的类型(或让后端执行转换并在无法转换时出错)。在伪代码中:

List<string> clauses = new List<string>();
var result = "SELECT * FROM MYTABLE";
foreach( var col in myTable.Columns )
{
   if (query.ContainsKey(col.Name))
   {
        clauses.Add( $"{col.Name} = @{col.Name}";
        string v = query[col.Name];
        command.Parameters.Add( $"@{col.Name}", col.Type).Value = typeParse(v); 
   }
}
if (clauses.Any())
{
   result += " WHERE " + string.Join( " AND ", clauses );
}
return result;

高温高压


推荐阅读