在ORMLite Query中使用任意数量的参数

时间:2014-11-12 00:02:29

标签: c# sql-server sqlcommand ormlite-servicestack

我正在修复一些易受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()是术语的数量)。如何使用任意数量的术语传入匿名对象?或者有更好的方法吗?

1 个答案:

答案 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#程序中进行比较 所有结果都与用户输入的剩余条款相对应。