Подтвердить что ты не робот

Инъекции Dapper и SQL

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

4b9b3361

Ответ 1

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

Это делает действительно, действительно простым в использовании полностью параметризованный доступ к данным, без необходимости связывать входные данные. В частности, поскольку вам не нужно перескакивать через множество "добавить параметр", установить тип параметра, проверить значение "null", поскольку ADO.NET имеет sucky null-handling, rinse/repeat для 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()) {}
    }
}

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

  • нулевое обращение параметров
  • Обработка имен столбцов результатов
  • с использованием индексов порядковых столбцов
  • адаптация к структурным изменениям таблицы и типа
  • преобразование данных столбцов результатов (между различными примитивами, строками, перечислениями и т.д.)
  • специальная обработка сценария oh-so-common "в этом списке"
  • для "execute", специальная обработка "примените это отдельно к списку входов"
  • избегая глупых опечаток
  • сокращение обслуживания кода
  • обработка нескольких сеток
  • обработка нескольких объектов, возвращаемых по горизонтали в одной сетке
  • работает с произвольными поставщиками ADO.NET(подсказка: AddWithValue редко существует)
    • включая определенную поддержку таких вещей, как Oracle, для которой требуется дополнительная настройка
    • отлично работает с ADO.NET decoratos, такими как "мини-профайлер"
  • встроенная поддержка как буферизированных (подходит для небольших и умеренных данных, минимизирует длительность команд), так и non-bufferesd (подходит для больших данных, минимизирует использование памяти).
  • оптимизируется людьми, которые заботятся о производительности и знают "совсем немного" о доступе к данным и метапрограмме
  • позволяет использовать ваш выбор POCO/DTO/anon-type/whatever для параметра и выхода
  • позволяет использовать либо dynamic (для нескольких столбцов), либо примитивы и т.д. (для одного столбца), когда вывод не требует генерации POCO/DTO
  • избегать накладных расходов сложных полностью типизированных ORM, таких как EF
  • избежать накладных расходов слабых типизированных слоев, например DataTable
  • открытие и закрытие соединений как необходимо
  • и широкий спектр других распространенных ошибок

Ответ 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, никаких проблем вообще)

Ответ 3

Да, в первую очередь каждый разработчик должен обеспечить безопасность бизнес-транзакции.

Для этого я всегда предпочитаю использовать storeprocude с dapper, а также метод обтекания для проверки storeprocedure, чтобы предотвратить нежелательные запросы и слова:

private static bool IsStoredProcedureNameCorrect(string storedProcedureName)
        {
            if (string.IsNullOrEmpty(storedProcedureName))
            {
                return false;
            }

            if (storedProcedureName.StartsWith("[") && storedProcedureName.EndsWith("]"))
            {
                return Regex.IsMatch(storedProcedureName,
                    @"^[\[]{1}[A-Za-z0-9_]+[\]]{1}[\.]{1}[\[]{1}[A-Za-z0-9_]+[\]]{1}$");
            }
            return Regex.IsMatch(storedProcedureName, @"^[A-Za-z0-9]+[\.]{1}[A-Za-z0-9]+$");
        }

А также используйте валидатор для предотвращения нежелательных запросов в качестве параметров:

public static partial class Validator
    {
        private static readonly string[] Expressions = {
            @"^.*((?i)select).*((?i)from).*$",
            @"^.*((?i)insert into).*$",
            @"^.*((?i)update).*((?i)set).*$",
            @"^.*((?i)delete from).*$",
            @"^.*((?i)create database).*$",
            @"^.*((?i)create table).*$",
            @"^.*((?i)create procedure).*$",
            @"^.*((?i)create index).*$",
            @"^.*((?i)alter database).*$",
            @"^.*((?i)alter table).*$",
            @"^.*((?i)alter procedure).*$",
            @"^.*((?i)alter index).*$",
            @"^.*\b((?i)exec(ute)?)\b.*$",
            @"^.*((?i)shutdown with nowait).*$",
            @"^.*((?i)waitfor delay).*$",
            @"^.*((?i)drop table).*$"
        };

        public static bool DoesContainQuery(string input)
        {
            var inLowerCase = input.ToLower();
            return Expressions.Any(expression => Regex.IsMatch(inLowerCase, expression));
        }

        public static string ReplaceSqlCharacter(string parameter)
        {
            parameter = parameter.Replace(";", "").Replace("[", "").Replace("]", "").Replace("--", "")
                .Replace("_xp", "").Replace(@"/*", "").Replace(@"*/", "").Replace("@@", "");
            return parameter;
        }
    }

Вы также можете увидеть мой подробный ответ здесь