2014-12-02 11 views
5

Jestem w pełni świadomy, że poprawną praktyką w zakresie odkażania zapytań SQL jest ich parametryzacja.Jak bezpieczny jest T-SQL po zastąpieniu znaku "escape"?

Pracuję nad wieloma wcześniej istniejącymi kodami, w których miara sanitacji miała zastąpić wszystkie instacje ' z '' w ciągach dynamicznych. Próbuję dowiedzieć się, jak bardzo powinienem być zaniepokojony.

Oto rzeczy: ten kod działa wyłącznie na T-SQL (SQL Server 2008R2 i wyższe) i, o ile wiem, ' jest ucieczka znaków dla T-SQL tylko.

Jak zatem wykonać atak iniekcyjny, aby pominąć powyższą miarę? To znaczy. czy ta "naiwna" sanitacja jest całkiem niezła na T-SQL, jak to wygląda?

+3

Można zastąpić znak pojedynczego cudzysłowu szesnastkową reprezentacją lub jego reprezentacją w Unicode lub można faktycznie oszukać "sanację", spodziewając się tego zachowania i używając odpowiedniej liczby pojedyncze cytaty, więc twoje "warunki sanitarne" całkowicie zawodzą ... ** poważnie **: nie rób tego. *** NIGDY WIECZNIE *** - używaj parmaeterów - *** ZAWSZE *** –

+1

@marc_s Proszę napisać instrukcję wstawiania wstawiającą 1000 linii z 50 polami. Jeśli możesz to zrobić (wskazówka: nie możesz), wtedy nazywam to dobrym komentarzem. W przeciwnym razie: ignorant. Liczba parametrów jest ograniczona i czasami istnieją dobre przypadki użycia innej metody. – TomTom

+2

Jeśli robisz to TomTom używaj SQLBulkCopy - marc_s ma rację, przynajmniej pod względem używania parametrów – Swomble

Odpowiedz

3

Tak, pojedynczy cudzysłów jest jedyną ucieczką, więc jesteś głównie, ale nie do końca w porządku.

Korzystanie z parametrów, podczas gdy najlepsze, polega głównie na wymianie ' na '', którą robisz ręcznie. ALE, również wymuszają maksymalną długość ciągu. Oczywiście, gdybyśmy mówili o parametrach innych niż łańcuchowe, mogliby wymusić na nich typ danych (tj. ' nie musi być zmieniony w przypadku danych liczbowych, daty/czasu itp., Ponieważ nie jest on prawidłowy dla na początek).

Problem, który można nadal pozostawić, stanowi podzbiór SQL Injection o nazwie SQL Truncation. Chodzi o to, aby zmusić część dynamicznego sql z końca łańcucha. Nie jestem pewien, jak prawdopodobne jest to w praktyce, ale w zależności od tego, jak i gdzie konstruujesz dynamiczny sql, musisz upewnić się, że zmienna przechowująca dynamiczny SQL do wykonania jest wystarczająco duża, aby pomieścić statyczne elementy w Twój kod plus wszystkie zmienne, zakładając, że są złożone w maksymalnej długości.

Oto artykuł z MSDN Magazine, New SQL Truncation Attacks And How To Avoid Them, który pokazuje zarówno zwykłe SQL Injection, jak i skracanie SQL. W artykule zobaczysz, że w celu uniknięcia SQL Injection najczęściej używają one metody REPLACE(@variable, '''', ''''''), ale w niektórych sytuacjach również są wyświetlane przy użyciu QUOTENAME(@variable, '[').

EDIT (20.01.2015): Tutaj jest dobrym źródłem informacji, choć nie jest specyficzny dla SQL Server, który zawiera szczegółowy opis różnych typów SQL Injection: https://www.owasp.org/index.php/Testing_for_SQL_Injection_(OTG-INPVAL-005)

Poniższy artykuł jest związany z jednym powyżej . Ten jest specyficzny dla SQL Server, ale bardziej ogólny pod względem ogólnego bezpieczeństwa. Istnieją sekcje związane z SQL Injection:
https://www.owasp.org/index.php/Testing_for_SQL_Server

+0

Dziękujemy! Dokładnie taki rodzaj odpowiedzi, którego szukałem. – piaste

3

(Insert uwagi o zagrożeniach związanych z łamanego dezynfekcji i ucieczki tutaj. Zobacz komentarz o marc_s.)

Co proponujesz tutaj jest taka sama metoda, że ​​serwer Microsoft SQL zarządzanych obiektów SMO) (użyć. Są to .NET DLL, które można kontrolować za pomocą dekompilatora. Na przykład:

internal static string MakeSqlString(string value) 
{ 
    StringBuilder builder = new StringBuilder(); 
    builder.Append("N'"); 
    builder.Append(EscapeString(value, '\'')); 
    builder.Append("'"); 
    return builder.ToString(); 
} 

public static string EscapeString(string value, char escapeCharacter) 
{ 
    StringBuilder builder = new StringBuilder(); 
    foreach (char ch in value) 
    { 
     builder.Append(ch); 
     if (escapeCharacter == ch) 
     { 
      builder.Append(ch); 
     } 
    } 
    return builder.ToString(); 
} 

Tak, wystarczy, że wystarczy Replace("'", "''") według firmy Microsoft. Jestem pewien, że nie jest to tylko kod wewnętrzny, ale został poddany audytowi pod kątem bezpieczeństwa. Zawsze robią to ze względu na SDL.

Należy również zauważyć, że kod ten wydaje się działać w trybie Unicode (patrz prefiks N). Wygląda na to, że jest to również bezpieczne dla Unicode.

Z bardziej subiektywnej uwagi: unikam literałów łańcuchowych T-SQL, tak jakbym musiał. Ufam tej metodzie.

2

to w .NET
I teraz zauważyć pytanie jest oznaczone TSQL ale nie .NET

Marc domniemanych można oszukać go lub Unicode hex reprezentacji. Testowałem i ani unicode, ani hex nie oszukało go w .NET.

Jeśli chodzi o oszukiwanie przy odpowiedniej liczbie apostrofów. Jeśli zawsze zamieniasz jeden na dwa, nie widzę, w jaki sposób odpowiednia liczba mogłaby go oszukać.

u0027 i x0027 jest apostrof i został zastąpiony dwoma apostrofu
2018 i 2019 są lewe i prawe cytaty i SQL prostu traktować je jako literały

string badString = "sql inject \' bad stuff here hex \x0027 other bad stuff unicode \u0027 other bad stuff left \u2018 other bad stuff right \u2019 other bad stuff"; 
    System.Diagnostics.Debug.WriteLine(badString); 
    System.Diagnostics.Debug.WriteLine(SQLclean(badString)); 
} 
public string SQLclean(string s) 
{ 
    string cleanString = s.Replace("\'", "\'\'"); 
    return "N\'" + cleanString + "\'"; 
} 

myślę parametry są lepsze praktyki

Powiązane problemy