Zabezpieczenie przed XSS

Zabezpieczenie przed XSS

Ten artykuł jest częścią serii o zagrożeniu XSS:

  1. Co to jest XSS?
  2. Wykrywanie XSS
  3. Automatyczne wykrywanie XSS
  4. Zabezpieczenie przed XSS

W ramach mojego cyklu artykułów dotyczących zagrożenia XSS (Cross Site Scripting) przyszedł czas na opisanie sposobów zabezpieczenia aplikacji. Potraktuj to jednak bardziej jako podsumowanie różnych metod zabezpieczenia niż jako pełne kompendium. Jeżeli zależy Ci na pełnym opisie określonych technik mitygacji, zwróć uwagę na linki do dodatkowych materiałów, które dołączę w treści artykułu.

W temacie zabezpieczenia przez atakami XSS można wyróżnić kilka poziomów zabezpieczeń:

  • ochrona przed właściwym XSS, 
  • ochrona przed jego skutkami. 

W idealnym rozwiązaniu tylko jeden poziom byłby potrzebny. Zakładając, że poprawnie zabezpieczyliśmy się przed samym Cross Site Scriptingiem, nie mielibyśmy powodów, żeby zabezpieczać się dodatkowo przed jego skutkami. Jednak w rzeczywistości ciężko być w 100% pewnym zabezpieczenia przed tego typu atakami. Dlatego też warto zastosować dodatkowe środki ochronne.

Zabezpieczenie przed XSS

Pierwszy poziom to ochrona przed właściwym wykorzystaniem podatności XSS. Jak już wspomniałem w opisie tego zagrożenia [] XSS polega na wykonaniu złośliwego skryptu pochodzącego od atakującego w przeglądarce innego użytkownika. Żeby temu skutecznie przeciwdziałać wystarczy zadbać o wszystkie teksty w naszej aplikacji, które są wyświetlane w interfejsie. Można przyjąć, że każdy tekst pochodzący od użytkownika jest niezzaufany i wymaga kontroli lub zabezpieczenia przed pokazaniem go. W szczególności te dostępne dla innych użytkowników. Przykładem tu mogą być dane klienta sklepu, które potem widoczne są w panelu administracyjnym.

Zabezpieczenie tekstów

Zabezpieczenie tekstów pochodzących od użytkownika można zrobić na 2 sposoby:

  • Warto tu zwrócić uwagę, że niektóre biblioteki lub frameworki frontendowe mają wbudowaną sanityzację każdego dynamicznego tekstu w aplikacji (np. React lub Angular)

W ogólności powinno wystarczyć zabezpieczenia tylko jednej strony przetwarzania (wejścia lub wyjścia). Jednak podobnie jak poprzednio ze względu na brak pewności co do skuteczności naszych rozwiązań dużo lepiej jest zabezpieczyć obydwa końce.

Mechanizmy przeglądarki

Kolejną metodą na zabezpieczenie przez atakami XSS jest skorzystanie z wbudowanych mechanizmów nowszych przeglądarek. W tym przypadku jest to zabezpieczenie tylko przed atakiem Reflected XSS. Mamy jednak do wyboru dwie opcje:

  • nagłówek X-XSS-Protection
    Pozwala sterować mechanizmem blokowania wyświetlania strony jeżeli atak XSS zostanie wykryty przez przeglądarkę. Jednak patrząc na zakres obsługi tego nagłówka w obecnych przeglądarkach warto go używać jedynie w celu kompatybilności wstecznej.
Zabezpieczenie przed XSS - XSS-Protection - wsparcie
XSS-Protection – wsparcie
  • nagłówek Content-Security-Policy
    Alternatywa dla poprzedniego nagłówka; jednak wspieraną (i zalecaną) przez najnowsze przeglądarki jest odpowiednie użycie Content-Security-Policy bez pozwalania na unsafe-inline dla skryptów. Widać też, że w tym przypadku większość przeglądarek wspiera ten standard.
Zabezpieczenie przed XSS - Content-Security-Policy - wsparcie
Content-Security-Policy – wsparcie

Ochrona przed skutkami

Powiedzieliśmy już sobie o ochronie przed atakiem XSS. Jednak nigdy nie mamy pewności, czy coś nie umknęło naszym filtrom. Jak widać w OWASP XSS filter evasion cheatsheet istnieje bardzo wiele metod na obejście standardowych mechanizmów zabezpieczenia. W związku z tym warto zabezpieczyć się również przed skutkami XSS. Mianowicie przed wykradzeniem danych z ciasteczek i wysyłce danych poza naszą aplikację.

Ochrona cookies

W ciasteczkach mogą znajdować się wrażliwe informacje, takie jak tokeny dostępowe lub identyfikatory sesji użytkownik. Ich kradzież mogłaby umożliwić nieuprawnionym osobom na dostęp do konta innego użytkownika.Podstawowym mechanizmem ochrony ciasteczek jest flaga HttpOnly jest ona ustawiana na konkretnym ciasteczku. Wskutek tego jest ono niedostępne z poziomu Java Script (jest tylko wysyłane do serwera przy każdym requeście).Dzięki temu nawet, gdy ktoś uruchomi złośliwy skrypt, nie będzie miał dostępu do wrażliwych danych.

Szczegóły: 
https://developer.mozilla.org/pl/docs/Web/HTTP/Cookies#ciasteczka_secure_i_httponly

Content-Security-Policy

Kolejną metodą zabezpieczenia jest skorzystanie z pełnego mechanizmu Content-Security-Policy. Dyrektywa ta pozwala sterować możliwościami aplikacji w zakresie wykonywania zapytań.
Zabezpiecza on aplikację na 2 sposoby:

  • nie pozwalając na wykonywanie nieautoryzowanych skryptów (poprzez brak zdefiniowania script-src 'unsafe-inline';)
  • nie pozwalając na połączenia z niezaplanowanymi domenami (poprzez odpowiednie zdefiniowanie Content-Security-Policy: connect-src <source>;)

Szczegóły:
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy
Polecam również mój artykuł o [] poziomach dojrzałości ochrony CSP. 

Podsumowanie

Mamy wiele możliwości ochrony przed XSS. Czyli mógłby się to wszystko wydawać bardzo proste, tymczasem zagrożenie to nadal znajduje się na liście 10 najpopularniejszych podatności w aplikacjach webowych. Warto więc zadbać o zabezpieczenie aplikacji z wielu różnych stron przed tym atakiem.
Jeżeli temat Cię zainteresował, polecam przejrzeć materiały dołączone przeze mnie do każdego z tematów (pod hasłem Szczegóły). Dodatkowo polecam dokładny opis OWASP XSS Prevention Cheat Sheet