使用EF Core SqlQuery传递参数能否防范SQL注入?
EF Core SqlQuery写法的SQL注入风险分析
你当前的写法无法防范SQL注入,问题出在字符串插值的使用方式上:
你虽然创建了SqlParameter对象,但用$""字符串插值把page_param和pageSize_param直接拼进SQL语句时,实际上是调用了SqlParameter.ToString()方法,把参数对象转成了类似@page_param的字符串——这并不是真正的参数化传递,EF Core不会识别这种拼接出来的参数名,最终执行时还是会把参数值直接拼进SQL,完全失去了参数化查询的安全防护作用。
正确的安全写法
写法1:用命名参数占位符+传递参数数组
var page_param = new SqlParameter("page_param", page); var pageSize_param = new SqlParameter("pageSize_param", pageSize); var users = _context!.Database.SqlQuery<UserDTO>( @"SELECT u.Id,u.FirstName,u.LastName,u.JoinDate,u.UserName,u.Email,u.EmailConfirmed,u.PhoneNumber,r.Name as Role FROM Users as u inner join UserRoles as ur on u.Id = ur.UserId inner join Roles r on ur.RoleId = r.Id order by u.JoinDate OFFSET @page_param ROWS FETCH NEXT @pageSize_param ROWS ONLY ", page_param, pageSize_param );
写法2:直接用FormattableString(推荐,更简洁)
EF Core支持直接解析FormattableString类型的SQL,会自动把插值变量转换成参数化查询:
var users = _context!.Database.SqlQuery<UserDTO>( @"SELECT u.Id,u.FirstName,u.LastName,u.JoinDate,u.UserName,u.Email,u.EmailConfirmed,u.PhoneNumber,r.Name as Role FROM Users as u inner join UserRoles as ur on u.Id = ur.UserId inner join Roles r on ur.RoleId = r.Id order by u.JoinDate OFFSET {page} ROWS FETCH NEXT {pageSize} ROWS ONLY " );
这里直接用{page}和{pageSize}做插值,EF Core会自动将它们包装成安全的SqlParameter,彻底避免SQL注入风险。
内容的提问来源于stack exchange,提问作者user18080571
相关产品推荐
相关产品推荐

