Czym jest SQL injection?

25 czerwca 2013, 08:55 | Teksty | komentarzy 16
: zin o bezpieczeństwie - pobierz w pdf/epub/mobi.

Z tekstu dowiesz się

  • Czym jest podatność SQL injection
  • Jakie są możliwe skutki jej wykorzystania
  • W jaki sposób uzyskiwany jest nieautoryzowany dostęp do bazy danych z wykorzystaniem SQL injection
  • Jakie są podstawowe metody ochrony przed atakami

Wstęp

Czym jest SQL injection?

To jedna z dość częstych i jednocześnie niebezpiecznych podatności w aplikacjach webowych (oraz niewebowych). Nie bez powodu SQL injection należy do pierwszej (A1) z dziesięciu kategorii błędów  wymienianych w dokumencie OWASP Top Ten. Już sama nazwa wskazuje na rodzaj problemu – atakujący wstrzykuje do aplikacji (nieautoryzowany) fragment zapytania SQL. Wstrzyknięcie zazwyczaj możliwe jest z jednego powodu – braku odpowiedniego sprawdzenia (walidacji) parametru przekazanego przez użytkownika. Taki parametr, gdy mamy do czynienia z SQL injection, często przekazywany jest bezpośrednio do zapytania SQL.

Czym to może skutkować?

W zależności od sytuacji możemy mieć do czynienia z:

  • nieautoryzowanym dostępem w trybie odczytu lub zapisu do całej bazy danych,
  • możliwością ominięcia mechanizmu uwierzytelnienia,
  • możliwością odczytania wybranych plików (system operacyjny, na którym pracuje baza danych),
  • możliwością tworzenia plików w systemie operacyjnym, na którym pracuje baza,
  • możliwością wykonania kodu w systemie operacyjnym (uprawnienia użytkownika, na którym pracuje baza lub web serwer – w przypadku aplikacji webowych).

Poniższe informacje podane są jedynie w celach edukacyjnych.

Ewentualne testy z wykorzystaniem zamieszczonych tu informacji  należy realizować jedynie na systemach, których bezpieczeństwo możemy oficjalnie sprawdzać.

 

Przykład praktyczny

Zobaczmy, jaka jest istota tej podatności na przykładzie prostej aplikacji napisanej w języku PHP, komunikującej się z bazą danych MySQL z wyświetleniem szczegółów newsa (przy okazji zaznaczam, że podatność nie jest ograniczona tylko do języka PHP czy MySQL).

W normalnym użyciu wyświetlenie newsa odbywa się poprzez odwołanie do URL-a: http://192.168.0.105/news_detail.php?id=1&action=view

Aplikacja wykonuje wtedy następujące czynności (kliknij dwa razy, aby powiększyć):

sql_query_1

 

Co się jednak stanie w przypadku, gdy zmodyfikujemy wartość zmiennej id?

Na przykład w ten sposób:

http://192.168.0.105/news_detail.php?id=-1 union select version(),2–&action=view.

Zobaczmy:

sql_injection2

Okazuje się, że w tym przypadku można było odczytać wynik funkcji bazodanowej version()!

Na podobnej zasadzie można tu również odczytać wybrane pliki z filesystemu:

image_preview-3

Analogicznie możliwe jest również pobranie danych z zupełnie innej tabeli niż oryginalna ‚news’.

Na przykład można pobrać login oraz hasła z tabeli ‚users’:

sqli_union_tabela-4

Jak z kolei będzie wyglądać sytuacja w przypadku, gdy nie mamy do czynienia ze zmienną liczbową tylko ze stringiem?

Zobaczmy na przykładzie formularza logowania:

sqli_auth-5

W tym przypadku udało się zalogować na użytkownika ‚admin’ bez znajomości jego hasła.

W jaki sposób można zalogować się na innego użytkownika? Patrząc na diagram powyżej, należałoby wybrać nie pierwszego z brzegu, a kolejnego użytkownika z tabeli ‚users’:

sqli_auth1-6

Ochrona

Nawet w tak skrótowym tekście warto poświęcić kilka słów ochronie przed SQL injection.

W jaki sposób się ochronić?

Mówiąc w dużym skrócie – w odpowiedni sposób weryfikować zmienne przekazywane do użytkownika do aplikacji.

  • W pierwszym omówionym przypadku (zmienna id) wystarczy sprawdzać czy przekazana zmienna jest liczbą.
  • W przypadku z mechanizmem logowania sytuacja jest trochę bardziej skomplikowana – tutaj należy uniemożliwić zamknięcie przez atakującego zmiennej tekstowej znakiem ‚ (np. używając funkcji mysql_real_escape_string(), choć sugerowaną metodą jest stosowanie zapytań parametryzowanych  (update: np. w najnowszej wersji PHP – 5.5.0 mysql_real_escape_string() deprecated i prawdopodobnie w przyszłych wersjach nie będzie obsługiwana))
Więcej informacji o bezpieczeństwie aplikacji webowych: nowy dokument OWASP Top Ten 2013 oraz kilka prostych metod na zabezpieczenie swojej webaplikacji.

michal.sajdak<at>securitum.pl

Spodobał Ci się wpis? Podziel się nim ze znajomymi:



Komentarze

  1. ja

    moglibyście przy okazji zrobić jakiś poradnik do bt :D

    Odpowiedz
    • pewnie kiedyś ;) Na razie kilka rzeczy o webie – bo ostatnio coś czytelnicy narzekali że nie ma nic web-u ;)
      –ms

      Odpowiedz
  2. Jakub

    Albo używać funkcji i procedur do pobierania/modyfikacji informacji w bazie. Jak parametr będzie miał coś niepokojącego w sobie to i tak będzie dalej parametrem, czyli np. stringiem i tak zostanie potraktowany. Najwyżej funkcja wywali błąd, że został przekazany błędny typ.

    Oczywiście, parametry powinny i tak być w jakiś sposób filtrowane.

    Odpowiedz
    • Zgadza się (choć z tymi funkcjami to uwaga – bo jeśli tam jest gdzieś dynamiczne zapytanie to może być SQLi). Trochę będzie o tym w kolejnych odcinkach o SQLi – bo takie planuję :) M.in. też przykłady źle przygotowanych zapytań parametryzowanych.
      –ms

      Odpowiedz
  3. Oskar

    Moglibyście jeszcze wspomnieć że poza samą aplikacją korzystającą z bazy danych należy zabezpieczyć też samą bazę. Stworzenie odpowiednich perspektyw i użytkowników z bardzo ograniczonymi prawami może sprawić że sam fakt istnienia SQL injection w aplikacji nie będzie zagrożeniem.

    Odpowiedz
  4. p

    Moglibyście opisać jak się chronić przed SQL Injection od strony serwerowej? W necie jest już mnóstwo artykułów o tym jak tworzyć bezpieczne aplikacje, ale wielu programistów chyba i tak tego nie czyta… Brakuje natomiast artów (zwłaszcza w języku polskim) poruszających takie kwestie jak na przykład używanie mod_security dla serwerów webowych.

    Odpowiedz
    • Jest u nas w planach (tzn. pisze się już :) seria tekstów generalnie o tematyce monitoringu bezpieczeństwa. OSSEC, snort, może i na mod_security wystarczy trochę czasu, choć przyznam że mamy trochę ograniczone moce przerobowe ;-)
      PS. Gdyby ktoś przypadkiem chciał przygotować tekst w jednym z ww. tematów to proszę o maila -> sekurak@sekurak.pl
      -ms

      Odpowiedz
  5. Crony

    Postaram sie cos przygotowac o modsecu:-) niech ten wpis bedzie moim motywatorem, pozdr0!

    Odpowiedz
  6. ixdude

    Taki kod jest zupełnie bezpieczny dla danych
    $sql = „SELECT title, body FROM news WHERE id = $_GET[‚id’]”;

    walnie takim soczystym parse errorem że nikt nie haknie sajta ;)

    Odpowiedz
    • @ixdude: jak to mawiają – u mnie działa ;-)
      Info o deprecjacji – tak, dzięki, zrobiłem mały update w arcie. Choć ta wersja php-a ma dosłownie kilka dni, więc i stare funkcje będę jeszcze dłuuugo. Też jak najbardziej zapytania parametryzowane to preferowana metoda ochrony (nie tylko w PHP)
      -ms

      Odpowiedz
  7. ixdude

    Co do metod zabezpieczania to funkcje z rozszerzenia mysql, zostały ostatecznie zdeprecjonowany (http://www.php.net/ChangeLog-5.php#5.5.0), tym samym zaleca się używanie filtrowania danych w inny sposób albo po prostu używania sparametryzowanych zapytań z mysqli czy PDO. Ogólnie fajny art.

    Pozdrawiam.

    Odpowiedz
  8. kszksz

    Czemu mam kliknąć obrazek DWA RAZY, aby powiększyć? :(

    Odpowiedz
    • To prawda – mało wygodne, dokładam to TODO.
      -ms

      Odpowiedz

Odpowiedz

Time limit is exhausted. Please reload CAPTCHA.