Dapper 和 SQL 注入
Posted
技术标签:
【中文标题】Dapper 和 SQL 注入【英文标题】:Dapper and SQL Injections 【发布时间】:2012-11-19 03:50:59 【问题描述】:Dapper 如何帮助防止 SQL 注入?我正在测试不同的 DAL 技术,并且必须选择一种来保护我们的站点。我倾向于 Dapper (http://code.google.com/p/dapper-dot-net/),但需要一些帮助来了解安全性。
【问题讨论】:
【参考方案1】:Dapper 如何帮助防止 SQL 注入?
它非常非常可以轻松地进行完全参数化的数据访问,而无需连接输入。特别是,因为您不需要跳过大量“添加参数、设置参数类型、检查 null 因为 ADO.NET 有糟糕的 null 处理,冲洗/重复 20 个参数” , 通过使参数处理愚蠢方便。它还使将行转换为对象变得非常容易,避免使用DataTable
的诱惑......每个人都赢了。
来自 cmets:
还有一个……那么 dapper 究竟能帮什么忙呢?
为了回答,让我们以marc_s的回复为例,用旧的方式写,假设我们必须从connection
开始。然后是:
List<Dog> dogs = new List<Dog>();
using(var cmd = connection.CreateCommand())
cmd.CommandText = "select Age = @Age, Id = @Id";
cmd.Parameters.AddWithValue("Age", DBNull.Value);
cmd.Parameters.AddWithValue("Id", guid);
using(var reader = cmd.ExecuteReader())
while(reader.Read())
int age = reader.ReadInt32("Age");
int id = reader.ReadInt32("Id");
dogs.Add(new Dog Age = age, Id = id );
while(reader.NextResult())
除了我过于简单化了,因为它还处理了广泛的问题,例如:
参数的空处理 结果列的空处理 使用序数列索引 适应基础表和类型的结构变化 结果列的数据转换(各种原语、字符串、枚举等之间) 非常常见的“在此列表中”场景的特殊处理 对于“执行”,“将其单独应用于输入列表”的特殊处理 避免愚蠢的拼写错误 减少代码维护 处理多个网格 处理在单个网格中水平返回的多个对象 使用任意 ADO.NET 提供程序(提示:AddWithValue
很少存在)
包括对 Oracle 等需要额外配置的特定支持
与 ADO.NET 装饰器(例如“mini-profiler”)完美搭配
内置支持缓冲(适用于中小型数据;最小化命令持续时间)和非缓冲(适用于大数据;最小化内存使用)访问
由关心性能并“相当了解”数据访问和元编程的人优化
允许您选择 POCO / DTO / anon-type / 不管参数和输出
当输出不能保证生成 POCO/DTO 时,允许使用 dynamic
(用于多列)或原语等(用于单列)
避免像 EF 这样的复杂全类型 ORM 的开销
避免像DataTable
这样的弱类型层的开销
根据需要打开和关闭连接
以及大量其他常见问题
【讨论】:
@niico 它在哪里做了不是Dog
的事情?
@niico 啊,对,现在和你在一起。我想当我阅读它时,我的眼睛会自动纠正它!是的,这样会更清楚。但是请注意,(如前所述)我是从另一个使用dog
作为变量名的答案中获取的示例。
现在,您是否使用 Dapper 进行参数化查询?【参考方案2】:
您只需要像往常一样使用参数化查询。由于 Dapper 只是对“原始”SQL 和 ADO.NET 的“小”(而且非常薄)扩展 - 只需使用参数化的 ADO.NET 查询并提供参数。
从 Dapper-Dot-Net 站点查看此示例:
var dog = connection.Query<Dog>("select Age = @Age, Id = @Id",
new Age = (int?)null, Id = guid );
SQL 查询使用参数 - 您将这些参数提供给“Dapper”查询。
总结一下:使用 Dapper 本身并不能帮助防止 SQL 注入 - 但是使用 参数化 ADO.NET/SQL 查询可以(而且 Dapper 绝对支持这些查询,没有问题完全)
【讨论】:
感谢这个问题的答案和另一个。还有一个……那么 dapper 究竟能帮什么忙呢? @Chris:它将 SQL 查询的结果(见上文)转换为 用户友好的 .NET 对象(如Dog
类) - 相反给你留下一堆行/列,你必须费力地弄清楚你从 SQL 中得到了什么......
我将不得不在我的代码中更改我的 sql 查询,然后让它从新的 SqlParameter(...) 到 dapper 版本?
@chris: 是的,您将不得不更改您的查询 - 因为 Dapper 扩展方法“存在”在 SqlConnection
上 - 所以它看不到您在 @987654324 上定义的任何参数@.
@chris "dapper" 通常被称为 library;通常,人们所说的 DAL 的意思是:您已将 UI 代码与 以某种方式 与数据库通信的代码分开。您的 DAL 通常会使用库来减少代码维护,但您的 DAL 对 UI一无所知,但知道表/列/过程/视图/等的名称。 UI 不需要:UI 只需要了解实体模型或(首选)视图模型。在上述所有内容中,请随意用“Web 服务 API”或类似内容替换“UI”。以上是关于Dapper 和 SQL 注入的主要内容,如果未能解决你的问题,请参考以下文章
NetCore+Dapper WebApi架构搭建:仓储的依赖注入
NetCore+Dapper WebApi架构搭建:仓储的依赖注入