FromSql():从字符串列表构建查询字符串以防止注入
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了FromSql():从字符串列表构建查询字符串以防止注入相关的知识,希望对你有一定的参考价值。
我正在EF Core中构建SQL搜索。 Microsoft建议您不要连接字符串,因为它会使应用程序容易受到SQL注入攻击,详见Microsoft文档:https://docs.microsoft.com/en-us/ef/core/querying/raw-sql。
始终对原始SQL查询使用参数化:除了验证用户输入外,还始终对原始SQL查询/命令中使用的任何值使用参数化。接受原始SQL字符串(如FromSql和ExecuteSqlCommand)的API允许将值作为参数轻松传递。接受FormattableString的FromSql和ExecuteSqlCommand的重载也允许以有助于防止SQL注入攻击的方式使用字符串插值syntaxt。
如果您使用字符串连接或插值来动态构建查询字符串的任何部分,或将用户输入传递给可以作为动态SQL执行这些输入的语句或存储过程,那么您负责验证任何输入以防止SQL注入攻击。
存储在此数据库中的信息不敏感,但显然我不想让数据库容易受到攻击。
我有一个param List<string> searchTerms
,我需要迭代并基于此列表构建查询。
我将和我的SQL查询一起使用字符串,但我只能看到如何通过连接来完成此操作。现在我的代码看起来像这样。
var query = String.Format("SELECT ... where mysqlField like '%{0}%'", searchTerm[0]);
for (int i = 1; i < searchTerm.Count(); i++)
{
query += String.Format(" and MySqlField like '%{0}%'", searchTerm[i]);
}
var results = context.MySqlTable.FromSql(query);
即使我使用插值,这里还有额外的验证吗?我错过了什么吗?
是否有一个linq查询可以对列表做同样的事情?
您的代码应该足够好并进行一些修改:
var query = String.Format("SELECT ... where 1=1 ");
for (int i = 0; i < searchTerm.Count(); i++)
{
query += $" and MySqlField like '%'+{{{i}}}+'%'";
}
var results = context.MySqlTable.FromSql(query, searchTerm.ToArray());
几乎没有选择:
- 以XML格式传递您的值(如果使用较新的SQL Server,则传递JSON),然后编写静态XML / JSON查询。
- 创建临时表,在临时表中插入所有搜索值,然后执行静态查询。
我现在无法测试它,所以我让你知道这种方法
List<string> ph = new List<string>();
int count = 0;
foreach(string s in searchTerm)
{
ph.Add($"MySqlField LIKE '%{{{count}}}%'");
count++;
}
if(count > 0)
query = query + " WHERE " + string.Join(" OR ", ph);
var results = context.MySqlTable.FromSql(query, searchTerm.ToArray());
虽然它看起来像字符串连接方法,但我们可以在docs中读到
虽然这可能看起来像String.Format语法,但提供的值包含在参数中,并且生成的参数名称插入到指定了{0}占位符的位置。
如果您使用EF,我建议您查看LINQ。对于安全性和性能,使用原始字符串sql不是一个好主意。 LINQ提供了一种执行查询的强大方法。只要小心你如何编写查询,因为LINQ可以试图过度复杂化它们。
https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/linq/
编辑:
我错过了你帖子的最后一行。抱歉,以下内容可帮助您走上正轨:
for (var item in searchTerms) {
query = query.Where(w => w.MySqlField.Contains(item.Value));
}
以上是关于FromSql():从字符串列表构建查询字符串以防止注入的主要内容,如果未能解决你的问题,请参考以下文章
在执行查询之前,如何从 Laravel 的查询构建器中获取原始查询字符串?
我正在寻找一种从字符串构建 IQueryable 查询的方法