EntityFramework Core 2.0执行原始查询如何防止SQL注入?
前言
接下来一段时间我们来讲讲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<TEntity> FromSql<TEntity>([NotNullAttribute] this IQueryable<TEntity> 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注入问题,精简的内容,简单的讲解,希望能帮助到您。我们明天再会。
原文:https://www.cnblogs.com/CreateMyself/p/8481331.html
.NET社区新闻,深度好文,欢迎访问公众号文章汇总 http://www.csharpkit.com
EntityFramework Core 2.0执行原始查询如何防止SQL注入?相关推荐
- EntityFramework Core 2.0自定义标量函数两种方式
前言 上一节我们讲完原始查询如何防止SQL注入问题同时并提供了几种方式.本节我们继续来讲讲EF Core 2.0中的新特性自定义标量函数. 自定义标量函数两种方式 在EF Core 2.0中我们可以将 ...
- EntityFramework Core 3.0 Preview
前段时间.Net Core 3.0 发布了,Entity Framework Core 3.0 也发布了Preview版.假期用了一上午大致研究了一遍,同时又体验了一把Visual Studio 20 ...
- 视图函数中进行sql查询,防止sql注入
视图函数中进行sql查询 import pymysql # 创建连接 use_unicode=true指定字符的编码.解码格式,进行自动编码解码,mysql数据库的编码格式为gbk,而项目数据库为ut ...
- 参数化查询为什么能够防止SQL注入
很多人都知道SQL注入,也知道SQL参数化查询可以防止SQL注入,可为什么能防止注入却并不是很多人都知道的. 本文主要讲述的是这个问题,也许你在部分文章中看到过这块内容,当然了看看也无妨. 首先:我们 ...
- EntityFramework Core 5.0 VS SQLBulkCopy
[导读]EF Core 5.0伴随着.NET 5.0发布已有一段时日,本节我们来预估当大批量新增数据时,大概是多少区间我们应该考虑SQLBulkCopy而不是EF Core SQLBulkCopy早出 ...
- 使用jdbc执行SQL实现登录查询2-避免SQL注入版
配置文件及工具类参考1 package com.jdsc;import javax.rmi.CORBA.Util; import java.sql.*; import java.util.Scanne ...
- PrepareStatement对象(新增、删除、更新、查询、防止SQL注入)
MySQL三十三:PrepareStatement对象 PrepareStatement 可以防止SQL注入,并且效率高! 1.新增 package lesson03;import lesson02. ...
- pdo连接mysql 注入_使用PDO查询mysql避免SQL注入
使用传统的 mysql_connect .mysql_query方法来连接查询数据库时,如果过滤不严紧,就有SQL注入风险.虽然可以用mysql_real_escape_string()函数过滤用户提 ...
- mysql参数化查询为什么可以实现_为什么参数化SQL查询可以防止SQL注入?
SQL 语句文本对于数据库来说,是一种指令,与 Shell 中输入的一条条命令行很类似.我们在 SQL 中混入的各种值就是操作的参数. 考虑一个 WHERE user_id = 10 的筛选,WHER ...
最新文章
- ORACLE JET BASIC TABLE
- Python3.6.4 安装
- MTK6589下传感器框架结构和代码分析以及传感器的参数指标
- 37. Leetcode 100. 相同的树 (二叉树-二叉树性质)
- JSONObject和JSONArray的关系
- java文档注释生产api没有注释_一个神奇的没有springboot注释的api文档生成器---JApiDocs...
- C语言实现去掉字符串中指定的字符
- 你以为熬个3年工作经验就是Java高级开发了?
- 修复Oracle9i中DBA的密码
- java 小数 乘法_javascript(js)的小数点乘法除法-Java架构师必看
- 螺旋矩阵(递归问题)
- 如何理解,互联网架构“高并发”?
- php正则 替换div标签内容,PHP 正则匹配标签内容,根据字符串长度进行替换
- [C/C++11语法]_[0基础]_[lamba 表达式介绍]
- MQ消息队列的优缺点介绍以及对比选型
- 什么是项目管理?怎么管?(一)
- oracle sys改密码,忘记oracle的sys用户密码怎么修改
- 2022年「博客之星」参赛博主:(天寒雨落)在等您评价 ~{附实时总榜单排名}
- 9343拆机 xps13_《拆机Pa》十二期 第二代XPS 13是进步还是退步
- Surround360 README文档——中文翻译
热门文章
- 多线程-单生产单消费模型
- 《Unity着色器和屏幕特效开发秘笈(原书第2版)》一2.9 打包和混合纹理
- IOZONE测试工具使用方法(转载)
- IPV6迎来商业元年 运营商短期盈利模式成难点
- [笔记].STM32 BOOT[0:1]启动设置
- .NET 6新特性试用 | LINQ功能改进
- GitHub Universe 2021|MS Reactor 邀你共聚年度盛会
- 为什么应该用record来定义DTO(续)
- [C#.NET 拾遗补漏]16:几个常见的TAP异步操作
- 很遗憾,总对工作挑挑拣拣的家伙,一般结局都不会太好