Regex для обнаружения SQL-инъекций в WinForms - PullRequest
5 голосов
/ 25 февраля 2010

я хочу кэшировать ввод, который, похоже, похож на 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?

Ответы [ 4 ]

15 голосов
/ 25 февраля 2010

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

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

Обновление: (следующие комментарии)

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

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

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

3 голосов
/ 25 февраля 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();
2 голосов
/ 25 февраля 2010

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

0 голосов
/ 21 марта 2011

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...