Dapper и SQL-инъекции

Как Dapper помогает защититься от SQL-инъекций? Я тестирую различные технологии DAL и должен выбрать одну из них, чтобы обезопасить наш сайт. Я склоняюсь к Dapper (http://code.google.com/p/dapper-dot-net/), но мне нужна помощь в изучении безопасности.


person cdub    schedule 30.11.2012    source источник


Ответы (2)


Как Dapper помогает защититься от SQL-инъекций?

Это позволяет действительно, очень легко осуществлять полностью параметризованный доступ к данным без необходимости объединения входных данных. В частности, потому что вам не нужно перескакивать через множество «добавить параметр, установить тип параметра, проверить на нуль, потому что ADO.NET плохо обрабатывает нуль, промыть/повторить для 20 параметров» , сделав обработку параметров глупо удобной. Это также позволяет очень легко превращать строки в объекты, избегая соблазна использовать DataTable... выигрывают все.

Из комментариев:

Еще один... что же на самом деле помогает 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()) {}
    }
}

за исключением того, что я сильно упростил, поскольку он также касается широкого круга вопросов, таких как:

  • нулевая обработка параметров
  • нулевая обработка столбцов результатов
  • используя порядковые индексы столбцов
  • адаптация к структурным изменениям базовой таблицы и типа
  • преобразование данных столбцов результатов (между различными примитивами, строками, перечислениями и т. д.)
  • специальная обработка очень распространенного сценария «в этом списке»
  • для «выполнить», специальная обработка «применить это отдельно к списку входов»
  • избегать глупых опечаток
  • сокращение обслуживания кода
  • работа с несколькими сетками
  • обработка нескольких объектов, возвращаемых горизонтально в одной сетке
  • working with arbitrary ADO.NET providers (hint: AddWithValue rarely exists)
    • including specific support for things like Oracle, which needs additional configuration
    • прекрасно работает с декорациями ADO.NET, такими как "мини-профилировщик"
  • встроенная поддержка как буферизованного (подходит для небольших и средних данных; минимизирует продолжительность команды), так и небуферизованного (подходит для больших данных; минимальное использование памяти) доступа
  • оптимизирован людьми, которые заботятся о производительности и знают «довольно немного» как о доступе к данным, так и о метапрограммировании.
  • позволяет вам использовать ваш выбор POCO/DTO/anon-type/что угодно как для параметра, так и для вывода
  • позволяет использовать либо dynamic (для нескольких столбцов), либо примитивы и т. д. (для одного столбца), когда вывод не гарантирует создание POCO/DTO
  • избежать накладных расходов сложных полнотипизированных ORM, таких как EF
  • избегайте накладных расходов на слаботипизированные слои, такие как DataTable
  • открытие и закрытие соединений по мере необходимости
  • и широкий спектр других распространенных ошибок
person Marc Gravell    schedule 01.12.2012
comment
@niico, где он делает что-то, кроме Dog? - person Marc Gravell; 15.05.2016
comment
@niico ах, хорошо, теперь с тобой. Я думаю, что мой глаз автоматически исправил это, когда я прочитал это! Да, так было бы понятнее. Однако обратите внимание, что (как указано) я брал пример из другого ответа, в котором в качестве имени переменной использовалось dog. - person Marc Gravell; 15.05.2016
comment
Используете ли вы Dapper для параметризованных запросов? - person Kiquenet; 14.02.2017

Вам просто нужно использовать параметризованные запросы, как и всегда. Поскольку 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, никаких проблем вообще)

person marc_s    schedule 30.11.2012
comment
Спасибо за ответ на этот вопрос и другой. Еще один... что же на самом деле помогает dapper? - person cdub; 01.12.2012
comment
@Chris: он превращает результат SQL-запроса (см. выше) в красивый, удобный для пользователя объект .NET (например, класс Dog) — вместо того, чтобы оставить вас с кучей строк/столбцов что вам нужно продираться, чтобы понять, что вы получили от SQL .... - person marc_s; 01.12.2012
comment
Тогда мне все равно придется изменить свои sql-запросы в моем коде, чтобы он перешел от нового SqlParameter (...) к более элегантной версии? - person cdub; 01.12.2012
comment
@chris: да, вам придется изменить свои запросы - поскольку метод расширения Dapper живет в SqlConnection - поэтому он не видит ни одного из ваших параметров, определенных в SqlCommand . - person marc_s; 01.12.2012
comment
считается ли это DAL (stackoverflow.com/questions/13653932/)? - person cdub; 01.12.2012
comment
@chris dapper обычно называют библиотекой; обычно люди подразумевают под DAL следующее: вы отделяете код пользовательского интерфейса от кода, который каким-то образом взаимодействует с базой данных. Ваш DAL обычно использует библиотеку для сокращения обслуживания кода, но ваш DAL — это часть, которая ничего не знает о пользовательском интерфейсе, но знает, как называются таблицы/столбцы/процедуры/представления/и т. д. В чем пользовательский интерфейс не должен нуждаться: пользовательский интерфейс должен знать только о модели объекта или (предпочтительно) о модели представления. Не стесняйтесь заменять API веб-сервиса или аналогичный пользовательский интерфейс во всем вышеперечисленном. - person Marc Gravell; 02.12.2012