
Zabezpieczenie przed XSS
Ten artykuł jest częścią serii o zagrożeniu 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:
- przy ich wejściu do aplikacji – w tym przypadku musimy się upewnić, że dane zapisane w bazie danych nie zawierają złośliwych sekwencji. Można to zrobić na następujące sposoby:
- ścisła walidacja – https://cheatsheetseries.owasp.org/cheatsheets/Input_Validation_Cheat_Sheet.html#White_List_Regular_Expression_Examples
- escapowanie – https://www.w3.org/International/questions/qa-escapes
- użycie biblioteki do walidacji – np. AntiXSS dla .NET
- przy ich wyjściu z aplikacji – warto również zadbać o bezpieczeństwo podczas wyświetlania. Możemy to zrobić za pomocą:
- sanityzacji – https://www.troyhunt.com/understanding-xss-input-sanitisation/
- escapowania kodu HTML – https://www.w3.org/International/questions/qa-escapes
- 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.

- nagłówek
Content-Security-Policy
Alternatywa dla poprzedniego nagłówka; jednak wspieraną (i zalecaną) przez najnowsze przeglądarki jest odpowiednie użycieContent-Security-Policy
bez pozwalania naunsafe-inline
dla skryptów. Widać też, że w tym przypadku większość przeglądarek wspiera ten standard.

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.