Читать книгу Na tropie błędów. Przewodnik hakerski - Peter Yaworski - Страница 28

4.
CROSS-SITE REQUEST FORGERY
CSRF przez żądanie POST

Оглавление

Jeżeli bank wykonuje przelewy przez żądania POST, do wykonania ataku CSRF będziesz musiał podejść w inny sposób. Atakujący nie mógłby użyć znacznika <img>, ponieważ <img> nie może wywołać żądania POST. Zamiast tego strategia atakującego będzie zależeć od zawartości żądania POST.

Najprostszy scenariusz obejmuje żądanie POST z nagłówkiem content-type application/x-www-form-urlencoded lub text/plain. Nagłówek content-type jest często dodawany przez przeglądarki przy wysyłaniu żądań HTTP. Podpowiada on odbiorcy, jak zakodowana jest treść żądania HTTP. Oto przykład żądania content-type text/plain:

POST / HTTP/1.1

Host: www.google.ca

User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:50.0) Gecko/20100101  Firefox/50.0

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8

Content-Length: 5

Content-Type: text/plain;charset=UTF-8

DNT: 1

Connection: close

hello

Content-type jest oznaczony, a jego rodzaj wymieniony wraz ze sposobem kodowania znaków w żądaniu. Nagłówek ten jest istotny, ponieważ przeglądarki mogą traktować różne rodzaje zawartości w odmienny sposób (do czego przejdę za moment).

W tej sytuacji złośliwa strona jest w stanie utworzyć ukryty formularz HTML i wysłać go do podatnej witryny bez wiedzy ofiary. Formularz może wysłać żądanie POST lub GET na dany adres URL, a nawet przesłać wartości parametrów. Poniżej zobaczysz przykład szkodliwego kodu na stronie, do której podejrzany link mógł przekierować Boba:

<iframe style="display:none" name="csrf-frame"></iframe>

<form method='POST' action='http://bank.com/transfer' target= "csrf-frame" id="csrf-form">

<input type='hidden' name='from' value='Bob'>

<input type='hidden' name='to' value='Joe'>

<input type='hidden' name='amount' value='500'>

<input type='submit' value='submit'>

</form>

<script>document.getElementById("csrf-form").submit()</script>

W tym przykładzie wykonujemy żądanie POST do banku Boba razem z formularzem (oznaczonym atrybutem action w tagu <form>). Ponieważ atakujący nie chce, żeby Bob widział formularz, dlatego każdy z elementów <input> jest oznaczony typem 'hidden', co czyni je niewidocznymi na stronie. Jako ostatni krok, atakujący dodaje kod JavaScript między tagami <script>, żeby automatycznie wysłać formularz, kiedy strona zostanie załadowana . Jest to możliwe dzięki metodzie dokumentu getElementByID() z argumentem ("csrf-form"), gdyż tak w drugim wierszu nazwaliśmy nasz formularz . Podobnie jak w przypadku żądania GET, kiedy tylko formularz zostanie wysłany, przeglądarka wykona żądanie POST w celu przesłania plików cookies do strony bankowej, które wywoła przelew. Ponieważ żądania POST zwracają odpowiedź HTTP z powrotem do przeglądarki, atakujący ukrywa odpowiedź w ramce iFrame z atrybutem display:none . W rezultacie Bob nie ma pojęcia o tym, co się właśnie stało.

W innych przypadkach strona może oczekiwać żądania POST z nagłówkiem content-type application/json. Czasami żądanie typu application/json będzie mieć token CSRF. Ten token jest wartością, która jest wysyłana wraz z żądaniem HTTP, zatem docelowa strona może zweryfikować, czy żądanie pochodzi od niej samej, a nie innej, potencjalnie złośliwej strony. Token może znajdować się w treści HTTP żądania POST lub we własnym nagłówku z nazwą taką jak X-CSRF-TOKEN. Kiedy przeglądarka ma zamiar wysłać żądanie POST z zawartością typu application/json do strony, najpierw wysyła dodatkowe żądanie OPTIONS. Następnie strona zwraca odpowiedź do żądania OPTIONS, wskazując, które rodzaje żądań HTTP akceptuje i z których zaufanych źródeł mogą pochodzić. Taka operacja jest nazywana „preflight OPTIONS call”. Przeglądarka odczytuje odpowiedź i wysyła poprawne żądanie HTTP, które w naszym przykładzie z bankiem będzie żądaniem POST.

Jeśli zostały zaimplementowane poprawnie, preflight OPTIONS call stanowi ochronę przed niektórymi podatnościami CSRF: złośliwe strony nie będą obecne na liście zaufanych witryn dla danego serwera, podczas gdy przeglądarki będą pozwalały tylko wybranym stronom (znajdującym się na whiteliście witryn) na odczytanie odpowiedzi OPTIONS. Dzięki temu, ponieważ złośliwa strona nie może przeczytać odpowiedzi OPTIONS, przeglądarki nie będą wysyłać niebezpiecznych żądań POST.

Zestaw zasad określających, kiedy i jak strony internetowe mogą czytać odpowiedzi od siebie nawzajem, nazywa się Cross-Origin Resource Sharing (CORS). CORS ogranicza dostęp do zasobów, włączając w to odpowiedzi JSON spoza tych domen, które obsługiwały te pliki lub są dozwolone przez testowaną witrynę. Innymi słowy, kiedy deweloper używa CORS do ochrony witryny, nie możesz wysłać żądania application/json w celu uruchomienia testowanej aplikacji lub odczytania odpowiedzi, chyba że testowana witryna na to zezwala. W niektórych przypadkach możesz ominąć to zabezpieczenie, zmieniając nagłówek content-type na application/x-www-form-urlencoded, multipart/form-data lub text/plain. Przeglądarki nie wyślą żądania preflight OPTIONS dla żadnego z tych trzech rodzajów zawartości przy wykonywaniu żądania POST, zatem żądanie CSRF może zadziałać. Jeśli nie zadziała, sprawdź nagłówek Access-Control-Allow-Origin w odpowiedziach HTTP z serwera, by upewnić się, czy serwer nie ufa wszystkim źródłom. Jeżeli nagłówek ten się zmienia, gdy żądania wysyłane są z dowolnych źródeł, aplikacja może mieć spory problem, gdyż pozwala wszystkim źródłom na odczyt odpowiedzi z ich serwera. Otwiera to drogę na istnienie dziur CSRF, ale może również pozwolić atakującym na odczytanie poufnych danych zebranych w odpowiedziach HTTP z serwera.

Na tropie błędów. Przewodnik hakerski

Подняться наверх