Programowanie w języku PHP

Ochrona przed XSS - podstawy

  • 2009-04-01 11:03
  • 13 komentarzy
  • 4514 odsłon
  • Oceń ten tekst jako pierwszy
Artykuł pochodzi ze strony: http://www.beldzio.com/blog/?p=8.

Czym jest XSS?


XSS czyli Cross Site Scripting to sposób na wstawienie swojego kodu na podatną stronę. Dzieje się to przez obdarzenie użytkownika zbyt dużym zaufaniem, czego skutkiem może być kompromitacja naszej strony.

Jakby zareagowali nasi klienci gdyby dowiedzieli się, że ich dane są w posiadaniu osób, które nie powinny mieć do nich dostępu, lub po wejściu na stronę ukazały by im się treści kompromitujące naszą firmę/stronę? Artykuł ten ma pokazać podstawowe sposoby zabezpieczania skryptów przed atakami typu XSS.

Co mamy do stracenia?


Umiejętne wykorzystanie błędów programisty może skutkować wejściem w posiadanie ważnych danych firmowych, pobraniem loginów oraz haseł użytkowników czy nawet zablokowaniem strony.

Do uzyskania danych firmowych może doprowadzić brak filtrowania danych przekazywanych przez użytkownika podczas zapisu ich do bazy danych. Do kradzieży danych użytkownika może doprowadzić wstrzyknięcie kodu JavaScript,  zaś do modyfikacji strony kodu HTML/PHP.

Niestety nie można bagatelizować sprawy nawet jeśli nasza strona umożliwia tylko i wyłącznie wprowadzenie kodu HTML. Bo co by było gdyby ktoś nagle po kilku minutach zabawy wpadł na pomysł stworzenia pływającej ramki, która przykryłaby całą właściwą stronę (to też nie jest problem, wstawia się kolorowego diva) i podlinkowanie jej do podróby naszego sajtu na jego serwerze. Co by było, gdyby nasi klienci otrzymali nagle wiadomości e-mail z prośbą zalogowania się na stronie? Większość z nich nie jest obeznana z metodami przechwycania haseł i z powodu 'prawidłowej domeny i kłódeczki' zalogowała się na prawdziwo-fałszywej stronie narażając się na niebezpieczeństwo.

W tym artykule pominiemy zaawansowane kwestie SQL Injection, a zajmiemy się wstrzykiwaniem kodu JavaScript i HTML. Spowodowane jest to głównie faktem, iż artykuł ma nauczyć podstawowych metod zabezpieczania się, a nie sposobów ataku.

Czas na zabezpieczanie, czyli psucie czas zacząć...


Jako, że uczyć się jest najlepiej na przykładach, dlatego w celu lepszego zobrazowania istoty błędów będę je opisywał na podstawie istniejących stron.
       
Przykładem ufności do użytkowników może być strona Narodowego Funduszu Zdrowia (http://www.nfz.gov.pl/). Najbardziej podatnym elementem stron są wszelkie formularze, na stronie NFZ rzuca nam się od razu w oczy wyszukiwarka. Co ciekawe nie filtruje ona danych, które otrzymuje od użytkownika co skutkuje możliwością wstrzyknięcia kodu HTML oraz JavaScript.

Jak działa wyszukiwanie podatności  na XSS ?


W polu input wyszukiwarki widoczne jest na bieżąco nasze zapytanie, dzięki czemu możemy bardzo prosto ingerować w wygląd strony. Żeby tego dokonać wystarczy zamknąć ostatni tag HTML poprzedzający nasze zapytanie, czyli w tym przypadku jest to:
<input
Do zamykania tegoż tagu posłuży nam kod:
"><h1>Test XSS</h1>
Dzięki takiej manipulacji nasz input zostanie zamknięty, a treść nagłówka:
<h1>
umieszczona poza formularzem. Efekt tego pokazuje poniższy obrazek:

<center>user image</center>

Jak się przed tym uchronić? Ochrona jest równie banalna jak i atak. Wystarczy użyć jednej funkcji PHP, a dokładnie strip_tags. Zadaniem funkcji strip_tags jest filtracja podanego jako parametr ciągu i usunięcie z niego tagów HTML oraz PHP. Gdyby programista piszący powyższą wyszukiwarkę użył tej funkcji efektem wpisania groźnego kodu byłaby następująca informacja:
Niestety, nie znaleziono wyników pasujących do zapytania Test XSS.



Kradzież danych użytkownika? Nic prostszego.


Wcześniejszy przykład ukazywał idee wstrzyknięcia kodu HTML, co jednak gdy agresor użyje JavaScript, który ma zdecydowanie większe możliwości? Powróćmy do wyszukiwarka NFZ, gdy dokonamy modyfikacji poprzedniego kodu, który modyfikował wygląd strony tak aby zawierał on w sobie kod JavaScript otworzą się przed nami ogromne możliwości. Aby sprawdzić, czy próba wstrzyknięcia kodu JavaScript powiedzie się wystarczy w wyszukiwarkę wpisać
">&lt;script>JavaScript:alert("Test XSS");&lt;/script>
i tutaj zaczynają się schody. Parser PHP serwera NFZ ma włączoną dyrektywę magic_quotes_gpc, która jest złym zwyczajem. Dlaczego przecież zapewnia ona podstawowe bezpieczeństwo skryptów? Tak jest,  lecz gdy programista przyzwyczai się do zrzucania bezpieczeństwa swoich skryptów na parser PHP to stracą one na swojej przenośności, wzrośnie obciążenie serwera oraz nie uchroni go to przed wszystkimi niebezpieczeństwami. W tym przypadku uniemożliwia nam to pokazanie napisu ponieważ parser PHP przerabia nasz kod na
">&lt;script>JavaScript:alert(\"Test XSS\");&lt;/script>
co uniemożliwia jego wykonanie. Nie blokuje to jednak wszystkich naszych możliwości. Możemy np. zmusić stronę do pokazania nam komunikatu z aktualną godziną:

<center>user image</center>

Skoro już wiemy, że wstrzyknięcie kodu JavaScript jest możliwe pomyślmy jak atakujący może ukraść dane użytkownika. Wiele stron w plikach cookies umieszcza dane o użytkownikach ? loginy, hasła itp. Za pomocą XSS agresor bez problemu może osiągnąć dostęp do tych danych. JavaScript posiada funkcję odczytującą dane z plików cookies, poprzez napisanie odpowiedniego skryptu PHP, dane te mogą być przekazywane do skryptu na serwerze agresora. Z badań przeprowadzonych na stronie NFZ wynika, że ich strona również zapisuje ciastko na naszym komputerze, co prawda nie zawiera ono danych o loginach czy hasłach lecz :

<center>user image</center>

Załóżmy, że dane te to poziom uprawnień użytkownika, jeśli agresor zmieniłby wartość na 0 to mógłby uzyskać dodatkowe prawa na serwerze. Dlatego ważne dane należy trzymać na serwerze, korzystając z sesji, a nie ciastek.
Mogłoby się wydawać, że skoro JavaScript ma większe możliwości to zabezpieczania też będą poważniejsze. Tak jednak nie jest, wystarczy, że prócz funkcji  strip_tags przydadzą się nam dwie dodatkowe funkcje addslashes oraz stripslashes  ich zadaniem jest dodawanie ukośnika przed znakami, które mogą byś niebezpieczne czyli
' ? \ i NUL
.


Bezpieczne dołączanie plików.


Wiele osób nie widzi nic niebezpiecznego w bezpośrednim dołączaniu plików ze zmiennych superglobalnych. Co może być w tym niebezpiecznego. Wyobraźmy sobie sytuację, gdy nazwa pliku przesyłana jest w zmiennej z tablicy GET. Odpowiednie zmodyfikowanie adresu strony przez agresora może doprowadzić do uzyskania dostępu do pliku passwd oraz shadow, które zawierają dane o użytkownikach w systemie oraz innych plików np konfiguracyjnych. Jak się przed tym zabezpieczyć? Wg mnie dobrym sposobem jest utworzenie tablicy ze zmiennymi, których odpowiedniki plikowe mogą być includowane i sprawdzać za pomocą funkcji in_array czy dany plik ma zezwolenie na dołączenie.


Bezpieczne dodawanie danych do bazy danych.


Tematyka SQL Injection jest bardziej rozległa niż poprzednich wstrzyknięć, dlatego przedstawię tutaj tylko podstawowe metody zabezpieczeń.
Pierwszą zasadą jest niewstawianie zmiennych przekazywanych przez użytkownika do zapytania. Należy wcześniej przefiltrować. I tu ponownie PHP ułatwia nam zadanie udostępniając szereg funkcji. Należą do nich addslashes/stripslashes,  strip_tags, htmlspecialchars. Wszystkie prócz ostatniej zostały już omówione więc skupimy się tylko na  htmlspecialchars. Umożliwia ona zamianę specjalnych znaczników HTML na odpowiednie im encje, dzięki czemu możemy bez poważnych konsekwencji przyjmować od użytkownika kod HTML.


Nie tylko formularze są podatne.


Najbardziej podatnymi na XSS elementami stron są formularze oraz dane przekazywane do skryptów za pośrednictwem adresu, czyli zmienne z tablicy GET. Brak filtracji tablicy GET może doprowadzić do tych samych konsekwencji co brak filtracji w formularzach.
Przykładem strony, a raczej stron podatnych na ?adresowy XSS? są strony, na których zainstalowany jest system zarządzania treścią Mambo. CMS ten komunikuje się z użytkownikiem za pośrednictwem zmiennej
mosmsg
znajdującą się w tablicy superglobalnej GET. Poprzez odpowiednie zmodyfikowanie adresu strony możemy wstawić na stronę dowolny tekst. Jest to jedyne uchybienie Mambo, ponieważ dane przekazywane przez tą zmienną są czyszczone do postaci czystego kodu, a więc wstrzyknięcie kodu HTML/PHP jest niemożliwe. Przykładem takiej modyfikacji adresu może być
http://www.mamboserver.com/?mosmsg= Witamy+jesteśmy+kolejną+stroną+podatną+na+XSS+.
czego efektem jest:

<center>user image</center>

Oprócz tego znajdzie się też wiele innych stron, które można bardzo łatwo udupić. Jedną z nich jest strona Ministerstwa Finansów, której autor nie zabezpieczył za pomocą funkcji strip_tags(). Zobaczmy poniższy przykład:
<center>user image</center>

Samozagłada, czyli register_globals.


Register_globals jest dyrektywą parsera PHP, umożliwiającą tworzenie, krótkich nazw zmiennych, dzięki temu zamiast pisać
$_POST['nasza_zmienna']
możemy napisać
$nasza_zmienna
. Początkowo może się wydawać, że dyrektywa ta jest bardzo pomocna, ponieważ pozwala zaoszczędzić czas związany z wpisywaniem nazwy tablicy, jednak stanowi ogromne niebezpieczeństwo dla naszej strony. Dlaczego ? Załóżmy, że nasz strona zawiera moduł logowania. Poziom użytkownika sprawdzany jest poprzez instrukcję warunkową
if ($poziom === 'admin') echo 'Jesteś adminem';
. Agresor poprzez modyfikację adresu strony ?
http://www.nasz.serwer.pl/logowanie.php?poziom=admin
uzyska dostęp do praw administratora, bez konieczności logowania się. Tak więc mimo swojej przydatności zalecane jest wyłączenie dyrektywy register_globals.

Zakończenie, czyli to jeszcze nie jest koniec.


W tym artykule starałem przekazać Wam podstawową wiedzę z zakresu obrony przed XSS. Uważam, że wiedza na ten temat jest bardzo potrzebna webmasterom, ponieważ ogromna ilość stron jest podatna na ten atak. Mimo, że PHP udostępnia nam wiele przydatnych funkcji pomagających w zabezpieczeniu przed wstrzykiwaniem złośliwego kodu, należy pomyśleć też o tworzeniu własnych funkcji, które zapewnią większe bezpieczeństwo pisanych przez nas skryptów. I pamiętajcie o najważniejszej zasadzie, podczas pisania kodu, należy postępować tak jakby każdy użytkownik był agresorem i próbował znaleźć każdy nasz błąd.

PS. Administrator strony NFZ został poinformowany o błędzie na stronie.

Autor: Michał Bełdzio Ławicki
WWW: http://www.beldzio.com/
Kontakt : [email protected]

Kopiowanie bez zgody autora zabronione.

13 komentarzy

Lily652 2016-12-03 13:37

Dobra postu. Dzięki, ll śledzę następny. Przydatne i ciekawe informacje.  prayer times

Tadeusz8888 2016-10-31 14:05

bardzo dobra informacja! Dodałem stronę do ulubionych dog grooming near me

Demonical Monk 2009-09-12 12:01

Cholera MF się zabezpieczyło ;/

adamkl 2008-06-28 21:06

oczywiście administrator NFZ przeczytał dokładnie <ort>artykół</ort> :D i zabezpieczył się w połowie :D

MikiKam 2008-04-16 19:32

http://www.mf.gov.pl/?const=1&dzial=25&wysw=[xss]
:) Niedlogo to sobie będziemy wypłacać pieniądze ze skarbu państwa :)

Adam.Pilorz 2006-01-24 20:01

Ataki na tym polegające są dość proste. Ale mój brat (który w sumie zawodowo zajmuje się bezpieczeństwem stron internetowych) wyznaje jedną zasadę - nigdy nie nauczysz się zabezpieczać stron, póki sam się daną metodą na jakąś nie włamiesz. Efektem tego jest fakt, że jego koledzy zaniechali zwyczaj beztroskiego otwierania linków, które od niego dostaną :D

Bełdzio 2005-09-15 21:59

to się możesz zdziwić :) a czemu nie mogłem tego sam wykombinować ? bo nie widzę powodu  :>

UnAdamBoduch 2005-09-15 14:00

kto ci o tym powiedzial, bo sam na pewno nie wykombinowales tego :>

Bełdzio 2005-09-11 15:01

nie o to mi chodziło :) chodziło mi raczej o coś takiego : argesor wstrzykuje kod którego zadaniem jest odwołanie się do skryptu znajdującego się na jego serwerze z parametrem, będącym wartością pobraną z ciastek

Deti 2005-09-11 09:25

nice, very nice:)

BTW: co znaczyło \"dostęp do ciastek\" .. rozumiem, że do ciastek naszych - czyli sprawdziło to by się w przypadku gdy z komputera korzysta wiele osób .. ?

Drajwer 2005-09-10 10:51

moim zdaniem tytul powinien brzmiec \"jak wlamac sie na strone przez XSS\" :)

Ktos 2005-09-09 15:35

Będzie może w następnym odcinku :)

angel2953 2005-09-09 11:29

Extra artukuł, przydałby się jeszcze o SQL Injections...