导读:本期聚焦于小伙伴创作的《.NET Core项目怎么修复SQL注入?使用Entity Framework Core参数化查询的完整指南》,敬请观看详情。把拼接字符串的SQL改成参数化查询,是阻断注入攻击最直接有效的手段。EF Core默认将LINQ翻译成带参数的命令,但开发者若误用FromSqlRaw拼接变量,仍会留下漏洞。本文说明如何用参数化方式与存储过程调用替换危险写法,并给出上下文配置与拦截器层面的防护办法,帮助团队在代码评审与运行时同时降低风险。

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

.NET Core项目怎么修复SQL注入?使用Entity Framework Core参数化查询的完整指南

一、识别项目中的SQL注入风险点

很多团队在迁移到EF Core后,以为只要用了ORM就绝对安全,其实不然。EF Core的FromSqlRawExecuteSqlRaw方法如果直接嵌入字符串变量,就会和手写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();
}

对于写操作,ExecuteSqlInterpolatedExecuteSqlRaw同样遵循该规则。建议统一封装数据访问层,禁止业务代码直接出现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

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。