Stored XSS
| Po angielsku | stored XSS |
|---|---|
| Którą formą pisać | po angielsku Polski odpowiednik istnieje, ale w praktyce nikt tak nie pisze. Zostaw angielski, polski trzymaj jako synonim. |
| Inne formy | trwały XSS · przechowywany XSS |
| Kategoria | Podatności i klasy błędów |
Stored XSS to odmiana XSS (Cross-Site Scripting), w której złośliwy skrypt zostaje trwale zapisany na serwerze, na przykład w bazie danych, na forum, w logu odwiedzin albo w polu komentarza [2]. Ofiara pobiera go razem z zapisaną treścią, gdy otwiera stronę, która ją wyświetla [2]. MITRE nazywa tę odmianę typem 2 i opisuje ją jako sytuację, w której aplikacja zapisuje niebezpieczne dane, a później dołącza je do treści dynamicznej [1]. W polskich źródłach spotyka się też nazwę Persistent XSS [3].
Jak działa
Atak ma dwa etapy rozdzielone w czasie. Najpierw atakujący wysyła treść z ładunkiem: komentarz, wpis na forum, pole profilu albo nazwę przesyłanego pliku. Aplikacja zapisuje ją bez neutralizacji. Później każdy użytkownik, który otworzy stronę z tą treścią, otrzymuje skrypt w kodzie HTML i jego przeglądarka go wykonuje. Schemat poniżej pokazuje przebieg z komentarzem na blogu.
Sekurak opisuje ten scenariusz wprost: atakujący wstawia JavaScript w komentarz na blogu, a gdy moderator przegląda komentarz, kod uruchamia się automatycznie i może wykraść sesyjne ciasteczka administratora [3]. Stored XSS nie wymaga więc namawiania ofiary do kliknięcia w link. Wystarczy, że wykona swoją zwykłą pracę.
Odmiany
OWASP wyróżnia jako formę trwałego XSS także Blind XSS: ładunek zapisany przez atakującego wyświetla się w aplikacji zaplecza, na przykład gdy administrator przegląda zgłoszenia z formularza opinii [2]. Atakujący nie widzi wtedy momentu wykonania skryptu. Porównanie z innymi typami XSS zawiera tabela poniżej.
| Odmiana | Gdzie jest ładunek | Kto uruchamia skrypt |
|---|---|---|
| Stored XSS (typ 2) | w bazie, na forum, w logu [1] | każdy, kto wyświetli treść [2] |
| Blind XSS | w danych czytanych w zapleczu [2] | pracownik lub administrator [2] |
| Reflected XSS (typ 1) | w żądaniu HTTP [1] | ofiara, która kliknie link [2] |
| DOM-based XSS (typ 0) | w kodzie po stronie klienta [1] | skrypt strony [1] |
Sekurak określa Persistent XSS jako najbardziej złowrogą z trzech omawianych odmian [3].
W WordPressie
Stored XSS w WordPressie ma szczególną postać: treść zapisuje jeden użytkownik, a wyświetla inny, często z wyższymi uprawnieniami. Dlatego znaczenie mają role i uprawnienia użytkowników. Uprawnienie unfiltered_html pozwala publikować znaczniki HTML, a nawet JavaScript we wpisach, stronach, komentarzach i widżetach [5]. Na pojedynczej witrynie mają je administrator i redaktor; autor i współpracownik go nie mają [5], więc wstawiany przez nich HTML powinien przejść przez filtr. Dokumentacja ostrzega, że nadanie tego uprawnienia niezaufanym użytkownikom może skończyć się publikacją złośliwego kodu [5].
Błędy tej klasy zdarzają się także w rdzeniu. Wydanie WordPress 7.0.3 z 6 sierpnia 2026 roku naprawiło między innymi cztery podatności Stored XSS dostępne dla konta współpracownika lub wyższego: przez element ustawień emoji we wpisach, w bloku Post Content, w Szybkiej edycji na witrynach z dużą liczbą użytkowników i w bloku Post Date [6]. Poprawki przeniesiono do wszystkich gałęzi, które otrzymują łatki bezpieczeństwa, obecnie do 4.7 [6]; stąd waga aktualizacji rdzenia WordPressa. Źródłem bywają też podatności we wtyczkach, które zapisują pola formularzy, ustawienia albo metadane i wypisują je bez kodowania.
Zagrożenia i skutki
MITRE wymienia jako skutki XSS ujawnienie danych z ciasteczek i sesji oraz, w połączeniu z innymi błędami, wykonanie dowolnego kodu [1]. OWASP opisuje zakres skutków od uciążliwości do pełnego przejęcia konta [2]. Sekurak zauważa, że dzięki Stored XSS atakujący ma dostęp do zalogowanej sesji administracyjnej bez znajomości loginu i hasła [3].
- Przejęcie sesji administratora, który otworzy zainfekowaną stronę panelu.
- Utworzenie nieautoryzowanego konta administratora żądaniem wysłanym przez skrypt.
- web skimming w sklepie, gdy ładunek trafi na stronę płatności.
- Trwałość: skrypt działa, dopóki treść nie zostanie usunięta z bazy.
Jak się bronić
Obrona zaczyna się przy wyjściu. 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 kodowanie jak najpóźniej, tuż przed wypisaniem [4]. Dla Stored XSS to kluczowe, bo dane w bazie mogły trafić tam wiele lat wcześniej, przed wprowadzeniem filtra na wejściu.
Funkcję dobiera się do kontekstu: esc_html() dla treści elementu, esc_attr() dla atrybutu, esc_url() dla adresu, a wp_kses() tam, gdzie wolno zostawić wybrane znaczniki [4]. Po stronie wejścia działa sanityzacja danych wejściowych. MITRE zaleca dodatkowo flagę HttpOnly na ciasteczkach sesji oraz zapory aplikacyjne jako obronę warstwową [1]; zob. flagi ciasteczek i WAF. Kolejną warstwą jest CSP (Content Security Policy), która ogranicza wykonywanie skryptów w linii.
Historia i przykłady
CERT Polska opisuje podatności tej klasy konsekwentnie jako „atak typu Stored XSS”. W publikacji z 10 lipca 2026 roku o systemie R-SOFT DMS podatność CVE-2026-41877 pozwala uwierzytelnionemu atakującemu wstrzyknąć kod HTML i JavaScript do nazwy przesyłanego pliku, który wykonuje się u użytkowników przeglądających listę plików [7]. W publikacji z 18 czerwca 2026 roku o forum UBB.threads podatność CVE-2026-54219 dotyczy wstrzykiwania JavaScriptu przez posty i pola profili użytkowników, bo aplikacja nie sanityzuje poprawnie danych wejściowych [8]. Podatne są wersje do 7.7.5 włącznie [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] Czym jest XSS? · Sekurak
- [4] Escaping Data — Common APIs Handbook · WordPress.org
- [5] Roles and Capabilities · WordPress.org
- [6] WordPress 7.0.3 Release · WordPress.org
- [7] Podatności w oprogramowaniu R-SOFT DMS (CVE-2026-41876 i inne) · CERT Polska
- [8] Podatności w oprogramowaniu UBB.threads (CVE-2026-54219 i inne) · CERT Polska