Regex для обнаружения SQL-инъекций в WinForms

Я хочу кэшировать ввод, который похож на SQL-инъекцию. Поэтому я написал метод:

        public static bool IsInjection(string inputText)
    {


        bool isInj = false;


        string regexForTypicalInj = @"/\w*((\%27)|(\'))((\%6F)|o|(\%4F))((\%72)|r|(\%52))/ix";
        Regex reT = new Regex(regexForTypicalInj);
        if (reT.IsMatch(inputText))
            isInj = true;


        string regexForUnion = @"/((\%27)|(\'))union/ix";
        Regex reUn = new Regex(regexForUnion);
        if (reUn.IsMatch(inputText))
            isInj = true;



        string regexForSelect = @"/((\%27)|(\'))select/ix";
        Regex reS = new Regex(regexForSelect);
        if (reS.IsMatch(inputText))
            isInj = true;

        string regexForInsert = @"/((\%27)|(\'))insert/ix";
        Regex reI = new Regex(regexForInsert);
        if (reI.IsMatch(inputText))
            isInj = true;

        string regexForUpdate = @"/((\%27)|(\'))update/ix";
        Regex reU = new Regex(regexForUpdate);
        if (reU.IsMatch(inputText))
            isInj = true;

        string regexForDelete = @"/((\%27)|(\'))delete/ix";
        Regex reDel = new Regex(regexForDelete);
        if (reDel.IsMatch(inputText))
            isInj = true;

        string regexForDrop = @"/((\%27)|(\'))drop/ix";
        Regex reDr = new Regex(regexForDrop);
        if (reDr.IsMatch(inputText))
            isInj = true;

        string regexForAlter = @"/((\%27)|(\'))alter/ix";
        Regex reA = new Regex(regexForAlter);
        if (reA.IsMatch(inputText))
            isInj = true;

        string regexForCreate = @"/((\%27)|(\'))create/ix";
        Regex reC = new Regex(regexForCreate);
        if (reC.IsMatch(inputText))
            isInj = true;

        return isInj;

    }

Но, кажется, я сделал несколько ошибок, потому что мой код не обнаруживает инъекции. Что я делаю неправильно? Я предполагаю, что что-то не так в определении выражений Regex?


person vts123    schedule 24.02.2010    source источник
comment
По какой причине вы вообще не используете параметризованные запросы?   -  person JasonTrue    schedule 25.02.2010
comment
Точно. Параметризованные запросы = очищены. Игра с регулярными выражениями для выполнения работы синтаксического анализатора = безумие.   -  person JasonTrue    schedule 25.02.2010
comment
Я делаю это в исследовательских (научных) целях. Моя структура позже будет использоваться для разработки приложений Win Forms. Другие разработчики часто являются новичками и иногда не используют параметры. Итак, сначала мне нужно как-то сделать защиту в коде C#.   -  person vts123    schedule 25.02.2010
comment
@ Vytas999 Vytas999 - А теперь вы можете использовать параметры под капотом в своей структуре?   -  person Oded    schedule 25.02.2010
comment
Мне кажется, что обнаружение того, что кто-то использует конкатенацию строк для построения SQL-запросов, и сообщение об этом как о возможной угрозе безопасности в статическом анализе кода более полезно, чем попытки обойти такие ошибки.   -  person JasonTrue    schedule 25.02.2010


Ответы (4)


Не пытайтесь сделать это с помощью RegEx — существует слишком много способов обойти это. См. этот классический ответ SO об анализе с помощью RegEx - это специфично для HTML, но все еще применимо.

Вы должны использовать параметры, они находятся в BCL и имеют анти-SQL встроенные инъекционные меры.

Обновление: (после комментариев)

Если вам действительно необходимо проанализировать SQL, не используйте RegEx по причинам, изложенным в связанной статье. RegEx не является синтаксическим анализатором и не должен использоваться как таковой.

Используйте синтаксический анализатор SQL — это должно помочь при попытках очистки. Вот один, здесь другой.

Вы можете продолжить свои научные исследования с ними.

person Oded    schedule 24.02.2010
comment
Я делаю это в исследовательских (научных) целях. Моя структура позже будет использоваться для разработки приложений Win Forms. Другие разработчики часто являются новичками и иногда не используют параметры. Итак, сначала мне нужно как-то сделать защиту в коде C#. - person vts123; 25.02.2010
comment
@ Vytas999 Vytas999 - я обновил свой ответ после вашего комментария. - person Oded; 25.02.2010

Не используйте синтаксический анализ строк или регулярные выражения для обработки подобных вещей. Синтаксис SQL слишком сложен для надежного анализа с помощью регулярных выражений.

Вместо этого используйте параметризованные запросы с заполнителями и вообще избегайте конкатенации строк. Это позволит победить SQL-инъекцию в корне.

var command = new SqlCommand(connection);
command.Text = "INSERT INTO foo (a, b, c) VALUES (@a, @b, @c)";
command.Parameters.AddWithValue("a", "this is invulnerable");
command.Parameters.AddWithValue("b", "to any sort of SQL injection");
command.Parameters.AddWithValue("c", "--'; DROP DATABASE");
command.ExecuteNonQuery();
person Alex J    schedule 24.02.2010

Если вы действительно хотите помочь своим «не очень опытным программистам», вам лучше попытаться определить, когда они делают встроенный sql в своем коде. Не должно быть слишком сложно написать правило FxCop, чтобы обнаружить это. Если вы включите его как часть процесса пост-сборки или если у вас есть командная система, установите правило, чтобы сбой сборки, они скоро освоятся.

person pms1969    schedule 24.02.2010

Проблема с внедрением SQL заключается в том, что пользовательский ввод используется как часть оператора SQL. Используя подготовленные операторы, вы можете заставить пользовательский ввод обрабатываться как содержимое параметра (а не как часть команды SQL). Параметры запроса помогают избежать этого риска, отделяя литеральные значения от синтаксиса SQL.

Большинство клиентских API (включая .NET) поддерживают параметризацию запросов. Это позволяет встраивать пользовательский ввод в качестве параметров. Параметры являются заполнителями для введенного пользователем значения, которое заменяется во время выполнения. Таким образом, пользователь не может внедрить код SQL, поскольку вся пользовательская запись рассматривается как значение параметра, а не как строка, добавленная к запросу.

параметризация — лучшее решение для атак SQL-инъекций.

person James    schedule 21.03.2011