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 - И сега има начин да използвате параметри под капака във вашата рамка?   -  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 - Актуализирах отговора си след вашия коментар. - 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