在.NET Core项目中,SQL注入往往源于直接拼接用户输入到查询字符串。Entity Framework Core作为主流ORM,本身提供了安全的参数化机制,但错误使用原始SQL方法仍会引入风险。理解其底层命令构造方式,才能彻底修复隐患。

一、识别项目中的SQL注入风险点
很多团队在迁移到EF Core后,以为只要用了ORM就绝对安全,其实不然。EF Core的FromSqlRaw和ExecuteSqlRaw方法如果直接嵌入字符串变量,就会和手写ADO.NET拼接一样危险。例如下面这段代码,用户名来自前端表单,被直接拼进SQL文本:
// 危险示例:字符串拼接导致SQL注入
public User GetUserByRaw(string username)
{
string sql = "SELECT * FROM Users WHERE UserName = '" + username + "'";
return _context.Users.FromSqlRaw(sql).FirstOrDefault();
}
上述写法中,如果用户输入admin' OR '1'='1,最终执行的SQL条件将永远成立,攻击者可以绕过认证或拖库。类似的隐患也出现在动态排序、动态表名等场景中,只要是把外部数据当作SQL文本片段而非参数值处理,就存在漏洞。
除了原始SQL,部分开发者还会用字符串插值误以为安全。EF Core的FromSqlInterpolated确实会把插值转为参数,但若将其强转为FromSqlRaw传入,则插值失效。代码评审时应重点检查所有出现Raw后缀的地方,确认没有字符串相加操作。
二、使用参数化查询修复注入
EF Core推荐使用FromSqlInterpolated或显式SqlParameter来传递外部值。插值方式写法直观,编译器会将其转化为带参数的DbCommand,从根本上避免拼接。以下为修复后的等价代码:
// 安全示例:使用插值自动参数化
public User GetUserSafe(string username)
{
FormattableString sql = $"SELECT * FROM Users WHERE UserName = {username}";
return _context.Users.FromSqlInterpolated(sql).FirstOrDefault();
}
如果必须写复杂原始SQL,应使用FromSqlRaw配合参数数组。这样可以明确控制参数类型和长度,也便于数据库重用执行计划。示例代码如下:
// 显式参数化原始SQL
public User GetUserWithParam(string username)
{
var param = new SqlParameter("@name", System.Data.SqlDbType.NVarChar, 50);
param.Value = username;
return _context.Users
.FromSqlRaw("SELECT * FROM Users WHERE UserName = @name", param)
.FirstOrDefault();
}
对于写操作,ExecuteSqlInterpolated和ExecuteSqlRaw同样遵循该规则。建议统一封装数据访问层,禁止业务代码直接出现Raw加字符串拼接。同时在CI中加入静态扫描,拦截含+拼接且调用Raw方法的提交。
三、通过LINQ与存储过程进一步隔离风险
最稳妥的方式是尽量使用LINQ to Entities,它生成的SQL全部参数化且经编译器检查。例如查询用户列表:
// LINQ自动参数化
public List<User> SearchUsers(string key)
{
return _context.Users
.Where(u => u.UserName.Contains(key))
.ToList();
}
当业务必须依赖存储过程时,可用FromSqlRaw调用并传参,过程内部也应避免动态拼SQL。如下调用方式将参数传给已定义的过程:
// 调用存储过程并传参
public User CallProc(string username)
{
return _context.Users
.FromSqlRaw("EXEC dbo.GetUser @name", new SqlParameter("@name", username))
.AsEnumerable()
.FirstOrDefault();
}
在架构层面,可借助EF Core拦截器对所有即将执行的命令做校验,发现可疑的非参数化语句则抛异常。同时配合最小权限数据库账号,即便万一漏网,攻击者也无法执行DROP等高危指令。通过代码规范、评审工具和运行时防护三层结合,.NET Core项目的SQL注入问题才能被系统性修复。
.NET_CoreSQL注入Entity_Framework_Core修改时间:2026-08-02 03:48:22