Mniej więcej na początku sierpnia ktoś przesłał mi dość długi adres prowadzący do strony internetowej dostawcy telewizji i internetu Vectra, w którym zaszyty był kod CSS. Pominąwszy celowe modyfikacje, odnośnik przedstawiał się następująco:
hxxps://www[.]vectra[.]pl/oferta-internet-swiatlowodowy?city_name=%3Cstyle%3E*+%7Bfont-family%3A+cursive+!important%3B+background-size%3A+contain%3B+background-image%3A+url(%27https%3A%2F%2Fwarsawsecurityforum.org%2Fwp-content%2Fuploads%2F2025%2F09%2FDonald-Tusk-scaled.webp%27)%7D%3C%2Fstyle%3E&city=544591&street=tuskowa&number=7
Otwarcie linku powodowało, iż użytkownik trafiał na stronę Vectry wypełnioną zdjęciami portretowymi Donalda Tuska tam, gdzie tylko się dało. Piszę „powodowało” – bo w prawie miesiąc po zgłoszeniu dostałem potwierdzenie, iż błąd został usunięty. Wolałem być pewny, iż nie opisuję podatności, którą da się jeszcze w jakikolwiek sposób wykonać.
Na czym polegała podatność?
Opisywany przypadek to „reflected XSS” – czyli rodzaj ataku, który uruchamia się po kliknięciu w specjalnie spreparowany link. Dobrze zabezpieczona strona internetowa odmówi wykonania zaszytego wewnątrz takiego linku kodu. adekwatne praktyki to między innymi odpowiednio skonfigurowany nagłówek Content-Security-Policy, ale też – co ważniejsze – automatyczne filtrowanie wprowadzanych do strony internetowej danych (po angielsku proces ten nazywa się „sanitisation”).
Łącza spreparowane w celu przeprowadzania ataków „reflected XSS” mogą zawierać kod HTML, CSS czy JavaScript, w szczególności więcej niż jeden lub wszystkie naraz. Odpowiednio oczyszczone dane – choćby gdybyśmy próbowali dodać w konkretnym miejscu w adresie JavaScriptowe alert(1) czy kod CSS wymuszający wszędzie pogrubioną czcionkę – nie powinny spowodować żadnej niepożądanej zmiany w odwiedzanej przez nas witrynie.
Zanim wysłałem zgłoszenie, sprawdziłem sytuację na stronie Vectry – tam kod JavaScript nie zostawał wykonany. Można było jednak wprowadzać własne style.
Sam CSS też bywa wystarczający chociażby do zdobywania podstawowych danych na temat użytkowników. Wystarczy do tego instrukcja url(), która wykonuje zapytania sieciowe. Spójrzmy jeszcze raz na link z początku artykułu – znajdziemy taką instrukcję:
...background-image%3A+url(%27https%3A%2F%2Fwarsawsecurityforum.org%2Fwp-content%2Fuploads%2F2025%2F09%2FDonald-Tusk-scaled.webp%27)...
Kiedy zostaje wykonana, przeglądarka wysyła zapytanie sieciowe do strony warsawsecurityforum.org, na której znajduje się zdjęcie portretowe premiera. Właściciele strony warsawsecurityforum.org mają już podstawowe dane na temat użytkownika, to jest: adres IP, czas wykonania żądania, informację zwrotną, czy się ono udało, być może także wizytówkę przeglądarki (user agent).
Warto jednak pamiętać, iż style na stronie możemy aplikować warunkowo. Wyobraźmy sobie, iż chcemy ostylować pola tekstowe noszące parametr name o wartości sq. Style do takich pól tekstowych możemy aplikować dzięki warunku input[name=sq]. Konkretne przykłady, jak dzięki tej techniki można wyłudzić potencjalnie poufne dane, opisał Mike Gualtieri na swoim blogu.
Jak zgłosiłem ten błąd
Po pewnym czasie, gdy już sprawdziłem wiarygodność tego błędu, uznałem, iż jest on na tyle poważny, iż należało go zgłosić Vectrze. Zacząłem szukać dedykowanego kanału kontaktu z firmą w sprawie problemów z bezpieczeństwem. Niestety, na próżno.
W końcu zdecydowałem się użyć standardowego formularza do kontaktu z konsultantem Vectry, żeby ten mógł eskalować sprawę dalej do odpowiedniego działu. Na pytanie, kim jestem, zaznaczyłem, iż „jestem klientem indywidualnym” (choć internet dostarcza mi zupełnie inna firma – musiałem zaznaczyć cokolwiek, żeby formularz mógł w ogóle dotrzeć do konsultanta) i wypełniłem formularz swoimi danymi kontaktowymi. Odpowiedź otrzymałem dzień później.
Brzmiała ona: „uprzejmie proszę o informację, jaki komunikat pojawia się na ekranie po wpisaniu adresu strony lub jaki komunikat pojawia się w programie antywirusowym”.
Odpowiedziałem, iż strona Vectry wykonuje kod CSS zawarty w linku, i poprosiłem o eskalację tej sprawy do „odpowiedniego działu”, tłumacząc, iż nie byłem w stanie znaleźć dedykowanego kontaktu do działu bezpieczeństwa. Do kolejnej wiadomości załączyłem zrzut ekranu w formacie PNG, który udowadniał podatność:
Zdjęcie z podatności „reflected XSS” przedstawiające ogrom portretów Donalda Tuska rozmieszczonych po całej stronie Vectry.Mail z odpowiedzią przyszedł do mnie jeszcze tego samego dnia. Konsultant nie był w stanie otworzyć obrazka w formacie PNG, więc poprosił mnie o przesłanie zdjęcia w formacie JPG, JPEG albo PNG. Zwróciłem mu uwagę, iż zdjęcie, które wysłałem, jest już w jednym z żądanych formatów.
Fragment konwersacji z konsultantem Vectry
image.png – czyli dowód występowania podatnościW końcu zostałem poproszony o podanie adresu świadczenia usług przez Vectrę oraz numeru klienta Vectry. Podkreślmy: wszystko po to, żeby zgłosić błąd bezpieczeństwa. Uważam, iż Vectra nie potrzebuje ani jednego, ani drugiego, biorąc pod uwagę, iż już na etapie strony z ofertą całą witrynę można było zobaczyć pokrytą portretami Tuska. Albo kogokolwiek lub czegokolwiek innego, gdyby w linku znalazło się łącze do innej grafiki.
Napisałem do CERT-u. Tam zgłoszenie przyjęto i niecały miesiąc później otrzymałem potwierdzenie – „podatność wyeliminowana”.
Ta sytuacja stanowi dla mnie lekcję – o ile coś jest potencjalnie nie tak z bezpieczeństwem na stronie jakiegoś popularnego podmiotu, to lepiej od razu załatwiać sprawę przez CERT.
Tak też zrobiłem w przypadku Discorda w 2023 roku, gdy zgłosiłem, iż załączniki przesyłane przez ten komunikator nie są w żaden sposób zabezpieczane – tzn. dostęp do wszystkich przesyłanych załączników miał każdy, kto dysponował odpowiednim adresem URL, nieważne kto był docelowym adresatem.
Ponadto informacje o lokalizacji wykonania zdjęcia, gdy takowe istniały, nie były automatycznie usuwane. Po tym, jak CERT skontaktował się z Discordem, błędy te zostały naprawione.
Zapytałem się Vectry o komentarz w sprawie naprawionej już podatności XSS oraz sposobu załatwienia tej sprawy przez konsultantów. Czekam na odpowiedź z ich strony. Gdy tylko ją otrzymam, zamieszczę ją.
Korekta: Łukasz Szczęsny
Źródła
Zdjęcie tytułowe zostało zrobione na podstawie dwóch zrzutów ekranu z prywatnego archiwum autora.



