threats.pl > Bezpieczeństwo aplikacji internetowych > Lekcja 25: Wyzwanie V > Wskazówki - część pierwsza

Wyzwanie V - wskazówki, część pierwsza

Formatka wyszukiwania wykorzystana w przykładzie wygląda w sposób następujący:

Tego typu formatki są często spotykane w różnego typu aplikacjach, służą zwykle do zaawansowanego wyszukiwania/filtrowania danych. W takich funkcjach prawdopodobieństwo wystąpienia błędów typu sql injection jest duże, z uwagi na dynamiczne budowanie przez programistów zapytania SQL w zależności od wybranych przez użytkownika parametrów wyszukiwania.

W tym przykładzie użytkownik ma możliwość określenia następujących parametrów wyszukiwania:

Jeśli poszczególne pola nazwiemy zgodnie z nazwami parametrów na formatce $name, $operator, $value i $oper, to zapytanie SQL (jego sekcja WHERE) będzie wyglądała mniej mniej więcej tak:

(...) WHERE $name $operator $value $oper (...)

Potencjalnie każdy z tych parametrów może być podatny na sql injection jeśli wartość przekazana przez użytkownika trafi do budowanego zapytania SQL bez odpowiedniej walidacji i odpowiedniego encodingu.

Przed dalszą lekturą warto zapoznać się z lekcją: Lekcja 7: (blind) SQL injection, jak również z wpisem Jak szukać SQLi - przykład.

Określenie kolumny

W przypadku parametru określającego kolumnę użytą w warunku częstą praktyką jest używanie bezpośrednio nazw kolumn bazy danych. Jest to podejście niepożądane, ponieważ prowadzi do ujawnienia pewnych (potencjalnie przydatnych dla atakującego) informacji o strukturze bazy danych. Poza tym w wielu przypadkach wartość otrzymywana od użytkownika jest wykorzystywana w budowanym zapytaniu SQL bez jakiejkolwiek walidacji. Wynika to być może z faktu, że parametr taki zwykle powiązany jest z polem typu select (drop down), co może sugerować (oczywiście błędnie, patrz: Lekcja 1: absolutne podstawy), że wartość parametru nie może być modyfikowana przez użytkownika.

Weryfikacja istnienia podatności w takim przypadku może sprowadzać się do modyfikacji parametru name z przykładowej wartości id do następujących wartości:

1=1 AND id
1=0 AND id

W efekcie hipotetyczne zapytanie SQL przyjmie następującą postać:

(...) WHERE 1=1 AND id $operator $value $oper (...)
(...) WHERE 1=0 AND id $operator $value $oper (...)

Podatność tego typu istniała w dwóch pierwszych wersjach przykładu. Jak aplikacja zachowuje się w trzecim przypadku: http://bootcamp.threats.pl/lesson25b/?

Określenie operatora

W GUI do wyboru dostępne są następujące operatory:

Warto zauważyć, że w zależności od typu danych w wybranej kolumnie, operatory te mogą mieć różne znaczenie. W szczególności mogą nie mieć sensu w danym kontekście. W takim przypadku warto przeanalizować jak poszczególne operatory są traktowane, w zależności od wybranej kolumny (parametru name).

Była raportowana podatność w parametrze operator. Warto sprawdzić w jakich przypadkach ona działa, a w jakich nie i spróbować ustalić dlaczego.

Wartość

Podobnie jak w przypadku parametru operator, również parametr value może być traktowany w sposób różny, w zależności od wybranej kolumny. W tym wypadku można przypuszczać, że będą wykorzystane trzy(?) typy:

Należy sprawdzić jak aplikacja przetwarza wartość (parametr value) w zależności od wybranego typu kolumny. Polecam również przykład: Lekcja 18: Więcej niż jedna ścieżka wykonania, który pokazuje, że (nie)istnienie podatności wcale nie musi być oczywiste i jej wystąpienie zależeć może od ustawienia innego parametru.

Operator logiczny AND/OR

W przypadku parametru oper sprawa przedstawia się w sposób podobny, jak dla parametru name. Parametr ten związany jest z polem drop down, w związku z czym w wielu wypadkach może nie być prawidłowo walidowany i encodowany. Ze sporym prawdopodobieństwem można założyć, że będzie on trafiał do budowanego zapytania SQL bezpośrednio.

Wartości parametru oper, które mogą być przydatne w weryfikacji istnienia podatności:

AND 1=1 AND
AND 1=0 AND

Sam parametr oper może być ignorowany przez aplikację, jeśli nie ma on sensu. Nie ma on sensu, jeśli nie są zdefiniowane żadne warunki drugiej części filtra.

Parametr oper był podatny w pierwszej wersji przykładu. W kolejnych wersjach jego zachowanie wygląda inaczej - jak?