Dapper 和 SQL 注入

Dapper and SQL injection

提问人:Autunna811 提问时间:12/14/2018 最后编辑:Autunna811 更新时间:12/14/2018 访问量:3788

问:

就我而言,我无法对某些参数(例如过滤器)使用参数化查询,因为过滤器是一个长字符串(而不是单个参数),所以我正在寻找解决方案。我的查询字符串中有以下代码片段。我试过把“@filter”,但似乎 dapper 首先原始查询字符串。

例如,我不能设置“....列 = @value“,因为我的列表的过滤器可能会像包含一样发生变化,以.....

queryString = @"SELECT 
                    R.RequestId As requestId, 
                    R.Number AS number, 
                    R.CargoReadyDate AS readyDate, 
                    PL.Name AS portIdOfLoading,  
                    PD.Name AS portIdOfDischarge,  
                    R.Status AS status,  
                    R.AllInFreightAmount_Value AS requestAmount , 
                    R.CreatedDate AS requestDate, 
                    R.AllInFreightAmount_Currency as currency 
                FROM 
                    Requests R  
                JOIN
                    [Ports] PL ON R.PortIdOfLoading = PL.PortId 
                JOIN
                    [Ports] PD ON R.PortIdOfDischarge = PD.PortId  
                WHERE 
                    R.ShipperId = @accountId And " + statusFilter + filter + " " +
              @"ORDER BY 
                    R.CreatedDate DESC 
                    OFFSET @pageSize * (@pageNumber - 1) ROWS 
                    FETCH NEXT @pageSize ROWS ONLY ";

var data = _dapperService.QueryDataSet<RequestDto>(queryString,
            new { accountId = query.AccountId, status = query.RequestStatus, pageSize = query.PageSize, pageNumber = query.PageNumber }, CommandType.Text);

return data;
.NET SQL 注入 dapper

评论

0赞 Autunna811 12/14/2018
我知道,所以我正在寻找解决方案。此查询用于列表,因此过滤器可以更改,我不能将其设置为常量参数。

答:

1赞 Marc Gravell 12/14/2018 #1

归根结底,Dapper 无法帮助处理实际参数化步骤之外发生的任何事情;如果你在把它交给 Dapper 之前引入 SQL 注入孔:是的,你会有 SQL 注入孔。

不过,您仍然可以将 Dapper 与重要的查询一起使用;您仍然可以参数化。例如,您可以执行以下操作:

int? userId = /* something, could be null */
string region = /* something, could be null */

var sql = new StringBuilder(@"select ... /* whatever */ where Open = 1");
if (userId != null) sql.Append(" and UserId = @userId");
if (region != null) sql.Append(" and Region = @region");
// ... etc

var data = conn.Query<SomeType>(sql.ToString(), new { userId, region }).AsList();

在这里,Dapper 将只添加它在查询中实际看到的参数;因此,如果未出现,则不会添加该参数。但至关重要的是:查询仍然是完全参数化的,并且没有 SQL 注入漏洞。@userId

对于更复杂的场景,Dapper 还支持类似字典的参数,因为您需要按需添加参数,而不是静态添加参数。