/OWASP

[OWASP Top 10] A7: XSS - Cross-Site Scripting

Cześć! Witam Cię w 7 odcinku z serii OWASP Top 10, w której przyglądamy się dziesięciu najpopularniejszym błędom bezpieczeństwa powiązanym z serwisami internetowymi. Dzisiaj o atakach XSS czyli Cross Site Scripting - a tłumacząc to na język polski - o skryptach międzyserwisowych.

Ten rodzaj ataku jest podobny do injekcji - dane pochodzące od użytkownika nie są odpowiednio filtrowane i walidowane. Tylko że tam były one przekazywane dalej - zazwyczaj do bazy danych i na ich podstawie otrzymywaliśmy jakieś dane, do których nie powinniśmy mieć dostępu. W atakach XSS natomiast treść podana przez użytkownika jest wyświetlana bezpośrednio w przeglądarce.

CSS

Wygląd każdej strony internetowej opiera się na połączeniu kodu HTML, CSS i JavaScript. Jeżeli użytkownik kontroluje to, co wyświetla się w przeglądarce - może dodać swój własny kod do naszej strony. Wyniki takiego zachowania mogą być różne. Począwszy od dodania nowego obrazka, formularza czy też tabelki - czyli po prostu zmiany wyglądu strony. Ale ten błąd umożliwia również atakującemu, który wykorzysta tą podatność, na wykonanie dowolnego skryptu na tej stronie. I co najważniejsze - kod ten zostanie wykonany na prawach bieżącego użytkownika.

Trojan

Najlepiej opisać to na przykładzie. Jeżeli błąd XSS istniałby na stronie banku, po zalogowaniu się na nasze konto - przeglądarka uruchomiłaby bez naszej wiedzy dodatkowy kod niestworzony przez ten bank. To co ten kod by robi zależy już od pomysłowości atakującego. Może dla przykładu podmieniać numer konta, który wklejamy podczas wykonywania przelewów. Więc środki, które przesyłalibyśmy na jakieś konto mogłyby trafić nie tam gdzie powinny. Co więcej, trudno z poziomu serwera wykryć taki błąd - ponieważ wszystko odbywa się po stronie klienta. Podatności XSS możemy podzielić na 3 główne rodzaje:

  1. Reflected XSS,
  2. Stored XSS
  3. oraz DOM Based XSS.

Zacznijmy od najprostszego rodzaju - czyli Reflected XSS. Tutaj parametr od użytkownika jest wyświetlany na stronie bez żadnej lub z drobną modyfikacją. Parametr ten może być częścią adresu URL lub też polem wysłanym w zwykłym formularzu. Może też być nagłówkiem wysyłanym przez przeglądarkę, chociażby polem User-agent.

To pole jest automatycznie wysyłane przez każdą przeglądarkę i znajduje się tam informacja o nazwie oraz wersji przeglądarki, której używa użytkownik. Jak to się zatem dzieje, że dane od użytkownika - jeżeli są wyświetlane na stronie, mogą być niebezpieczne? Przecież praktycznie każda obecna strona pozwala na tworzenie własnych treści przez użytkowników.

HTML

Problem tkwi w szczegółach. Większość stron opiera się na składni HTML. To właśnie z tych klocków składa się schemat strony, któremu następnie przy pomocy kaskadowych arkuszy stylów nadaje się piękny wygląd. W HTMLu możemy używać tagów - czyli specjalnych sformułowań, które są rozpoznawane przez przeglądarkę.

Zazwyczaj jest to ciąg znaków zawarty pomiędzy znakami mniejszości i większości. Dla przykładu: tag <b> - informuje przeglądarkę o tym, że tekst pomiędzy takim tagiem powinien być pogrubiony. Również inne główne elementy każdej strony internetowej tworzy się w podobny sposób. Tak definiuje się zatem każdy obrazek, tabelkę czy też pole w formularzu. Upraszczając: przeglądarka napotykając na znak mniejszości lub większości spodziewa się tagu, który musi odpowiednio obsłużyć. Jeżeli zatem dane od użytkownika są wyświetlane na stronie bez żadnych zmian, nic nie stoi na przeszkodzie aby zawierały one kod HTML. Przecież użytkownik może wysłać w parametrze do adresu URL ciąg <b> - sprawiając tym samym, że tekst będzie pogrubiony.

HTML Injection

Taka sama sprawa dotyczy pola w formularzu. Jeżeli atakujący prześle kod HTML na podatnej stronie - mamy do czynienia z HTML Injection. Jest to pewien rodzaj ataków XSS, nie taki groźny jak ten pierwszy. Nie wszystkie akcje bowiem da się wykonać przy użyciu samego HTML, bez żadnego kodu JavaScript. Dlatego też ten rodzaj ataku jest rzadko spotykany - głównie w stronach phishingowych, kiedy to odpowiednio pokolorowany tekst na stronie głównej serwisu - wyglądający jak komunikat od administratora tej witryny, próbuje przekonać użytkownika do wykonania jakiejś złośliwej akcji.

Tag script

Ale nowoczesne strony korzystają z dużej ilości kodu JavaScript. Tak się składa, że je również umieszcza się na stronie przy pomocy odpowiedniego tagu. Jest to tag <script> i generalnie można go używać na dwa sposoby.

  1. Pierwszy - w którym definiujemy adres do zewnętrznego skryptu, który zostanie pobrany przez przeglądarkę i odpowiednio zinterpretowany.
  2. Drugi - gdzie treść skryptu znajduje się bezpośrednio w kodzie strony pomiędzy tagiem script.

I właśnie to jest niebezpieczne. Bo jeżeli strona nie filtruje parametrów od użytkownika - to równie dobrze może on podać jako parametr tag <script> a następnie kod JavaScript. Przeglądarka wyświetlając daną stronę - dochodząc do tagu <script> po prostu wykona kod, który się tam znajduje. A ten kod nie został stworzony przez programistów danej aplikacji. No dobrze - ale jak to się dzieje, że większość stron nie jest podatna na ten atak? Mówiłem już, że przeglądarka napotykając na znak większości lub mniejszości spodziewa się tam napotkać tag.

Encje

Ale co w przypadku, kiedy chce użyć w swoim tekście tych znaków - na przykład w kontekście jakiejś matematycznej operacji. Z tego też powodu powstały encje, czyli znaki specjalne zaczynające się od &. Znak mniejszości zapisuje się przy pomocy encji jako &lt;. Encje są traktowane przez przeglądarkę jako zwykły znak i nawet pomimo tego iż jest to znak mniejszości - który otwiera w html tagi - przeglądarka napotykając taki znak będzie go traktowała jako zwykły tekst. Ochrona przed tymi atakami opiera się zatem na odpowiednim filtrowaniu danych od użytkownika, zamieniając pewne specyficzne znaki na encje. Wtedy to parametr jest traktowany jako tekst i nie może wyrządzić żadnej szkody.

XSS Stored

Na razie mówiliśmy o atakach reflected - czyli parametrach od użytkownika, które są wyświetlane na bieżącej stronie. Ale ten atak z punktu widzenia przestępców ma pewien minus. Jeżeli bowiem chcemy kogoś zaatakować, musimy jakoś przekazać złośliwą treść w parametrze. Ciężko mi sobie wyobrazić atak, w którym prosi się użytkownika o wklejenie jakiegoś długiego, niezrozumiałego ciągu znaków do formularza.

Dlatego też najczęściej używa się do tego celu odpowiednio spreparowanych adresów URL. Ofiara musi zatem otrzymać taki adres od atakującego, a następnie go kliknąć. W tym adresie znajdują się złośliwe wartości parametrów - które są następnie wyświetlane w kontekście bieżącej strony. Posiadając dostęp do wykonywania kodu, atakujący może zrobić wiele rzeczy. Najpopularniejszą jest pobranie ciasteczek użytkownika. One to są wysyłane do serwera automatycznie przez przeglądarkę z każdym żądaniem. To na ich podstawie serwer wie, że my to my. Jeżeli atakujący pozyska takie ciasteczko, może wykorzystać je do zalogowania się na nasze konto - i to wszystko bez znajomości naszego hasła. Ciasteczko jest bowiem generowane już po sprawdzeniu danych logowania użytkownika.

XSS Auditor

Z poziomu kodu JS może również wykonać dowolną akcję jako dany użytkownik. A tu możliwości są nieograniczone: od zmiany naszego hasła, po wysłanie dowolnej wiadomości, czy też po prostu usunięcie naszego konta w tym serwisie. Ba, można również monitorować klawisze wciskane na danej stronie. Atak XSS jest bardzo popularny - co nie dziwi. Bardzo łatwo przy dużym serwisie zapomnieć o jakimś jednym parametrze - sprawiając tym samym, że może zostać użyty do niecnych celów. Sytuację tą zauważyli również producenci przeglądarek - i postanowili coś z tym zrobić.

Tak narodził się koncept XSS Auditor. Idea za nim stojąca jest prosta do wyjaśnienia. Przeglądarka monitoruje wszystkie parametry przekazywane przez użytkownika. Jeżeli któryś z nich zawiera kod JavaScript i dokładnie ten sam kod pojawia się w treści strony i próbuje być wykonany - przeglądarka blokuje takie wykonanie. Dzięki temu nawet jeżeli strona jest podatna to atakujący nie może wykorzystać tej podatności. Oczywiście co jakiś czas pojawiają się metody na ominięcie tego zabezpieczenia, co nie zmienia faktu, że ta metoda jest skuteczna. To spowodowało, że ataki Reflected nie są popularne wśród przestępców - ponieważ pomimo istnienia błędu, kod nie wykonuje się u ofiary.

Atak Stored XSS

Stąd też druga metoda - czyli ataki Stored XSS. Tym razem, żeby atak się powiódł, konieczne są dwa elementy. Pierwszy z nich to wysłanie złośliwego parametru. Tylko, że tym razem nie jest on od razu wyświetlany na stronie, a zapisywany w jakimś miejscu - zazwyczaj bazie danych. Teraz wystarczy już tylko wejść na odpowiednią podstronę, która pobierze zapisaną wcześniej treść z bazy danych i wyświetli ją. Jeżeli tutaj ponownie (jak w atakach reflected) treść jest zapisywana do bazy i wyświetlana z niej bez żadnej walidacji - atakujący, może przemycić tam swój kod. Ten atak jest dużo groźniejszy.

Jeżeli bowiem strona posiada ogólnodostępną funkcjonalność, która jest podatna - wystarczy, że atakujący sam wprowadzi tam złośliwy kod tylko raz. Każdy odwiedzający podatną podstronę, za każdym razem pobierze z bazy danych ten sam złośliwy kod, który zostanie u nich wykonany. W tym rodzaju podatności zatem nie trzeba wysyłać żadnego linku do atakowanej osoby. Co więcej XSS Auditor tutaj nie zadziała, ponieważ wchodząc na wyświetlaną podstronę nie przekazujemy już żadnego złośliwego parametru.

Dom Based XSS

Ostatnim głównym rodzajem ataków XSS jest Dom Based XSS. Kod HTML może być bowiem tworzony również z poziomu kodu JavaScript. Jeżeli więc na stronie istnieje kod JS, który pobiera jakieś parametry z adresu URL, a następnie na jego podstawie tworzony jest nowy kod HTML - to również tu może dojść do błędu. Jeżeli bowiem ten parametr nie jest odpowiednio traktowany - on również może wyrządzić szkodę użytkownikowi.

Na sam koniec warto wspomnieć, że tag <script> to nie jedyna możliwość jeśli chodzi o wykonywanie kodu. Sporo innych tagów posiada tak zwane event handlery, czyli metody obsługi zdarzeń. Dzięki nim można oskryptować dodatkowe zdarzenia, które wykonają się, gdy użytkownik wykona jakąś akcję. Na przykład handler onclick zawiera kod, który wykona się po kliknięciu w dany element. Dlatego też ochrona przed atakami XSS nie może jedynie polegać na blokowaniu pól, jeżeli znajduje się w nich wyraz “script”. Inną, dodatkową, bardziej zaawansowaną metodą obrony jest mechanizm CSP - czyli Content Security Policy, w którym można zdefiniować miejsca, z których mogą wykonywać się skrypty. Jest to więc lista reguł, która obowiązuje przeglądarkę. Jeżeli napotka ona skrypt, pochodzący z innej domeny - nie pozwoli na jego wykonanie.

Handlers

I to już wszystko w tym odcinku. A w następnym dowiesz się o niebezpiecznej deserializacji obiektów. W międzyczasie zapraszam do posłuchania podcastu Szurkogadanie, w którym opowiadam co ostatnio działo się w branży bezpieczeństwa. Jeżeli ten materiał Ci się spodobał nie zapomnij o subskrypcji kanału i zostawieniu łapki w górę. Do zobaczenia. Cześć!

Cables from the Side by Simon Waldock CC BY 3.0 Stock video by Videezy.com Design vector created by freepik - www.freepik.com Icon made by Freepik, Vectors Market, Smashicons, Eucalyp, Flat Icons, Dreamstale, juicy_fish www.flaticon.com