Canvas fingerprinting poza podstawami: dlaczego dwa identyczne Chrome renderują różne piksele
Dwa urządzenia z tym samym Chrome, systemem i GPU wciąż renderują różne piksele canvas. Dlaczego potok renderowania jest niedeterministyczny, dlaczego wstrzykiwanie szumu zawodzi i gdzie canvas mieści się w nowoczesnym stosie detekcji.
Canvas fingerprinting jest wykorzystywany w produkcji od 2012 roku. Idea jest prosta: poprosić przeglądarkę o wyrenderowanie treści 2D, odczytać piksele i policzyć z nich hash. Różne urządzenia produkują dla tych samych instrukcji nieco inne piksele, a te różnice są na tyle stabilne, że pozwalają rozpoznać urządzenie między sesjami.
To akurat jest dobrze znane. Mniej rozumiane jest, dlaczego ta technika działa — dlaczego identyczne konfiguracje oprogramowania na identycznym sprzęcie wciąż produkują różne wyjścia pikselowe. Odpowiedź leży na styku sterowników GPU, renderowania fontów i arytmetyki zmiennoprzecinkowej.
Potok renderowania nie jest deterministyczny
Gdy JavaScript wywołuje context.fillText("Cwm fjord bank glyphs vext quiz", 4, 45), Chrome nie renderuje pikseli samodzielnie. Generuje instrukcje dla Skia — biblioteki grafiki 2D — która z kolei wydaje polecenia rysowania do backendu przyspieszanego przez GPU (zazwyczaj ANGLE na Windows, Metal na macOS lub programowego fallbacku w kontenerach).
Na każdym kroku kumulują się drobne różnice implementacyjne:
-
Podsystem fontów w Skia wybiera rodzinę czcionek. Jeśli Arial nie jest zainstalowany, następuje fallback — a fallback zależy od czcionek zainstalowanych w systemie.
-
Wybrany font jest renderowany w żądanym rozmiarze za pomocą FreeType (na Linuksie), DirectWrite (na Windows) lub Core Text (na macOS). Każda z tych bibliotek ma inne algorytmy hintingu.
-
Stosowane jest pozycjonowanie subpikselowe. To właśnie tutaj identyczne fonty zaczynają produkować różne piksele — algorytm zaokrągla pozycje do ułamkowych przesunięć pikselowych, a reguły zaokrąglania różnią się między platformami.
-
Zrasteryzowany tekst jest komponowany na canvas. Na systemach z akceleracją sprzętową blending wykonują shadery GPU, a w trybie fallback — kod CPU.
Każdy z tych kroków może wprowadzić różnice o jedną lub dwie wartości pikselowe. Pojedynczo niewidoczne. Zbiorczo unikalne.
Wersje sterowników GPU dominują w fingerprincie
Dwie maszyny z Windows 11 i układami Intel UHD Graphics 620 mogą produkować różne wyjścia canvas, jeśli różnią się ich sterowniki GPU. Intel wypuszcza aktualizacje sterowników kilka razy w roku, a każda z nich może zmienić filtrowanie subpikselowe, korekcję gamma i antyaliasing tekstu.
Oznacza to, że stabilność fingerprintu canvas jest ograniczona częstotliwością aktualizacji sterowników. Użytkownik, który zaktualizuje sterownik karty graficznej — często po cichu, przez Windows Update — zobaczy zmianę swojego fingerprintu canvas.
Systemy detekcji radzą sobie z tym, traktując fingerprint canvas jako jeden z wielu sygnałów, a nie samodzielny identyfikator. Gdy się zmienia, ale inne sygnały pozostają stabilne (fingerprint TLS, renderer WebGL, strefa czasowa, zainstalowane czcionki), odwiedzający wciąż jest rozpoznawany.
Renderowanie emoji to żyła złota
Najbardziej identyfikującym elementem fingerprintu canvas jest często nie tekst czy kształty, lecz emoji. Renderowanie emoji zależy od czcionki emoji dostarczanej z systemem — Segoe UI Emoji na Windows, Apple Color Emoji na macOS, Noto Color Emoji na Androidzie.
Nawet w obrębie jednego systemu renderowanie emoji zmienia się między wersjami. Renderowanie emoji tęczy w Windows 10 różni się od tego w Windows 11. Uśmiechnięta twarz w iOS 16 ma inny antyaliasing niż w iOS 17.
Nowoczesne skrypty canvas fingerprinting renderują specjalnie sekwencje emoji, w tym nowe dodatki do Unicode. Odwiedzający twierdzący, że korzysta z Safari na iPhonie, który nie potrafi wyrenderować emoji dodanego w iOS 17, korzysta ze starszego iOS — albo kłamie na temat platformy.
Frameworki automatyzacji produkują charakterystyczne fingerprinty
Headless Chrome, działający w kontenerze Docker bez GPU, używa do renderowania SwiftShadera. SwiftShader produkuje wyjścia canvas, które są wewnętrznie spójne, ale odmienne od jakiegokolwiek Chrome z akceleracją sprzętową.
Sygnatura jest rozpoznawalna: nietypowo czysty antyaliasing, specyficzne wartości kolorów w obszarach gradientu i krawędzie tekstu niepasujące do żadnego znanego sterownika GPU. Fingerprint canvas zgodny ze SwiftShaderem w Chrome 124 w kontenerze Linux to niemal na pewno automatyzacja — żaden prawdziwy użytkownik nie uruchamia przeglądarki w ten sposób.
Puppeteer-extra-stealth próbuje podrobić wyjście canvas, przechwytując toDataURL() i zwracając zmodyfikowane dane. Ale modyfikacja często wprowadza własne artefakty — wzorce szumu powtarzające się między sesjami, które paradoksalnie czynią próbę obrony przed fingerprintingiem bardziej wykrywalną niż bezczynność.
Dlaczego wstrzykiwanie szumu nie działa dobrze
Przeglądarki nastawione na prywatność, takie jak Brave, wstrzykują szum do wyjścia canvas, aby zapobiec śledzeniu. Idea polega na dodawaniu małych losowych wariacji do wartości pikseli, tak aby to samo urządzenie produkowało inny fingerprint w każdej sesji.
W praktyce wstrzykiwanie szumu ma trzy problemy:
1. Sam szum jest fingerprintem. Odwiedzający, którego wyjście canvas zmienia się przy każdym załadowaniu, ale którego inne sygnały pozostają identyczne, jest rozpoznawalny jako przeglądarka wstrzykująca szum. To samo w sobie jest identyfikujące.
2. Algorytm szumu jest stabilny. Implementacja Brave produkuje specyficzne wzorce szumu, które nie odpowiadają naturalnej wariancji renderowania GPU. Systemy detekcji potrafią odróżnić wyjścia canvas wyglądające na wstrzyknięte szumem od tych wyglądających naturalnie.
3. Zaawansowane systemy łączą próbki. Wiele renderowań na tej samej stronie lub w różnych sesjach można uśrednić. Jeśli szum jest mały, średnia zbiega do leżącego u podstaw deterministycznego fingerprintu.
Co przechwytuje canvas fingerprinting
Poza oczywistym wyjściem wizualnym canvas fingerprinting może wydobyć jako efekt uboczny kilka atrybutów urządzenia:
Czas renderowania — to, jak długo canvas się renderuje, ujawnia wydajność GPU. Desktop 4K z dedykowanym GPU renderuje szybciej niż laptop klasy średniej.
Metryki tekstu — measureText() zwraca dokładne szerokości pikselowe, które różnią się w zależności od renderowania fontów. Szerokości tekstu można użyć jako fingerprintu nawet bez renderowania.
Wsparcie operacji composite — niektóre przeglądarki lub konfiguracje GPU wspierają rozszerzone tryby composite. Testowanie wsparcia ujawnia granice możliwości.
Efekty filtrów — filtry w stylu CSS zastosowane do canvas produkują różne wyjścia na różnych GPU, zwłaszcza filtry blur i drop-shadow.
Gdzie canvas fingerprinting mieści się w stosie detekcji
Samodzielnie canvas fingerprinting nie jest solidnym identyfikatorem. Sterowniki się zmieniają. Użytkownicy zmieniają przeglądarki. Wstrzykiwanie szumu jest powszechne wśród odbiorców dbających o prywatność.
Jego prawdziwą siłą jest rola weryfikacji krzyżowej. Gdy sesja twierdzi, że należy do powracającego użytkownika na podstawie ciasteczek lub logowania do konta, fingerprint canvas działa jako drugi sygnał — zgodność z historycznym fingerprintem potwierdza to twierdzenie, niezgodność sygnalizuje przejęcie konta lub porwanie sesji.
W detekcji botów canvas fingerprinting doskonale sprawdza się w wychwytywaniu automatyzacji w kontenerach. Prawdziwi użytkownicy mają prawdziwe GPU. Prawdziwe GPU produkują rozpoznawalne sygnatury renderowania. Wszystko, co renderuje jak SwiftShader lub jak źle podrobiony canvas, ląduje w koszyku „niemal na pewno bot”.
Technika z 2012 roku wciąż działa w 2026 roku z tego samego powodu: renderowanie jest deterministyczne w obrębie środowiska, ale niemal niemożliwe do pełnego podrobienia. Każda próba ukrycia się zostawia ślady samej próby.