【问题标题】:Dapper and SQL InjectionsDapper 和 SQL 注入
【发布时间】:2012-11-19 03:50:59
【问题描述】:

Dapper 如何帮助防止 SQL 注入?我正在测试不同的 DAL 技术,并且必须选择一种来保护我们的站点。我倾向于 Dapper (http://code.google.com/p/dapper-dot-net/),但需要一些帮助来了解安全性。

【问题讨论】:

    标签: .net orm .net-3.5 dapper


    【解决方案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”。
    猜你喜欢
    • 2014-07-16
    • 2012-05-20
    • 2021-06-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多