Dapper and SQL injection



在我的情况下,我不能对一些参数(如filter(使用参数化查询,因为filter是一个长字符串(而不是单个参数(,所以我正在为此寻找解决方案。我的查询字符串中有以下代码片段。我试过放"@filter",但似乎dapper先处理了查询字符串。

例如,我不能设置"….Column=@value",因为我的列表的过滤器可能会像contain一样更改,以…开头。。。。。

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;

最终,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将只添加它在查询中实际看到使用的参数;因此,如果@userId没有出现,它就不会添加该参数。但至关重要的是:查询仍然是完全参数化的,并且没有SQL注入漏洞。

对于更复杂的场景,Dapper还支持类似字典的参数,用于需要按需而非静态添加参数的情况。

最新更新