我对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注入安全吗?除了在程序代码中使用该方法之外,不应该有用户输入,但之后没有手动输入。
EDIT:重要的是,我不知道使用的where子句的数量,它可能在1到4 之间
如果通过串联字符串手动构建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;
如果您正确使用实体框架,那么您几乎不必自己编写任何SQLEF将以不受SQL注入影响的方式为您生成它。
只要字符串列表不是由用户输入形成的,就可以安全地进行SQL注入;然而,这仍然是一个糟糕的代码:
- 您不应该选择*From。这很糟糕,因为如果表得到了一个你不需要的新列——它很可能是巨大的二进制数据——你最终会在不需要它的情况下得到它,这会大大降低你的应用程序的速度
- 最好创建一个带有参数的存储过程来过滤数据。这样,您就可以保护您的代码不受SQL注入的影响,并且您仍然可以分支SQL语句以根据传递的参数执行筛选
- 如果在任何时候,您的字符串列表都是从用户输入中收集的,那么您的代码就会受到攻击