这个动态查询容易受到SQL注入的攻击吗?

时间:2020-08-12 09:42:34

标签: c# sql sql-injection

我对使用C#的SQL相当陌生,我需要一些有关SQL注入的建议。

public System.Linq.IQueryable findBy(List<String> lWhere) 
{
        string sWhere;

        foreach (var (sQueryPart, i) in lWhere.Select((Value, i) => (Value, i)))
        {
            if (i == 0) 
            {
                sWhere = sQueryPart;
            }
            else if (i == 1)
            {
                sWhere += " = " + sQueryPart;
            }
            else if (i % 2 == 0)
            {
                sWhere += " and " + sQueryPart;
            } 
            else
            {
                sWhere += " = " + sQueryPart;
            }

        }
        
        return this.TABLE.FromSqlRaw("SELECT * FROM TABLE WHERE {0}", sWhere);
}

此方法获取包含诸如{“ COLUMN1”,“ VALUE1”,“ COLUMN2”,“ VALUE2” ...}等条目的列表

然后,我使用此列表构建Where子句,并将其输入到select语句中。

首先,列表可能会被字典替换,实际上我对此很确定。

第二个问题是,这种方法可以防止SQL注入吗?除了使用程序代码中的方法之外,不应有用户输入,但此后没有任何人工输入。

编辑:重要的是,我不知道所使用的where子句的数量,范围可以从1到4

2 个答案:

答案 0 :(得分:2)

如果通过串联字符串手动构建SQL查询,则很容易受到SQL注入的攻击。句号。

我不明白您为什么还要这样做,因为您的代码暗示您正在使用实体框架。这就在数据库实体上添加了方法,使您可以根据需要动态链接许多.Where()子句,从而完全不需要您自己编写SQL,例如:

var results = dbContext.Table
    .Where(t => t.Column1 == "foo")
    .Where(t => t.Column2 == 42);

将按照以下方式生成并执行SQL:

select *
  from Table
 where Column1 = 'foo'
   and Column2 = 42;

如果您正确使用Entity Framework,则几乎不必自己编写任何SQL。 EF会以不易受到SQL注入影响的方式为您生成它。

答案 1 :(得分:0)

只要不是由用户输入形成字符串列表,就可以安全地进行SQL注入;但是,这仍然是错误的代码:

  1. 您不应选择* From。这很糟糕,因为如果表中有不需要的新列,而且很可能是巨大的二进制数据,那么最终将不需要它就可以获取它,这会大大降低应用程序的速度。
  2. 最好创建一个带有用于过滤数据的参数的存储过程。这样,您就可以保护代码免受SQL注入的侵害,并且仍然可以分支SQL语句以根据传递的参数执行过滤。
  3. 如果在任何时候从用户输入中收集了字符串列表,您的代码将很容易受到攻击。