Wykrywanie przeglądarek headless: Playwright, Puppeteer i więcej
Nasz silnik Bot Detection identyfikuje ponad 15 frameworków automatyzacji dzięki niespójnościom sygnałów, brakującym API i wzorcom zachowań, których boty nie potrafią podrobić.
Przeglądarki headless to broń pierwszego wyboru w zaawansowanym web scrapingu, credential stuffingu i operacjach oszukańczych. W przeciwieństwie do prostych klientów HTTP przeglądarki headless wykonują JavaScript, renderują strony i obsługują nowoczesne API webowe — co czyni je znacznie trudniejszymi do wykrycia. Nasz silnik Bot Detection wykorzystuje wiele niezależnych metod wykrywania, aby identyfikować ponad 15 frameworków automatyzacji przy niemal zerowej liczbie fałszywych trafień.
Ewolucja automatyzacji przeglądarek
Automatyzacja przeglądarek przeszła długą drogę od prostych skryptów curl. Nowoczesne narzędzia, takie jak Playwright, Puppeteer i Selenium WebDriver, sterują prawdziwymi silnikami przeglądarek — Chromium, Firefox lub WebKit — w trybie headless. Wykonują JavaScript, przetwarzają CSS, renderują elementy canvas i obsługują zapytania WebGL dokładnie tak, jak przeglądarki z interfejsem. Sprawia to, że są niewidoczne dla metod wykrywania, które sprawdzają jedynie zdolność do wykonywania JavaScriptu.
Najnowsza generacja narzędzi poszła jeszcze dalej. Tryb stealth w Playwright łata wiele sygnałów, na których opiera się tradycyjne wykrywanie botów. Puppeteer-extra-plugin-stealth modyfikuje właściwości navigatora, nadpisuje ciągi znaków identyfikujące dostawcę WebGL i podrabia zdarzenia interakcji użytkownika. Te środki przeciw wykrywaniu wywołały wyścig zbrojeń między operatorami botów a systemami detekcji.
Metoda wykrywania 1: analiza flagi WebDriver
Właściwość navigator.webdriver przyjmuje wartość true, gdy przeglądarka jest sterowana przez automatyzację. Wczesne wykrywanie sprowadzało się do zwykłego sprawdzenia tej właściwości. Nowoczesne narzędzia stealth jednak ją usuwają lub nadpisują. Nasze wykrywanie sięga głębiej — sprawdzamy nie tylko wartość właściwości, ale też jej deskryptor, obecność w łańcuchu prototypów oraz to, czy podejmowano próby jej przedefiniowania. Kontrolujemy również powiązane właściwości, takie jak anomalie w długości navigator.plugins, które towarzyszą nadpisaniu WebDrivera.
Metoda wykrywania 2: artefakty Chrome DevTools Protocol
Playwright i Puppeteer sterują przeglądarkami za pośrednictwem Chrome DevTools Protocol (CDP). Nawet gdy tryb stealth jest aktywny, CDP pozostawia artefakty w środowisku wykonawczym: określone zmienne globalne, zmodyfikowane funkcje getter oraz zmienione deskryptory właściwości obiektów Window i Navigator. Wykrywamy te artefakty technikami odpornymi na proste nadpisania.
Metoda wykrywania 3: fingerprinting przeglądarek headless
Chrome w trybie headless ma inny zestaw możliwości niż Chrome z interfejsem. Brakuje mu pewnych wtyczek przeglądarki, inaczej renderuje niektóre właściwości CSS i zwraca inne wartości dla części wyników MediaQuery. Utrzymujemy bazę danych znanych cech przeglądarek headless i porównujemy z nią napływające fingerprinty.
Do kluczowych wskaźników trybu headless należą: brak chrome.runtime (obecnego w Chrome z interfejsem, lecz nieobecnego w trybie headless), tablica navigator.plugins o zerowej długości, konkretne wzorce user agent kojarzone z trybem headless we wcześniejszych wersjach oraz różnice w sposobie obsługi kontekstów bezpieczeństwa iframe przez Chrome headless.
Metoda wykrywania 4: analiza długości eval
Różne silniki JavaScript mają odmienne implementacje wbudowanych funkcji, a te implementacje mają różne reprezentacje tekstowe. Sprawdzając długość Function.prototype.toString.call(eval) i porównując ją ze znanymi wartościami dla każdego silnika przeglądarki, potrafimy wykryć podszywanie się pod inne środowisko — na przykład instancję Chrome headless udającą Firefoxa.
Metoda wykrywania 5: krzyżowa walidacja TLS
Jak omawialiśmy w naszym artykule o fingerprintingu TLS, komunikat TLS Client Hello ujawnia rzeczywistą przeglądarkę lub bibliotekę HTTP nawiązującą połączenie. Gdy skrypt Playwright steruje Chrome, fingerprint TLS pasuje do Chrome — i to jest oczekiwane. Ale gdy niestandardowy bot korzysta z biblioteki requests w Pythonie albo z net/http w Go, fingerprint TLS zdradza oszustwo niezależnie od tego, jaki ciąg user agent zostaje wysłany.
Metoda wykrywania 6: analiza czasowa i behawioralna
Prawdziwi użytkownicy wykazują naturalną zmienność w czasie swoich interakcji. Poruszają myszą po krzywych, a nie po liniach prostych. Robią pauzę przed kliknięciem. Przewijają ze zmienną prędkością. Narzędzia automatyzujące, nawet te symulujące ludzkie zachowanie, generują statystycznie odróżnialne wzorce — zbyt równomierne czasy, idealnie liniowe ścieżki myszy i nienaturalne prędkości przewijania.
Zbieramy minimalne sygnały behawioralne już w trakcie samego procesu fingerprintingu — czas wywołań API, kolejność zbierania sygnałów oraz responsywność określonych API przeglądarki. Te mikrobehawioralne sygnały są trudne do podrobienia dla narzędzi automatyzacji, ponieważ zależą od faktycznego środowiska wykonawczego, a nie od właściwości, które można nadpisać.
Metoda wykrywania 7: niespójność uprawnień i API
Prawdziwe przeglądarki mają spójne stany uprawnień i dostępność API. Przeglądarka, która twierdzi, że obsługuje powiadomienia, ale nie ma konstruktora Notification, albo która raportuje określoną rozdzielczość ekranu, lecz zwraca inne wartości z window.screen i z zapytań medialnych CSS, wykazuje niespójności świadczące o manipulacji lub emulacji.
Sprawdzamy dziesiątki takich punktów walidacji krzyżowej, wypatrując sprzeczności powstających, gdy narzędzia automatyzacji wybiórczo nadpisują niektóre sygnały, nie dbając o spójność wszystkich powiązanych API.
Metoda wykrywania 8: wykrywanie maszyn wirtualnych i emulacji
Wiele operacji botów działa wewnątrz maszyn wirtualnych lub instancji chmurowych. Choć samo w sobie nie jest to dowodem automatyzacji, stanowi silny sygnał w połączeniu z innymi wskaźnikami. Warto rozróżnić tutaj dwie odrębne rzeczy, ponieważ często się je myli.
Pierwsza to renderowanie programowe. Maszyna bez prawdziwego GPU przechodzi na rasteryzator programowy, a ciąg znaków renderera WebGL mówi to wprost — „llvmpipe”, „SwiftShader” i ich warianty nazywają to bezpośrednio. To wskaźnik trybu headless: informuje o ścieżce renderowania i zasila werdykt dotyczący bota w każdym planie.
Druga to właściwe wykrywanie maszyn wirtualnych, będące funkcją planu Enterprise. Odczytuje ono ciągi renderera i dostawcy WebGL w poszukiwaniu sygnatur hipernadzorców — VMware, VirtualBox, Parallels, QEMU, Hyper-V — i zestawia je z cechami sprzętowymi niespójnymi z urządzeniami konsumenckimi: rozdzielczościami ekranu typowymi dla VM, jednym lub dwoma rdzeniami CPU przy desktopowym User-Agencie, dwoma gigabajtami pamięci lub mniej. Nie rozstrzyga żaden pojedynczy marker; detektor ocenia kombinację i podaje wartość pewności wraz z markerami, które zadziałały. Zakresy adresów centrów danych i dostawców hostingu, ustalone na podstawie danych IP intelligence, potwierdzają to od strony sieci.
Żaden z tych sygnałów nie jest sam w sobie dowodem automatyzacji — testy przeglądarek w chmurze i wirtualne pulpity bez GPU są uzasadnione — dlatego oba zasilają ważony werdykt, zamiast samodzielnie wywoływać blokadę.
Przewaga podejścia wielometodowego
Każda metoda wykrywania z osobna ma ograniczenia — wyrafinowany operator botów może ominąć dowolną pojedynczą metodę. Ale ominięcie wszystkich metod jednocześnie, przy zachowaniu spójności walidacji krzyżowej między nimi wszystkimi, jest niebotycznie kosztowne. Koszt opracowania i utrzymania bota przechodzącego wszystkie kontrole przekracza wartość ekonomiczną większości operacji botów.
Niemal zerowa liczba fałszywych trafień
Nasze wykrywanie działa w oparciu o model whitelisty dla botów wyszukiwarek (Googlebot, Bingbot itd.) weryfikowanych przez reverse DNS oraz o model wielosygnałowy dla pozostałego ruchu. Zanim zaklasyfikujemy ruch jako zautomatyzowany, wymagamy wielu potwierdzających się sygnałów. Na tym właśnie polega sens ostrożnej konstrukcji: pojedynczy niejednoznaczny marker nigdy nie wystarcza sam z siebie, więc zwykły odwiedzający, który przypadkiem uruchomi jedną kontrolę, nie zostaje zaklasyfikowany jako bot.