我正在修复一些易受sql注入攻击的错误sql查询。大多数是没有输入的直接查询,但我们的搜索字段采用未参数化的搜索项。下面是一个片段:
using (var db = ORMLite.Open())
{
StringBuilder sb = new StringBuilder();
sb.Append("select * from column1, column2");
if (terms.Count() > 0)
{
sb.Append("where (column1 like '%@term0%' or " + column2 + " like '%@term0%') ");
if (terms.Count() > 1)
{
for (int i = 1; i < terms.Count(); i++)
{
sb.Append("and (column1 like '%@term" + i + "%' or " + column2 + " like '%@term" + i + "%') ");
}
}
}
List<POCO> testQuery = db.Select<POCO>(sb.ToString());
}
@term组件是我打算使用参数的地方(它们曾经是'" + term[i] + '"
形式,但是任何带有恶意代码的术语都会被插入。当我转到我的select语句时,我想要添加参数。通常这样做:
列出testQuery = db.Select(sb.ToString(),new {term0 =“t”,term1 =“te”,term2 =“ter”});
但是我可以有任意数量的术语(term.count()是术语的数量)。如何使用任意数量的术语传入匿名对象?或者有更好的方法吗?
答案 0 :(得分:0)
我在Postgresql中寻找几乎相同的东西。基于this SO question 答案看起来像&#34;你必须执行多个查询。&#34;
给定部分参数化,我可以从我的表中获取唯一的行ID 查询,然后直接将这些唯一ID粘贴回查询 - 因为那些 行ID是安全的。
这是我的意思的一个例子,但c#可能是错的(抱歉):
string query = "SELECT unique_id FROM table WHERE (column1 LIKE '%@term%' OR column2 LIKE '%@term%')";
string safeIDs;
List uniqueRowIDs = db.Select(query, new {term = term[0]});
for (int i = 1; i < terms.Count(); i++) {
// Loop to narrow down the rows by adding the additional conditions.
safeIDs = uniqueRowIDs.Aggregate( (current, next) => current + string.Format(", '{0}'", next) );
uniqueRowIDs = db.Select(
query + string.Format(" AND unique_id IN ({0})", safeIDs),
new {term = term[i]});
}
// And finally make the last query for the chosen rows:
safeIDs = uniqueRowIDs.Aggregate( (current, next) => current + string.Format(", '{0}'", next) );
List testQuery = db.Select(string.Format("SELECT * FROM table WHERE unique_id IN ({0});", safeIDs));
您的案例的另一个选择可能是获取所有值
就像使用参数化查询的term0
一样,然后在c#程序中进行比较
所有结果都与用户输入的剩余条款相对应。