XSS (Cross-Site Scripting)
| Po angielsku | cross-site scripting (XSS) |
|---|---|
| Którą formą pisać | bez tłumaczenia Skrót, nazwa własna albo nazwa standardu — nie tłumaczymy w ogóle. |
| Inne formy | skrypty międzyserwisowe |
| Kategoria | Podatności i klasy błędów |
XSS (Cross-Site Scripting) to podatność, w której aplikacja nie neutralizuje albo błędnie neutralizuje danych kontrolowanych przez użytkownika, zanim umieści je na stronie podawanej innym użytkownikom [1]. Efektem jest skrypt atakującego wykonywany w przeglądarce ofiary tak, jakby pochodził z zaufanej witryny. OWASP zalicza XSS do ataków typu wstrzyknięcie, w których złośliwe skrypty trafiają do skądinąd nieszkodliwych i zaufanych serwisów [2]. W zestawieniu CWE Top 25 za 2024 rok słabość CWE-79 zajęła pierwsze miejsce [3].
Jak działa
Według OWASP podatność XSS powstaje, gdy spełnione są dwa warunki: dane trafiają do aplikacji z niezaufanego źródła, najczęściej z żądania HTTP, i zostają dołączone do treści dynamicznej wysyłanej użytkownikowi bez sprawdzenia [2]. Przeglądarka nie odróżnia wtedy kodu strony od kodu wstrzykniętego. Skrypt działa z uprawnieniami witryny: widzi jej treść, może wysyłać żądania w imieniu zalogowanego użytkownika i czytać ciasteczka, które nie mają flagi HttpOnly.
Przebieg typowego ataku przez złośliwy link pokazuje schemat poniżej.
Mechanizm widać na prostym przykładzie w PHP. Pierwsza linia wypisuje parametr wprost, druga koduje go dla kontekstu HTML.
echo 'Wyniki dla: ' . $_GET['q']; // podatne
echo 'Wyniki dla: ' . esc_html( $_GET['q'] ); // zakodowane
Odmiany
MITRE wyróżnia trzy główne typy XSS [1]. Różnią się tym, gdzie ładunek jest przechowywany i kto składa go w stronę.
| Odmiana | Gdzie jest ładunek | Jak dociera do ofiary |
|---|---|---|
| Reflected XSS (typ 1) | w żądaniu HTTP, odbity w odpowiedzi [1] | link w mailu albo na innej stronie [2] |
| Stored XSS (typ 2) | w bazie, forum, logu odwiedzin [1] | każde wyświetlenie zapisanej treści [2] |
| DOM-based XSS (typ 0) | w kodzie JavaScript po stronie klienta [1] | skrypt strony sam wstawia dane do DOM [1] |
Stored XSS jest zwykle groźniejszy od odbitego, bo nie wymaga namawiania ofiary do kliknięcia. Wystarczy, że administrator otworzy w panelu komentarz albo wpis z ładunkiem.
W WordPressie
W WordPressie większość błędów XSS dotyczy wtyczek i motywów, które wypisują dane bez kodowania; zob. podatność we wtyczce i podatność w motywie. Rdzeń udostępnia funkcje do obu stron obrony.
Kodowanie wyjścia. Dokumentacja WordPressa definiuje escapowanie jako zabezpieczanie danych wyjściowych przez usuwanie niechcianych elementów, takich jak zniekształcony HTML albo znaczniki skryptów [4]. Zaleca zasadę „escape late”: kodować jak najbliżej miejsca wypisania, bo to ułatwia przegląd kodu i automatyczne skanowanie [4]. Funkcja dobierana jest do kontekstu.
| Funkcja | Kontekst |
|---|---|
esc_html() | treść elementu HTML [4] |
esc_attr() | wartość atrybutu HTML [4] |
esc_url() | adres w href, src i podobnych [4] |
esc_js() | JavaScript w linii [4] |
wp_kses(), wp_kses_post() | HTML z listą dozwolonych znaczników [4] |
Czyszczenie wejścia. Sanityzacja to według dokumentacji zabezpieczanie, czyszczenie i filtrowanie danych wejściowych [5]. Walidacja jest preferowana, bo jest bardziej precyzyjna; sanityzacja jest następnym wyborem, gdy walidacja nie jest możliwa [5]. Przykładowo sanitize_text_field() sprawdza poprawność UTF-8 i usuwa wszystkie znaczniki [5].
Uprawnienie unfiltered_html. Uprawnienie unfiltered_html pozwala publikować znaczniki HTML, a nawet kod JavaScript we wpisach, stronach, komentarzach i widżetach [6]. Na pojedynczej witrynie mają je administrator i redaktor, a w sieci Multisite tylko superadministrator [6]. Dokumentacja ostrzega, że nadanie go niezaufanym użytkownikom może skończyć się publikacją złośliwego kodu [6]. Dlatego ważne są role i uprawnienia użytkowników: autor i współpracownik tego uprawnienia nie mają [6], więc wstawiany przez nich HTML powinien przejść przez filtr.
Zagrożenia i skutki
MITRE wymienia jako skutki XSS ujawnienie informacji z ciasteczek i danych sesji, kradzież lub manipulację ciasteczkami, a w połączeniu z innymi błędami wykonanie dowolnego kodu [1]. OWASP dodaje przejęcie sesji, nieuprawniony dostęp do kont, podmianę treści strony, instalację złośliwego oprogramowania i przekierowania na strony atakującego [2].
- Przejęcie sesji i przejęcie konta przez kradzież tokenu sesyjnego.
- Działania w panelu w imieniu administratora, na przykład utworzenie nieautoryzowanego konta administratora.
- Podmiana treści strony i złośliwe przekierowania.
- web skimming, czyli podsłuch formularzy płatności w sklepie.
Jak się bronić
Podstawą jest kodowanie danych przy wyjściu, dopasowane do kontekstu, i walidacja przy wejściu. MITRE zaleca sprawdzone biblioteki i frameworki, kodowanie wyjścia, walidację wejścia z listą dozwolonych wartości oraz flagę HttpOnly na ciasteczkach sesji [1]. Jako obronę warstwową wymienia też zapory aplikacyjne [1], czyli WAF.
Drugą warstwą jest CSP (Content Security Policy). MDN opisuje Content Security Policy jako zestaw instrukcji od witryny do przeglądarki, ograniczających to, co kod strony może robić, używany głównie przeciw XSS [7]. Jeśli polityka zawiera dyrektywę default-src albo script-src, skrypty w linii nie wykonają się bez dodatkowego oznaczenia, na przykład jednorazowego nonce albo skrótu [7]. MDN zaznacza, że CSP nie zastępuje czyszczenia danych wejściowych: strona powinna robić jedno i drugie [7]. CSP należy do szerszej grupy nagłówków bezpieczeństwa HTTP.
Historia i przykłady
Błędy XSS występują także w oprogramowaniu używanym w Polsce. CERT Polska 2 czerwca 2026 roku opublikował informację o podatnościach w systemie Wirtualna Uczelnia firmy Simple SA; jedna z nich, CVE-2026-34907, to Reflected Cross-Site Scripting w parametrze locale w kilku punktach końcowych [8]. Ta sama publikacja opisuje CVE-2026-34906, wstrzyknięcie szablonu po stronie serwera prowadzące do zdalnego wykonania kodu [8]. Wersje późniejsze niż wskazana w komunikacie kompilacja z 27 marca 2026 roku nie są już podatne [8].
Przypisy
8- [1] CWE-79: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting') · MITRE
- [2] Cross Site Scripting (XSS) · OWASP
- [3] 2024 CWE Top 25 Most Dangerous Software Weaknesses · MITRE
- [4] Escaping Data — Common APIs Handbook · WordPress.org
- [5] Sanitizing Data — Common APIs Handbook · WordPress.org
- [6] Roles and Capabilities · WordPress.org
- [7] Content Security Policy (CSP) · MDN Web Docs
- [8] Podatności w oprogramowaniu Wirtualna Uczelnia (CVE-2026-34906, CVE-2026-34907) · CERT Polska
Hasła w tym artykule
20- podatność
- Reflected XSS
- Stored XSS
- DOM-based XSS
- podatność we wtyczce
- podatność w motywie
- escapowanie
- sanityzacja danych wejściowych
- role i uprawnienia użytkowników
- przejęcie sesji
- przejęcie konta
- token sesyjny
- nieautoryzowane konto administratora
- podmiana treści strony (defacement)
- złośliwe przekierowanie
- web skimming
- WAF
- CSP (Content Security Policy)
- nonce
- nagłówki bezpieczeństwa HTTP
Linkują tutaj
48- podatność
- OWASP Top 10
- ładunek
- łatka (patch)
- SQL injection
- przejęcie konta
- CWE
- CSRF (Cross-Site Request Forgery)
- nonce
- escapowanie
- fałszywy alarm
- podatność we wtyczce
- WAF
- porzucona wtyczka
- bug bounty
- CVSS
- sanityzacja danych wejściowych
- Stored XSS
- edytor plików motywów i wtyczek
- CSP (Content Security Policy)
- ModSecurity
- RFI (Remote File Inclusion)
- Reflected XSS
- SSTI
- flagi ciasteczek
- nagłówki bezpieczeństwa HTTP
- podatność w motywie
- prototype pollution
- CORS misconfiguration
- CSV injection
- DOM-based XSS
- HTTP request smuggling
- LFI (Local File Inclusion)
- open redirect
- session fixation
- subdomain takeover
- web cache poisoning
- przejęcie sesji
- clickjacking
- drive-by download
- exploit kit
- skanowanie podatności
- JWT (JSON Web Token)
- token sesyjny
- CERT Polska / CSIRT NASK, CSIRT GOV, CSIRT MON
- vibe coding
- unfiltered_html
- WPCS