Ile to razy czytałeś już w Gazecie, że „Olbrzymie zainteresowanie spowodowało zablokowanie stron premiera, Sejmu i prezydenta!

Niniejszy wpis pokaże Ci jak na własnych stronach odnieść taki sukces!

Brzmi jak tani wstęp do książki „Zostań e-milionerem w 24h”?

Każdy wie, że to nie działa. Na podstawie fikcyjnego sklepu internetowego pokażę Ci gdzie czyhają potencjalne błędy bezpieczeństwa, czym mogą skutkować i jak z nimi walczyć. Czyli co zrobić, żeby i nasze strony nie przeżywały tak nagłego wzrostu zainteresowania.

Nasz sklep

Nasz sklep

Nasz sklep

Miejsca gdzie mogą czyhać potencjalne luki bezpieczeństwa pokażę na przykładzie fikcyjnego sklepu internetowego My e-shop.

Składa się on z pewnych sekcji, które już od dłuższego czasu zagościły na stałe na większości stron – sklepach internetowych, portalach społecznościowych, blogach itp.

Pomimo tego, że elementy te są powtarzalne i tak popularne, ciągle na większości serwisów, w których audytach miałem okazję uczestniczyć (lub byłem zwykłym gościem), są one źródłem krytycznych błędów bezpieczeństwa.

Opinie klientów są najważniejsze! – XSS (Cross Site Scripting)

Atak XSS na formularz dodawania opinii

Atak XSS na formularz dodawania opinii

Początek „audytu” zaczniemy od formularza dodawania opinii o produkcie. Składa się on ze standardowych pól – klient może za pomocą slidera określić ocenę produktu, dodać słowny komentarz, a całą opinię podpisać swoim nickiem.

Zwróćmy uwagę na mechanizm oceniania – klient widzi JavaScriptowy slider, za którym tak naprawdę kryje się pole typu hidden. Jest to najczęściej stosowana praktyka.

Co się stanie, gdy konkurencja z evilshop.com spróbuje użyć formularz do nietypowej akcji promocyjnej swojego sklepu?

Pamiętajmy również o ukrytym polu formularza – to, że wizualnie go nie widać, nie oznacza, że nie może być on celem ataku!

Efekt ataku

Efekt ataku XSS

Efekt ataku XSS

Okazuje się, że formularz dodawania opinii był podatny na atak typu XSS. Polega on na tym, że teksty wpisane w pola nie zostały przefiltrowane ze znaczników HTML – ani w momencie zapisu danych do bazy danych, ani w momencie wyświetlenia ich na stronie. Następnie są one swobodnie wyświetlane na stronie produktu.

Dlatego osobom odwiedzającym nasze strony produktów wyświetla się gustowny alert z reklamą konkurencyjnego sklepu a także ich logotyp przy liście opinii.

Przykład kodu

Za mechanizmem dodawania opinii może kryć się np. taki kod skryptu:

<?php
DB::insert(‘opinions’, $_POST['name'], $_POST['opinion'], $_POST['rating']);
// ...
echo $_POST['name'];
echo 'Rating: ' . $_POST['rating'];
echo $_POST['opinion'];
?>

Widać tu, że to co zostanie przesłane formularzem jest w niezmienionej formie zapisywane do bazy danych a następnie wyświetlane i renderowane przez przeglądarkę.

Jak się przed tym zabezpieczyć?

  1. Już przed zapisem do bazy danych escapeować znaczniki html
  2. Walidować formularz – pozwalać na wpisywanie jedynie ustalonego zbioru znaków – może się to sprawdzić w polu na wpisanie nazwy komentującego. Natomiast jest konieczne w polu hidden oceny produktu. To, że wizualnie nie widać miejsca gdzie można wpisać dane, to nie znaczy, że nie jest to potencjalna furtka dla atakującego. W tym przypadku wpisanie „evilshopownz” w tym polu, może spowodować znacznie gorsze i daleko idące skutki – brak zachowania spójności danych. Co się stanie gdy posiadamy inny program, który robi statystyki ocen produktów? Najprawdopodobniej cały system się wywali. Niewątpliwie naprawa skutków będzie wtedy bardzo kosztowna.
  3. Escapeowanie tekstów w momencie wyświetlania na stronie. W bazie danych będziemy przechowywać oryginalny tekst, jednak na stronie komentarzy znaki < > itp. zostaną zamienione na ich odpowiedniki encji (> na &gt;). W przeglądarce, klientom wyświetlą się ładne znaki „>” natomiast nie będą one interpretowane przez przeglądarkę jako tagi html.

Łatwo znaleziony towar to szybko sprzedany towar! – SQL injection

Sklep internetowy bez wyszukiwarki? Już od lat ’90 normą jest search na stronie. Nie mogło go zabraknąć i u nas. W końcu to ona generuje duży procent sprzedaży.

Nawet w tak, wydawało by się, prozaicznym elemencie może kryć się wiele niebezpieczeństw.

Niepozorna, mała kontrolka wyszukiwarki może być źródłem wielu krytycznych problemów :

  • Nietypowa, wzmożona aktywność serwera.
  • Znikanie produktów ze sklepu.
  • Problemy z zalogowaniem się do panelu administracyjnego.

Dla wielu może się to wydać wręcz nieprawdopodobne, że pole wyszukiwania może powodować tak daleko idące efekty. Zaraz postaram się pokazać jak to wszystko jest możliwe.

Sprawdzimy teraz podatność tego pola na SQL injection.

Efekt ataku

Odwzorowanie ataku SQL injection

Odwzorowanie ataku SQL injection

Formularz wyszukiwania nie został odpowiednio zabezpieczony przed wstrzykiwaniem zapytań do bazy danych. Odpowiednio spreparowana treść pozwalała na wykonywanie złożonych zapytań na bazie danych.

Przykład kodu

Bardzo upraszczając, kod odpowiedzialny za wyszukiwanie może mieć poniższą postać:
<?php
$term = $_POST['search'];
$result = DB::query('SELECT * FROM products WHERE title LIKE "%' . $term . '%"');
?>

Gdy w wyszukiwarce zostanie wpisane:

anything"; __INNE_ZAPYTANIE__; --

Zapytanie będzie miało wtedy postać:

SELECT * FROM products WHERE title LIKE "% anything"; __INNE_ZAPYTANIE__; -- %"

Co spowoduje wykonania dwóch zapytań w bazie: SELECT i tego, kryjącego się pod __INNE_ZAPYTANIE__.

Wzrost aktywności serwera może być spowodowany zapytaniami do bazy, które „na raz” zwracają listę wszystkich możliwych produktów (dodanie do zapytania np. ” OR 1=1 — ) – w skrajnych przypadkach jest to na tyle zabójcze, że może wystąpić przepełnienie pamięci. Do tego stopnia, że strona potrafi stać się niedostępna na dłuższy czas.

Gorsze są jednak bardziej złożone zapytania. Okazuje się, że atakujący ma możliwość przemycenia dodatkowych zapytań „DELETE”, którymi usuwa produkty z bazy, a także „UPDATE”, którym ma możliwość chociażby zmiany hasła administratora do panelu administracyjnego.

Jak się przed tym zabezpieczyć?

  1. Wpisane dane do formularza escapeować odpowiednimi funkcjami języka. (w PHP np. mysql_real_escape_string)
  2. Nie używać niskopoziomowych mechanizmów dostępu do bazy. Zamiast tego użyć bibliotek wysokopoziomowych (np. abstrakcji dostępu do bazy danych), które przeważnie już same posiadają mechanizmy zabezpieczające przed tego typu atakami.

Cross-site request forgery (CSRF)

Strona produktu, widok administratora

Strona produktu, widok administratora

Ostatnim typem ataku, którym się zajmiemy jest tzw. CSRF.

Po zalogowaniu się na konto administratora mamy możliwość usuwania i edytowania produktów. Usunięcie odbywa się po przez proste kliknięcie na link „Delete”, który natychmiastowo usuwa produkt ze sklepu.

Ostatnio dostałeś maila z wycinkiem ciekawego artykułu, żeby przeczytać go w całości musiałeś wejść na podaną stronę.

W tym momencie z niedowierzaniem zauważyłeś, że ze sklepu zniknęły wszystkie produkty.

Efekt ataku

Atakujący po nakłonieniu administratora na wejście na specjalną stronę miał możliwość usuwania produktów wykorzystując adres „http://e-shop.com/category/23/product/ACME-product/delete”.

Przykład kodu

Żeby atak się powiódł, na stronie atakującego mógł się znaleźć zwykły obrazek:
<img src="http://e-shop.com/category/23/product/ACME-product/delete" width="1" height="1" />

Ramka:
<iframe src="http://e-shop.com/category/23/product/ACME-product/delete" width="1" height="1"></iframe>

Lub odniesienie w zagnieżdżonym skrypcie:
<script type="text/javascript" src="http://e-shop.com/category/23/product/ACME-product/delete"></script>

Te trzy możliwości spowodują ten sam efekt – usunięcie produktu ACME-product.

Jak się przed tym zabezpieczyć?

  1. Akcje, które powodują skutki uboczne (np. usuwanie, modyfikowanie, dodawanie zasobów) nie powinny odbywać się metodą GET (np. wyżej opisany link). Jest to nawet spisane w RFC 2616 jako zalecenie protokołu HTTP.Jeżeli jednak koniecznie chcemy niektóre tego typu akcje odpalać po kliknięciu na link można:
    • Stosowanie dodatkowej strony z potwierdzeniem wykonania akcji. Po kliknięciu na link „Delete” zwracana jest dodatkowa strona, na której należy potwierdzić chęć usunięcia produktu (z dynamicznie wygenerowanym formularzem potwierdzenia)
    • Dokładanie tokena zabezpieczającego. Do URLa usuwania produktu dodajemy specjalny, losowo wygenerowany token (np. ?t=f96b697d7cb7938d525a2f31aaf161d0). W sesji przechowujemy informację o tym, jaki token był wygenerowany a następnie porównujemy go z tym, którego dostaliśmy w żądaniu.
  2. Stosowanie formularzy z metodą POST do złożonych akcji, powodujących skutki uboczne. Trzeba pamiętać, żeby je również zabezpieczyć dodatkowym tokenem (analogicznie jak w punkcie 1 b).
    Formularze są tak samo podatne na atak CSRF jak zwykłe linki.

Końcowe refleksje

Musimy sobie uświadomić, że obecność luk bezpieczeństwa na stronach internetowych jest bardzo powszechna. Również największe portale (Gazeta.pl, AOL.com, strony MTV i wiele innych) mają problemy z zachowaniem standardów bezpieczeństwa. Okazuje się, że nawet coś, co wydawać by się mogło, nie może stanowić żadnego zagrożenia (np. formularz wyszukiwarki) może być źródłem daleko idących efektów („zablokowaniem” całej strony, wyciek danych z bazy danych, ataki phishingowe itp). Tak naprawdę wszystko będzie zależeć od sprytu i pomysłowości atakującego.

Warto się zastanowić, czy szczególnie na stronach o charakterze e-commerce, przy których kluczowe jest zaufanie klienta i dbanie o dobry wizerunek, nie warto poświęcić większej uwagi kwestiom poruszonym w niniejszym artykule. Najlepszym rozwiązaniem jest niewątpliwie zlecenie przeprowadzenia audytu bezpieczeństwa firmie, zajmującej się tym profesjonalnie.