Twoja przeglądarka zdradza system ostatnimi bitami wyniku. Jak działa fingerprinting bez cookies

Wpisujesz w przeglądarce Math.tanh(0.8). Dostajesz liczbę. Zwykły wynik funkcji matematycznej, którego nikt przy zdrowych zmysłach nie uznałby za informację o swoim komputerze.

A jednak jej ostatnie cyfry mogą zdradzić system operacyjny, na którym działa Chromium.

Nie imię, nie numer seryjny procesora i nie dokładny model laptopa. Coś subtelniejszego, a w praktyce bardzo użytecznego: odpowiedź na pytanie, czy historia opowiadana przez przeglądarkę trzyma się kupy. Jeśli User-Agent mówi „macOS”, ale matematyka, fonty, WebGL i warstwa sieciowa zachowują się jak Linux uruchomiony w kontenerze, powstaje całkiem dobry powód, żeby przyjrzeć się tej sesji dokładniej.

Na co dzień używam automatycznych przeglądarek do testów, audytów i zbierania danych. Playwright jest jednym z moich podstawowych narzędzi. Im głębiej wchodzę w to, jak serwisy próbują odróżnić prawdziwego użytkownika od automatu, tym mniej sensowna wydaje mi się popularna opowieść: „wyczyściłem cookies, mam adblocka, więc nikt nie wie, że to ja”.

Punktem wyjścia były dla mnie dwie świetne dyskusje na Hacker News: jedna o wykrywaniu systemu przez różnice w funkcjach matematycznych, druga o tym, ile naprawdę mówi fingerprint przeglądarki. Same artykuły są ciekawe, ale dopiero komentarze odsłaniają właściwy spór: unikalny wynik nie musi być trwały, przypadkowe fałszowanie cech może zaszkodzić, a ochrona przed botami i śledzenie ludzi korzystają czasem z tych samych danych.

Adblock ma sens. Tryb prywatny ma sens. VPN ma sens. Żaden z nich nie jest jednak przyciskiem „stań się niewidzialny”.

Test wykonywany lokalnie

Co wiemy o Tobie — a dokładniej co mówi wynik Twojej przeglądarki

Trwa obliczanie
Math.tanh(0.8) uruchom JavaScript, aby wykonać test

Poniżej nadal znajdziesz wyniki referencyjne. Automatyczne porównanie wymaga JavaScriptu.

Przeglądarka
do odczytania lokalnie
Deklarowana platforma
do odczytania lokalnie
Co naprawdę wiemy
sam wynik nie identyfikuje urządzenia

Test działa wyłącznie w tej karcie. Wyniku nie zapisujemy ani nie wysyłamy.

Ostatnie bity wyniku

Punktem wyjścia do tego tekstu był opis zmiany w silniku V8. Chromium przestało korzystać z własnej implementacji części funkcji matematycznych i zaczęło wywoływać funkcje dostarczane przez bibliotekę systemową. Można to zobaczyć w konkretnym commicie V8.

Różne systemy mogą liczyć ten sam wynik odrobinę inaczej. Nie na poziomie istotnym dla człowieka. Na poziomie ostatnich bitów liczby zmiennoprzecinkowej — jak najbardziej.

Uruchomiłem punktowy test na macOS w systemowym Chrome 150 sterowanym przez Playwrighta. Math.tanh(0.8) zwróciło 0.664036770267849, czyli wartość przypisaną macOS w analizie Scrapfly. To nie dowodzi, że jedna funkcja niezawodnie rozpoznaje każdy system i każdą wersję Chrome. Potwierdza coś ciekawszego: kod strony może zaglądać w miejsca, których użytkownik w ogóle nie kojarzy z informacją o swoim urządzeniu.

Źródłowy test na trzech rzeczywistych maszynach pokazuje też, dlaczego detektor musi dobrać odpowiednie wejście. Dla 0.5 wszystkie systemy zwracają identyczny wynik. Przy 0.7 odstaje Linux, przy 0.9 Windows, a 0.8 rozdziela wszystkie trzy:

Wywołanie Linux — glibc macOS — libsystem_m Windows — UCRT Twoja przeglądarka
Math.tanh(0.5)pełna zgodność referencji
Porównywanie…
0.46211715726000974 0.46211715726000974 0.46211715726000974 wymaga JavaScriptu
Math.tanh(0.7)Linux odstaje o 1 ULP
Porównywanie…
0.6043677771171636 0.6043677771171635 0.6043677771171635 wymaga JavaScriptu
Math.tanh(0.8)trzy różne wyniki
Porównywanie…
0.6640367702678491 0.664036770267849 0.6640367702678489 wymaga JavaScriptu
Math.tanh(0.9)Windows odstaje o 1 ULP
Porównywanie…
0.7162978701990245 0.7162978701990245 0.7162978701990244 wymaga JavaScriptu

Żółte podświetlenie pokazuje końcówkę, w której zaczynają się różnice. Kolumna „Twoja przeglądarka” jest obliczana lokalnie i nie jest nigdzie wysyłana.

Żółte podświetlenie zaczyna się w miejscu, w którym kończy się wspólny zapis dziesiętny. ULP — unit in the last place — oznacza najmniejszą różnicę, jaką w tym miejscu może zapisać liczba typu double. JavaScript pokazuje najkrótszy zapis dziesiętny pozwalający odtworzyć tę samą wartość binarną, dlatego wynik macOS dla 0.8 ma o jedną widoczną cyfrę mniej. Pomiary wykonał Scrapfly przez DevTools Protocol na Chrome 150: Linuxie z glibc, macOS 26 na Apple Silicon oraz Windows 11 z UCRT.

Sam wynik tanh nie jest unikalnym identyfikatorem. Jest testem spójności. Detektor może zestawić go z danymi z kilkunastu innych warstw i zapytać: czy wszystkie te cechy mogły powstać w jednym prawdziwym środowisku?

Bot, fałszywa przeglądarka i powracający użytkownik to trzy różne problemy

W dyskusjach o fingerprintingu regularnie miesza się trzy pytania:

  1. Czy ta sesja jest sterowana automatycznie?
  2. Czy deklarowana przeglądarka, system i urządzenie tworzą wiarygodną całość?
  3. Czy to ten sam klient, którego widzieliśmy wczoraj?

To nie są synonimy.

Zwykły użytkownik może mieć bardzo charakterystyczny fingerprint, ale nie być botem. Automat może używać prawdziwego profilu Chrome i wyglądać całkiem zwyczajnie. Nietypowa konfiguracja może należeć do osoby korzystającej z technologii wspomagającej, korporacyjnego proxy albo restrykcyjnych ustawień prywatności.

Dlatego sensowne systemy nie powinny wydawać wyroku na podstawie jednego pola. Składają ocenę z wielu sygnałów. Cloudflare opisuje wprost połączenie heurystyk, testów JavaScript, modeli uczących się i danych o sesji w swojej dokumentacji mechanizmów bot detection.

Najlepsze detektory nie pytają więc: „czy navigator.webdriver ma wartość true?”. Pytają: „czy setki sygnałów opowiadają tę samą historię?”.

Schemat sześciu warstw wykrywania automatycznej przeglądarki: zachowanie, JavaScript, runtime automatyzacji, rendering, protokół żądania oraz sieć i reputacja, łączonych w ocenę ryzyka
Detektor składa ocenę z wielu warstw. Pojedynczy sygnał może być niewinny; znaczenia nabierają zgodność cech, historia sesji i ich korelacja.

Co wysyłasz, zanim strona uruchomi JavaScript

Fingerprinting kojarzy się zwykle ze skryptem rysującym coś na niewidocznym canvasie. Tymczasem serwer dostaje pierwszą porcję informacji, zanim przeglądarka wykona choćby jedną linijkę JavaScriptu.

Widzi między innymi:

  • adres IP, operatora i przybliżoną lokalizację;
  • nagłówki HTTP, ich wartości i kolejność;
  • User-Agent, Client Hints, język i preferowane formaty;
  • sposób zestawienia TLS;
  • parametry HTTP/2 albo HTTP/3;
  • charakterystykę połączenia i historię reputacji adresu.

Bez cookies i bez kliknięcia „zgadzam się”

Tyle strona wie o tej sesji już teraz

Odczyt lokalny
Sygnał Co widać Skąd
Adres IP i połączenie Serwer musiał je zobaczyć, aby odesłać tę stronę. Ten widget celowo nie pobiera ani nie wyświetla Twojego IP. żądanie HTTP
User-Agent wymaga JavaScriptu HTTP + JavaScript
Platforma wymaga JavaScriptu Client Hints + JavaScript
Języki wymaga JavaScriptu HTTP + JavaScript
Strefa czasowa wymaga JavaScriptu JavaScript
Ekran wymaga JavaScriptu JavaScript
Okno strony wymaga JavaScriptu JavaScript
CPU i pamięć wymaga JavaScriptu JavaScript
Obsługa dotyku wymaga JavaScriptu JavaScript
Sygnały prywatności wymaga JavaScriptu JavaScript
Skąd tu przyszedłeś wymaga JavaScriptu HTTP + JavaScript

Adblock nadal pomaga, bo może zatrzymać zewnętrzny tracker. Nie odbiera jednak kodowi first-party uruchomionemu razem ze stroną dostępu do tych API. Żaden z powyższych odczytów nie wymaga zapisania cookie.

Widget nie wykonuje dodatkowych żądań, nie zapisuje wyniku i nie wysyła dynamicznych odczytów do Critical.pl.

Samo Accept-Language potrafi być zaskakująco szczegółowe. W jednej z dyskusji na Hacker News użytkownik zauważył, że wybieranie w Chrome opcji „nigdy nie tłumacz tego języka” zbudowało mu nietypową, uporządkowaną listę języków wysyłaną do odwiedzanych stron. Google przygotowało nawet propozycję ograniczenia informacji w tym nagłówku, właśnie ze względu na pasywny fingerprinting.

Jeszcze ciekawiej robi się na poziomie TLS i HTTP/2. Przeglądarka, Python, biblioteka Go i reverse proxy mogą inaczej układać rozszerzenia TLS, cipher suites, ustawienia połączenia i pseudo-nagłówki. Dlatego automat może deklarować w JavaScripcie, że jest najnowszym Chrome na Windowsie, a warstwa sieciowa nadal wyglądać jak klient HTTP uruchomiony z serwera.

Zmiana samego User-Agenta jest jak założenie cudzej koszulki bez zmiany głosu, chodu i dokumentów.

Co strona może policzyć w twojej karcie

Po uruchomieniu JavaScriptu powierzchnia robi się znacznie większa.

Przeglądarka, ekran i sprzęt

Strona może poznać język, strefę czasową, rozmiar ekranu i viewportu, skalowanie, głębię kolorów, liczbę logicznych rdzeni procesora, przybliżoną pamięć urządzenia, obsługiwane API, touch, preferencje kontrastu czy ograniczenie animacji.

Żadna z tych informacji nie musi być szczególnie rzadka. Problemem jest ich kombinacja.

Canvas, WebGL i audio

Canvas pozwala narysować ustalony tekst oraz kształty, odczytać piksele i porównać wynik. Różnice biorą się z fontów, rasteryzacji, systemu, GPU i sterownika. WebGL dodaje informacje o rendererze, limitach i sposobie wykonywania shaderów. Web Audio może wygenerować dźwięk w pamięci — bez odtwarzania go w głośnikach — a następnie porównać próbki.

To nie znaczy, że jeden hash canvasu zna numer seryjny karty graficznej. Zazwyczaj rozpoznaje klasę konfiguracji. W połączeniu z pozostałymi cechami może jednak istotnie zawęzić zbiór podobnych klientów.

Fonty i zachowanie implementacji

Lista dostępnych fontów zdradza więcej, niż mogłoby się wydawać: system, język, czasem zawód albo zainstalowane oprogramowanie. Do tego dochodzą różnice w CSS, obsłudze błędów, precyzji layoutu, kodekach, WebAssembly i funkcjach matematycznych takich jak tanh.

Detektor nie potrzebuje magicznej właściwości o ogromnej unikalności. Może budować profil z wielu nudnych, słabych sygnałów.

Po czym widać Playwrighta, Puppeteera i Selenium

Najprostszy test jest częścią standardu. W3C definiuje navigator.webdriver jako informację, że przeglądarka jest sterowana przez WebDriver.

To użyteczne wobec zwykłej, nieukrywanej automatyzacji. Jest też banalne do nadpisania, więc brak tej flagi niczego nie dowodzi.

Kolejne warstwy to między innymi:

  • pozostałości po ChromeDriverze i skryptach inicjalizujących;
  • nietypowe deskryptory właściwości oraz prototypy;
  • różnice widoczne w iframe’ach i workerach, których nie objęła łatka;
  • ślady komunikacji przez Chrome DevTools Protocol;
  • renderer programowy, brak typowych fontów albo urządzeń multimedialnych;
  • rozdzielczości i konfiguracje charakterystyczne dla maszyn wirtualnych;
  • timing, regularność event loop i zachowanie pod obciążeniem;
  • syntetyczne ruchy myszy, scroll, rytm wpisywania i kolejność zdarzeń;
  • nieludzkie tempo oraz powtarzalność całej sesji.

Playwright i Puppeteer sterują Chromium przez Chrome DevTools Protocol. CDP jest świetnym interfejsem do debugowania i automatyzacji, ale nie powstało po to, żeby być niewidoczne. Niektóre testy wykorzystują efekty uboczne serializacji obiektów, stack traces i subskrybowania zdarzeń runtime.

To nadal nie jest dowód. Człowiek może mieć otwarte DevTools. Narzędzie dostępnościowe może sterować stroną. Monitoring syntetyczny z definicji zachowuje się jak automat. CDP powinno być cechą modelu, nie wyrokiem.

Stealth nie usuwa problemu. Przesuwa go o warstwę niżej

Historia narzędzi „stealth” wygląda jak klasyczny wyścig zbrojeń:

  1. Detektor sprawdza navigator.webdriver.
  2. Automat ukrywa flagę.
  3. Detektor sprawdza deskryptor, prototyp albo nowy iframe.
  4. Automat poprawia przeglądarkę na niższym poziomie.
  5. Detektor porównuje TLS, HTTP/2, grafikę, timing i zachowanie.
  6. Automat korzysta z prawdziwego profilu, residential proxy i nagranych interakcji.
  7. Obrona koreluje wiele kont, historię sesji i wzorce nadużyć.

Nie istnieje jedna „undetectable browser”. Istnieje koszt utrzymania wiarygodnej persony oraz koszt pomyłki po obu stronach.

Co gorsza, prymitywne fałszowanie może zwiększyć wykrywalność. Losowy szum nie zawsze pomaga. Jeśli canvas zmienia się przy każdym odczycie albo przeglądarka podaje kombinację cech, która nie występuje na żadnym realnym urządzeniu, samo fałszerstwo staje się sygnałem.

Najgorsze jest to, że fingerprint nie musi być jednym hashem

Łatwo uspokoić się myślą: „mój fingerprint zmieni się po aktualizacji, więc nie da się mnie śledzić”.

Rzeczywiście, fingerprint się zmienia. Aktualizujesz system i przeglądarkę, instalujesz font, podłączasz monitor, podróżujesz do innej strefy czasowej. To ważne ograniczenie.

Tracker nie potrzebuje jednak wiecznego numeru seryjnego. Może utrzymywać graf hipotez:

  • profil A i A’ różnią się wyłącznie wersją Chrome;
  • oba pojawiają się z podobnego operatora i w tej samej strefie czasowej;
  • jeden zniknął dokładnie wtedy, gdy pojawił się drugi;
  • oba poruszają się po serwisie w podobny sposób;
  • oba w końcu logują się na to samo konto.

Badanie FP-STALKER pokazało, że zmieniające się fingerprinty można wiązać w czasie. To nadal model probabilistyczny, nie nieomylne rozpoznawanie człowieka. W wielu zastosowaniach „bardzo prawdopodobne” w zupełności jednak wystarcza.

Adblock, incognito i VPN: pomagają, ale nie czynią cię niewidzialnym

Adblock

Adblock realnie blokuje znane skrypty, endpointy i synchronizację identyfikatorów. Kod, który nie został pobrany, nie wykona fingerprintingu i nie wyśle jego wyniku. To duża korzyść.

Nie zablokuje jednak automatycznie kodu first-party, self-hosted albo nowego. Sama konfiguracja blokowania może też wpływać na DOM, timing i listę wykonanych żądań, stając się jednym z sygnałów. Wniosek nie brzmi „adblock nic nie daje”. Brzmi: adblock ogranicza ekspozycję, ale nie usuwa fingerprintu przeglądarki.

Tryb prywatny

Tryb prywatny przede wszystkim izoluje i usuwa stan: historię, cookies oraz część magazynów po zamknięciu sesji. Nie gwarantuje anonimowości wobec odwiedzanej strony. IP, TLS, konfiguracja przeglądarki i wiele cech urządzenia nadal są widoczne.

VPN

VPN ukrywa domowy adres IP przed stroną i może powiększyć grupę osób wychodzących przez jeden serwer. Nie zmienia automatycznie fontów, WebGL, języka, zachowania ani konta, na które się logujesz. Adres znanego VPN-u może też podnieść ocenę ryzyka w systemie antyfraudowym.

Każde z tych narzędzi rozwiązuje realny fragment problemu. Rozczarowanie zaczyna się dopiero wtedy, gdy oczekujemy od jednego z nich pełnej niewidzialności.

Ta sama technika może chronić konto albo śledzić reklamowo

Fingerprinting nie ma jednego zastosowania.

Bank może używać podobnych cech do wykrycia przejęcia konta. Sklep może walczyć z credential stuffingiem, masowym wykupywaniem limitowanego produktu albo fraudem płatniczym. Serwis może ograniczać scraping i automatyczne zakładanie kont.

Ta sama telemetria może jednak służyć do łączenia wizyt, obchodzenia blokowania cookies oraz budowania profilu reklamowego.

Technika nie rozstrzyga celu. Znaczenie mają zakres, podstawa, retencja, przejrzystość oraz to, czy użytkownik ma realny wybór. Problem pojawia się również po stronie obrony: restrykcyjne ustawienia prywatności, VPN, nietypowa przeglądarka albo technologia wspomagająca mogą wyglądać „podejrzanie”. Jeśli system blokuje na podstawie pojedynczej cechy, będzie karał również prawdziwych ludzi.

Sprawdź, co potrafi zobaczyć strona

Publiczne testy pozwalają obejrzeć tę powierzchnię z różnych stron:

  • EFF Cover Your Tracks pokazuje fingerprint i działanie ochron przed trackerami na tle populacji użytkowników testu;
  • AmIUnique zbiera szeroki zestaw atrybutów i bada zmianę fingerprintu w czasie;
  • BrowserLeaks rozdziela testy canvas, WebGL, audio, fontów, WebRTC, TLS i HTTP/2;
  • oryginalne demo CreepJS agresywnie sprawdza spójność wielu cech środowiska.

Wynik „unikalny” nie oznacza „jesteś jedyną taką osobą w Internecie”. Oznacza najwyżej, że w konkretnej, samodzielnie dobranej bazie testu nie znaleziono identycznego profilu. Każde z tych narzędzi ma też własną politykę zbierania danych — warto przeczytać ją przed uruchomieniem.

Dlatego dodałem do tego artykułu prosty test działający wyłącznie w przeglądarce. Bez wysyłania wyniku na serwer i bez udawania, że znamy globalną unikalność. Pokazuje nie „jesteś anonimowy w 37%”, lecz konkret: czy cztery wyniki matematyczne są stabilne i czy pasują do profili referencyjnych. Nie widzi warstwy sieciowej, historii ani pozostałych cech urządzenia, więc nie udaje pełnego fingerprintu.

Co faktycznie możesz zrobić

Nie ma jednego przełącznika „niewidzialny”. Możesz natomiast świadomie zmniejszać powierzchnię i utrudniać korelację:

  1. Blokuj znane trackery i third-party JavaScript. To nadal jedna z najskuteczniejszych warstw ochrony.
  2. Korzystaj z ochron wbudowanych w przeglądarkę. Tor Browser i Mullvad Browser stawiają na podobieństwo dużej grupy użytkowników. Brave stosuje kontrolowaną randomizację części wyników. Firefox i Safari ograniczają wybrane powierzchnie fingerprintingu.
  3. Nie dokładaj przypadkowych rozszerzeń spoofujących każdą właściwość osobno. Niespójna konfiguracja może stać się bardziej charakterystyczna niż domyślna.
  4. Rozdzielaj konteksty. Osobne profile lub przeglądarki ograniczają łączenie aktywności między rolami i kontami.
  5. Dobierz VPN albo Tor do rzeczywistego zagrożenia. Zmiana IP pomaga, ale nie zastępuje pozostałych warstw.
  6. Nie loguj się na konto, jeśli celem jest brak powiązania sesji z tożsamością. Najlepszy fingerprint nie jest potrzebny, gdy sam podajesz adres e-mail.

Najważniejsze: ochrona prywatności nie jest bezwartościowa tylko dlatego, że nie daje absolutnej anonimowości. Każdy zablokowany skrypt to jeden podmiot mniej, który może zebrać i połączyć dane.

Przeglądarka musi zdradzać szczegóły, żeby współczesny web działał

Problemem nie jest jedna zdradziecka właściwość JavaScriptu. Problemem jest suma szczegółów.

Przeglądarka musi wiedzieć, jak renderować fonty, używać GPU, odtwarzać audio, dopasować layout do ekranu, obsłużyć język, urządzenia wejścia i setki API. Każda różnica potrzebna do działania może zostać zamieniona w sygnał. Do tego dochodzi sieć, historia sesji i zachowanie człowieka.

Nie znaczy to, że każda strona zna twoje imię. Znaczy, że „nie mają mojego cookie” jest znacznie słabszym zdaniem, niż większość z nas chciałaby wierzyć.

FAQ

Czy fingerprint przeglądarki pozwala rozpoznać konkretną osobę?

Sam fingerprint częściej opisuje urządzenie, przeglądarkę albo prawdopodobnie powracającego klienta niż osobę z imienia i nazwiska. Może jednak zostać powiązany z tożsamością po zalogowaniu, zakupie, podaniu adresu e-mail albo zestawieniu z innymi danymi.

Czy adblock blokuje fingerprinting?

Blokuje wiele znanych skryptów i endpointów fingerprintingowych, więc realnie ogranicza śledzenie. Nie usuwa jednak cech przeglądarki i nie musi zatrzymać kodu first-party albo nowego trackera, którego nie ma jeszcze na liście filtrów.

Czy tryb incognito zmienia fingerprint przeglądarki?

Może zmienić część stanu i niektóre zachowania przeglądarki, ale jego głównym zadaniem jest izolowanie oraz usuwanie historii, cookies i danych sesji. Nie ukrywa automatycznie IP, TLS, ekranu, systemu ani wszystkich wyników canvas i WebGL.

Jak strony wykrywają Playwrighta i Selenium?

Łączą jawne sygnały WebDrivera z artefaktami JavaScriptu, CDP, grafiki, warstwy sieciowej, timingu i zachowania. Usunięcie navigator.webdriver omija tylko najprostszy test; wiarygodne środowisko musi pozostać spójne na wszystkich warstwach.

Czy VPN chroni przed fingerprintingiem?

VPN zmienia adres IP widziany przez stronę i utrudnia prostą korelację z domowym łączem. Nie zmienia automatycznie fingerprintu canvas, WebGL, fontów, języka, zachowania ani kont, na które się logujesz.

Gotowy na strategiczne partnerstwo w marketingu cyfrowym?

Porozmawiajmy o Twoich wyzwaniach i celach. Opracujemy dopasowaną strategię i plan działania, które przyniosą mierzalne rezultaty dla Twojego e-commerce lub instytucji.