热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

EntityFrameworkCore2.0执行原始查询如何防止SQL注入?

前言接下来一段时间我们来讲讲EntityFrameworkCore基础,精简的内容,深入浅出,希望为想学习EntityFrameworkCore的童鞋提供一点帮助。EntityFr

前言

接下来一段时间我们来讲讲EntityFramework Core基础,精简的内容,深入浅出,希望为想学习EntityFramework Core的童鞋提供一点帮助。

EntityFramework Core执行原始查询

在EntityFramework Core中执行原始查询我们借助FromSql来实现,如下:

            using (var cOntext= new EFCoreDbContext())
            {
                var orders = context.Orders
                    .FromSql("SELECT * FROM dbo.Orders")
                    .ToList();
            }    

技术分享图片

这是最简单且不带任何条件的查询方式,接下来我们看看有条件的查询我们应该如何查询,如下:

            using (var cOntext= new EFCoreDbContext())
            {
                var parameters = new SqlParameter[]
                {
                    new SqlParameter(){ ParameterName = "@p0", Value = 1, SqlDbType = System.Data.SqlDbType.Int }
                };

                var orders = context.Orders
                    .FromSql("SELECT * FROM dbo.Orders WHERE Id = @p0", parameters)
                    .ToList();
            }

技术分享图片

除了以上利用参数化查询方式外,若我们还借助string.format或者C# 6.0出现的新特性字符串插值即美元符号$来查询最终生成的SQL是否仍然是以参数化查询呢,我们来看看。

            using (var cOntext= new EFCoreDbContext())
            {

                var orders = context.Orders
                    .FromSql($"SELECT * FROM dbo.Orders WHERE Id = {1}")
                    .ToList();
            }

技术分享图片

由上我们看出即使利用字符串插值最终仍然翻译成参数化SQL。接下来我们再来看看字符串拼接查询方式。

            using (var cOntext= new EFCoreDbContext())
            {

                var searchString = "Jeffcky";

                var blogs = context.Blogs
                    .FromSql("SELECT Id, Name, CreatedTime, Url, ModifiedTime FROM dbo.Blogs " +
                    "WHERE Name = ‘" + searchString + "")
                    .ToList();
            }

技术分享图片

此时我们通过控制台打印能够看出最终生成的SQL语句是以字符串形式展示,在EntityFramework Core 2.0+上执行原始查询的APi即FromSql有重载方法,如下:

public static IQueryable FromSql([NotNullAttribute] this IQueryable source, [NotNullAttribute][NotParameterized] FormattableString sql) where TEntity : class;

我们利用上述FromSql重载方法传递字符串参数,同时在查询字符串中添加对数据库表操作,验证EF Core是否能防止SQL注入。

            using (var cOntext= new EFCoreDbContext())
            {

                var searchString = "Jeffcky; DROP TABLE dbo.Blogs;";

                var blogs = context.Blogs
                    .FromSql("SELECT Id, Name, Url, CreatedTime, ModifiedTime FROM dbo.Blogs "
                    + " WHERE Name = {0}", searchString)
                    .ToList();
            }

技术分享图片

经过验证您会发现上述我们注入上述Blogs表的SQL语句,最终表将不会删除。我们看到当未利用重载方法进行字符串拼接,此时参数将以字符串形式展示,这种情况极易引起SQL注入问题。C# 6.0引入了字符串插值(String Interpolation),此特性能够允许C#表达式直接嵌入到字符串文本中,为运行时构建字符串提供了一个很好的方法。在EF Core 2.0特性中,对FromSql和ExecuteSqlCommand方法都添加了对插入字符串的特殊支持。此新特性的支持允许以安全的方式使用C#字符串插值。即防止在运行时动态构建SQL时可能发生SQL注入问题。

是不是到了这里就这样结束了呢?显然不是这样,接下来咱们再来看看另外一种情况,如下:

            using (var cOntext= new EFCoreDbContext())
            {

                var author = "Jeffcky Wang";
                var query = $"SELECT * FROM Blogs WHERE Name = {author}";
                var blogs = context.Blogs.FromSql(query).ToList();
            }

技术分享图片

技术分享图片

这样的语法错误显而易见,我们需要用单引号将变量包含起来才能避免语法错误,如下:

            using (var cOntext= new EFCoreDbContext())
            {

                var author = "Jeffcky Wang";
                var query = $"SELECT * FROM Blogs WHERE Name = ‘{author}‘";
                var blogs = context.Blogs.FromSql(query).ToList();
            }

上述情况下,EF Core依然将执行明文字符串而不是作为变量查询并未以参数化执行。如果变量包含恶意字符串,那么EF Core将根本无法防范并保护SQL。因此,如果我们需要通过EF Core执行原始T-SQL,则应使用参数化SQL或利用FormatttableString,FromSql有两个重载,其一为通过FormatttableString可格式化字符串参数,其二为原始字符串且可传递查询参数。所以上述错误,我们可利用FormatttableString来执行,同时在利用FromSql方法查询过后我们仍可以继续进行查询,比如如下关联查询Posts表数据。

            using (var cOntext= new EFCoreDbContext())
            {

                var searchString = "Jeffcky Wang";

                FormattableString sql = $@"SELECT Id, Name, Url, CreatedTime, ModifiedTime FROM dbo.Blogs WHERE Name = {searchString}";

                var blogs = context.Blogs
                    .FromSql(sql)
                    .Include(d => d.Posts)
                    .ToList();
            }

技术分享图片

通过【$@】并利用FormattableString重载或者传递参数化变量来防止SQL注入问题,希望您发现EF Core 2.0中这个新特性,同时不要忘记它也用来承担更大的责任,由于SQL注入攻击,不会让我们所写代码存在漏洞。

总结

本节我们详细讲解了EF Core 2.0中执行原始查询如何防止SQL注入问题,精简的内容,简单的讲解,希望能帮助到您。我们明天再会。

EntityFramework Core 2.0执行原始查询如何防止SQL注入?


推荐阅读
  • 本文介绍了C#中数据集DataSet对象的使用及相关方法详解,包括DataSet对象的概述、与数据关系对象的互联、Rows集合和Columns集合的组成,以及DataSet对象常用的方法之一——Merge方法的使用。通过本文的阅读,读者可以了解到DataSet对象在C#中的重要性和使用方法。 ... [详细]
  • 本文内容为asp.net微信公众平台开发的目录汇总,包括数据库设计、多层架构框架搭建和入口实现、微信消息封装及反射赋值、关注事件、用户记录、回复文本消息、图文消息、服务搭建(接入)、自定义菜单等。同时提供了示例代码和相关的后台管理功能。内容涵盖了多个方面,适合综合运用。 ... [详细]
  • Mac OS 升级到11.2.2 Eclipse打不开了,报错Failed to create the Java Virtual Machine
    本文介绍了在Mac OS升级到11.2.2版本后,使用Eclipse打开时出现报错Failed to create the Java Virtual Machine的问题,并提供了解决方法。 ... [详细]
  • 本文详细介绍了Linux中进程控制块PCBtask_struct结构体的结构和作用,包括进程状态、进程号、待处理信号、进程地址空间、调度标志、锁深度、基本时间片、调度策略以及内存管理信息等方面的内容。阅读本文可以更加深入地了解Linux进程管理的原理和机制。 ... [详细]
  • 1,关于死锁的理解死锁,我们可以简单的理解为是两个线程同时使用同一资源,两个线程又得不到相应的资源而造成永无相互等待的情况。 2,模拟死锁背景介绍:我们创建一个朋友 ... [详细]
  • 后台获取视图对应的字符串
    1.帮助类后台获取视图对应的字符串publicclassViewHelper{将View输出为字符串(注:不会执行对应的ac ... [详细]
  • 《数据结构》学习笔记3——串匹配算法性能评估
    本文主要讨论串匹配算法的性能评估,包括模式匹配、字符种类数量、算法复杂度等内容。通过借助C++中的头文件和库,可以实现对串的匹配操作。其中蛮力算法的复杂度为O(m*n),通过随机取出长度为m的子串作为模式P,在文本T中进行匹配,统计平均复杂度。对于成功和失败的匹配分别进行测试,分析其平均复杂度。详情请参考相关学习资源。 ... [详细]
  • 深入理解CSS中的margin属性及其应用场景
    本文主要介绍了CSS中的margin属性及其应用场景,包括垂直外边距合并、padding的使用时机、行内替换元素与费替换元素的区别、margin的基线、盒子的物理大小、显示大小、逻辑大小等知识点。通过深入理解这些概念,读者可以更好地掌握margin的用法和原理。同时,文中提供了一些相关的文档和规范供读者参考。 ... [详细]
  • Redis底层数据结构之压缩列表的介绍及实现原理
    本文介绍了Redis底层数据结构之压缩列表的概念、实现原理以及使用场景。压缩列表是Redis为了节约内存而开发的一种顺序数据结构,由特殊编码的连续内存块组成。文章详细解释了压缩列表的构成和各个属性的含义,以及如何通过指针来计算表尾节点的地址。压缩列表适用于列表键和哈希键中只包含少量小整数值和短字符串的情况。通过使用压缩列表,可以有效减少内存占用,提升Redis的性能。 ... [详细]
  • 本文介绍了lua语言中闭包的特性及其在模式匹配、日期处理、编译和模块化等方面的应用。lua中的闭包是严格遵循词法定界的第一类值,函数可以作为变量自由传递,也可以作为参数传递给其他函数。这些特性使得lua语言具有极大的灵活性,为程序开发带来了便利。 ... [详细]
  • 本文分享了一个关于在C#中使用异步代码的问题,作者在控制台中运行时代码正常工作,但在Windows窗体中却无法正常工作。作者尝试搜索局域网上的主机,但在窗体中计数器没有减少。文章提供了相关的代码和解决思路。 ... [详细]
  • 本文介绍了使用Java实现大数乘法的分治算法,包括输入数据的处理、普通大数乘法的结果和Karatsuba大数乘法的结果。通过改变long类型可以适应不同范围的大数乘法计算。 ... [详细]
  • HDU 2372 El Dorado(DP)的最长上升子序列长度求解方法
    本文介绍了解决HDU 2372 El Dorado问题的一种动态规划方法,通过循环k的方式求解最长上升子序列的长度。具体实现过程包括初始化dp数组、读取数列、计算最长上升子序列长度等步骤。 ... [详细]
  • 本文讨论了如何优化解决hdu 1003 java题目的动态规划方法,通过分析加法规则和最大和的性质,提出了一种优化的思路。具体方法是,当从1加到n为负时,即sum(1,n)sum(n,s),可以继续加法计算。同时,还考虑了两种特殊情况:都是负数的情况和有0的情况。最后,通过使用Scanner类来获取输入数据。 ... [详细]
  • CentOS 6.5安装VMware Tools及共享文件夹显示问题解决方法
    本文介绍了在CentOS 6.5上安装VMware Tools及解决共享文件夹显示问题的方法。包括清空CD/DVD使用的ISO镜像文件、创建挂载目录、改变光驱设备的读写权限等步骤。最后给出了拷贝解压VMware Tools的操作。 ... [详细]
author-avatar
嗯呢
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有