Zero-Day
8 min czytania
17 marca 2026

Kiedy int staje się złośliwym skryptem. Reflected XSS w CVAT (CVE-2024-47064)

Kiedy int staje się złośliwym skryptem. Reflected XSS w CVAT (CVE-2024-47064)

Czasami programiści zapominają, że jeśli coś wygląda jak liczba i powinno być liczbą, nie zawsze nią będzie, gdy trafi w ręce pentestera. Podczas kolejnych testów penetracyjnych potężnego narzędzia do adnotacji danych. Computer Vision Annotation Tool (CVAT), natrafiłem na klasyczny, ale bardzo niebezpieczny błąd typu Reflected Cross-Site Scripting (XSS).

Znaleziony przeze mnie błąd dorobił się oficjalnego numerka CVE-2024-47064 oraz biuletynu bezpieczeństwa na GitHubie (GHSA-hp6c-f34j-qjj7). Podatność została sklasyfikowana jako High ze scoringiem 8.1 (wektor: CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:N). Zobaczmy, jak brak rygorystycznej walidacji typów danych wejściowych i odpowiedniego kodowania na wyjściu pozwolił na wstrzyknięcie złośliwego kodu JavaScript bezpośrednio do przeglądarki ofiary.

TL;DR - Najważniejsze wnioski

  • Co poszło nie tak? (Endpointy i założenia)
  • Proof of Concept (Weryfikacja Koncepcji)
  • Jaki to ma wpływ na bezpieczeństwo?
  • Jak to naprawić? (Remediacja)

Co poszło nie tak? (Endpointy i założenia)

Aplikacja CVAT (podatne wersje to m.in. Server: 2.16.3, Core: 15.1.1, Canvas: 2.20.8, UI: 1.64.51) posiada endpointy API służące do zarządzania żądaniami (Requests). W moich testach wziąłem pod lupę dwa konkretne adresy:

Standardowe zapytanie wykorzystuje w miejscu <ID> identyfikator numeryczny (typu int). Jeśli spróbujemy odpytać serwer o nieistniejące zapytanie (np. ID 2137), serwer grzecznie zwróci błąd w formacie HTML:

  • /api/requests/<ID> (metody GET i POST)
  • /api/requests/<ID>/cancel (metoda POST)
"There is no request with specified id: 2137"
GET/api/requests/2137
Odpowiedz serwera

"There is no request with specified id: 2137"

Nieszkodliwe: int w odpowiedzi
GET/api/requests/<script>alert(1)</script>
Odpowiedz serwera

"There is no request with specified id: <script>alert(1)</script>"

Reflected XSS: kod odbity bez kodowania!

Proof of Concept (Weryfikacja Koncepcji)

Wydaje się nieszkodliwe, prawda? A co, jeśli zamiast liczby wpiszemy tam dowolny ciąg znaków (string)? Okazuje się, że aplikacja przyjmuje go bez zająknięcia i odbija (reflect) bezpośrednio w odpowiedzi, nie filtrując znaków specjalnych HTML!

Wykorzystując fakt, że nasz ciąg znaków jest odzwierciedlany na stronie, możemy pokusić się o wstrzyknięcie kodu HTML/JavaScript. Zamiast liczby, w ścieżce URL umieszczamy złośliwy payload (odpowiednio zakodowany URL-encoded, aby serwer poprawnie go zinterpretował):

GET /api/requests/%3Cimg%20src=x%20onerror=print()%3E HTTP/1.1 Host: app.cvat.ai

Zdekodowana wartość to po prostu: <img src=x onerror=print()>. Co się dzieje po stronie przeglądarki?

Przeglądarka próbuje wyrenderować obrazek ze źródła x. Ponieważ taki obrazek nie istnieje, uruchamia się zdarzenie onerror, które posłusznie wykonuje funkcję print(), wywołując na ekranie ofiary systemowe okno drukowania.

To samo osiągnąłem na endpoincie /cancel, używając payloadu wywołującego klasycznego alert-boxa na zdarzenie najechania myszką:

Reflected XSS, dlaczego to działa?

Serwer nie koduje danych wyjściowych. Cokolwiek umieścimy w URL jako parametr ID, zostanie wklejone bezpośrednio do kodu HTML odpowiedzi. Przeglądarka traktuje to jako poprawny HTML i posłusznie wykonuje osadzony skrypt.

Atakujacy
Phishing link
Ofiara klika
JS wykonany!
Endpoint #1: /api/requests/<ID>
GET /api/requests/%3Cimg%20src=x%20onerror=print()%3E

Dekodowany: <img src=x onerror=print()>

Efekt: przegladarka wykonuje print() - okno drukowania

Endpoint #2: /api/requests/<ID>/cancel
POST /api/requests/<IMG SRC=x onmouseover="alert('xss')">/cancel

Zdarzenie: onmouseover

Efekt: alert('xss') po najechaniu myszka

Cross-Site Scripting - wizualizacja ataku XSS
Reflected XSS, złośliwy payload zostaje odzwierciedlony w odpowiedzi serwera i wykonany w przeglądarce ofiary.

Jaki to ma wpływ na bezpieczeństwo?

Choć jest to XSS typu Reflected (wymaga interakcji użytkownika, parametru UI:R w wektorze CVSS, np. kliknięcia w spreparowany link przesłany w mailu phishingowym lub komunikatorze), jego konsekwencje są poważne. Z tego też powodu wektor wskazuje na wysoką poufność (C:H) oraz integralność (I:H).

Gdy uwierzytelniony użytkownik (np. administrator projektu) kliknie w taki link, złośliwy skrypt uruchomi się w kontekście jego zaufanej sesji z CVAT. Atakujący może w ten sposób:

  • Przejąć tokeny sesyjne lub ciasteczka, pełna kompromitacja konta.
  • Wykonywać akcje z uprawnieniami ofiary (np. modyfikować adnotacje, dodawać złośliwe konta, usuwać projekty).
  • Przekierować ofiarę na strony wyłudzające dane (phishing).

CVSS 8.1, High

Mimo wymogu interakcji użytkownika, brak wymaganych uprawnień (PR:N) i wysoki wpływ na poufność oraz integralność sprawiają, że ta podatność otrzymała ocenę 8.1 (High). Link phishingowy to jedyne, czego potrzebuje atakujący.

CVE-2024-47064
8.1High
Vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:N
Exploitability Metrics
Attack Vector (AV)
Network (N)Adjacent (A)Local (L)Physical (P)
Attack Complexity (AC)
Low (L)High (H)
Privileges Required (PR)
None (N)Low (L)High (H)
User Interaction (UI)
None (N)Required (R)
Scope (S)
Unchanged (U)Changed (C)
Impact Metrics
Confidentiality Impact (C)
None (N)Low (L)High (H)
Integrity Impact (I)
None (N)Low (L)High (H)
Availability Impact (A)
None (N)Low (L)High (H)

Jak to naprawić? (Remediacja)

Ten błąd przypomina, jak ważne są dwie warstwy obrony przed XSS-em:

  • Rygorystyczna walidacja danych wejściowych (Input Validation): Serwer powinien na samym początku sprawdzić, czy przekazany parametr <ID> rzeczywiście jest liczbą całkowitą. Jeśli nie jest, żądanie powinno zostać natychmiast odrzucone (zwracając np. błąd 400 Bad Request), bez procesowania jego treści. Zawsze lepiej stosować białe listy (whitelisting) dozwolonych typów danych.
  • Kodowanie danych wyjściowych (Context-Aware Output Encoding): To najważniejsza linia obrony. Wszelkie dane wprowadzane przez użytkownika, przed ich wyświetleniem w odpowiedzi HTTP (kontekst HTML), muszą zostać odpowiednio zakodowane. Znaki kontrolne HTML muszą zostać zamienione na odpowiednie encje: <&lt;, >&gt;.

Złota zasada dewelopera

Kiedy wysyłasz do przeglądarki użytkownika tekst, który zawierał fragmenty jego własnych zapytań (np. komunikaty błądów, wyniki wyszukiwania), ZAWSZE koduj wyjście. Przeglądarka to ufna bestia, wykona każdy kod, który serwer uzna za poprawny HTML.

Podatne
Brak walidacji wejscia
ID = <script>alert(1)</script>
Przyjete jako poprawne
Brak kodowania wyjscia
Response: "...id: <script>alert(1)</script>"
Przegladarka wykonuje skrypt!
Bezpieczne
Walidacja wejscia (Whitelisting)
ID = <script>...</script>
400 Bad Request: to nie int!
Kodowanie wyjscia (HTML Entities)
Response: "...id: &lt;script&gt;...&lt;/script&gt;"
Wyswietlony jako tekst, nie kod!
Bezpieczeństwo przeglądarki - ochrona przed XSS
Walidacja wejścia i kodowanie wyjścia, dwie kluczowe warstwy obrony przed atakami XSS.

Podsumowanie

CVE-2024-47064 to klasyczny przykład podatności Reflected XSS, w której brak walidacji typu danych wejściowych i kodowania wyjściowego pozwolił na wstrzyknięcie złośliwego kodu JavaScript do przeglądarki ofiary. Podatność w narzędziu CVAT otrzymała ocenę CVSS 8.1 (High) ze względu na brak wymaganych uprawnień i wysoki wpływ na poufność oraz integralność. Została odpowiedzialnie zgłoszona i załatana, ale pozostaje doskonałą lekcją: nigdy nie ufaj danym od użytkownika i zawsze koduj wyjście.

Bibliografia

1
CVE-2024-47064 - NIST National Vulnerability Database

Oficjalny wpis w bazie NIST NVD opisujący podatność Reflected XSS w CVAT z oceną CVSS 8.1.

2
GHSA-hp6c-f34j-qjj7 - GitHub Security Advisory

Biuletyn bezpieczeństwa opublikowany na GitHubie przez zespół CVAT, zawierający szczegóły podatności XSS i informacje o poprawce.

3
OWASP - Cross Site Scripting (XSS)

Kompendium wiedzy OWASP na temat ataków Cross-Site Scripting, typy, wektory, mechanizmy obrony i przykłady.

4
OWASP Top 10:2021 - A03 Injection

Kategoria OWASP Top 10 obejmująca ataki iniekcyjne, w tym Cross-Site Scripting (XSS), jako jedno z najczęstszych zagrożeń bezpieczeństwa aplikacji webowych.

5
CVAT - Computer Vision Annotation Tool (GitHub)

Repozytorium open-source narzędzia CVAT do adnotacji danych w projektach uczenia maszynowego i Computer Vision.

Czy Twoja aplikacja odbija to, czego nie powinna?

Reflected XSS to jedna z najczęstszych podatności webowych. Nasi pentesterzy testują każdy parametr wejściowy, każdy endpoint i każdy wektor wstrzyknięcia. Nie czekaj, aż ktoś inny znajdzie XSS-a w Twojej aplikacji.

Zamów test penetracyjny