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 注入的主要内容,如果未能解决你的问题,请参考以下文章

使用dapper进行参数化查询

.net core 3.1 加入ORM框架(Dapper)

NetCore+Dapper WebApi架构搭建:仓储的依赖注入

NetCore+Dapper WebApi架构搭建:仓储的依赖注入

Zoey.Dapper--Dapper扩展之把SQL语句放到文件中

使用dapper时动态拼接查询sql有啥好的方法吗