PerimeterX Detection: dlaczego to najtrudniejszy bot-manager na rynku
Jeśli kiedykolwiek próbowałeś scrapować strony lotnicze — United, American Airlines, Delta — albo platformy e-commerce takie jak Neiman Marcus czy Saks Fifth Avenue, prawdopodobnie spotkałeś się z blokadą PerimeterX, obecnie markowaną jako HUMAN Security. Odpowiedź HTTP 403 z ciasteczkiem _px3 to znak, że trafiłeś na jeden z najbardziej zaawansowanych systemów anti-bot na rynku.
PerimeterX różni się od konkurencji jednym kluczowym aspektem: ciężarem sygnałów behawioralnych. Podczas gdy DataDome skupia się na fingerprintingu urządzenia, a Akamai na sygnaturach TLS i HTTP/2, PerimeterX łączy wszystkie te wektory, ale decydującą rolę przypisuje temu, jak przeglądarka się zachowuje — od ruchów myszą, przez tempo wpisywania, aż po mikrozależności czasowe między eventami.
Ten artykuł to techniczny deep-dive dla inżynierów scrapingu, analityków bezpieczeństwa i zespołów QA. Pokażę architekturę PerimeterX, konkretne sygnały detekcji i — co najważniejsze — jak legalnie i etycznie pracować z serwisami chronionymi przez HUMAN Security.
Architektura PerimeterX: przepływ wyzwania JS i ciasteczka _px3 / _pxhd
PerimeterX operuje jako reverse-proxy (edge side) przed chronionym serwerem origin. Każde żądanie przechodzi przez pipeline detekcji zanim trafi do aplikacji docelowej.
Przepływ wyzwania — krok po kroku
- Pierwsze żądanie — klient wysyła GET do chronionej strony. PerimeterX sprawdza obecność i ważność ciasteczka
_px3(lub_pxhdna stronach z nowszą wersją sensora). - Brak ważnego ciasteczka — PX wstrzykuje JavaScript sensor do odpowiedzi HTML. Ten skrypt zbiera ~50+ sygnałów fingerprintowych i behawioralnych, szyfruje je i wysyła jako POST do endpointu
/_px.giflub podobnego. - Analiza po stronie serwera — model ML na backendie PerimeterX ocenia sygnały. Wynik to score 0–100, gdzie wyższy = bardziej bot-like.
- Decyzja — na podstawie score i polityki klienta: pozwól (pass-through), zablokuj (403 z customową stroną CAPTCHA), lub wyzwól (interstitial CAPTCHA / block page).
- Wydanie ciasteczka — jeśli score jest niski, PX ustawia
_px3lub_pxhdz podpisanym tokenem. To ciasteczko jest kluczem do kolejnych żądań.
Ciasteczka _px3 vs _pxhd
| Parametr | _px3 | _pxhd |
|---|---|---|
| Generacja | Starsze wdrożenia PX | Nowsze wdrożenia (2023+) |
| Zawartość | Base64-encoded payload z session ID, score, timestamp | Podobna struktura, ale z dodatkowym binding do fingerprintu urządzenia |
| TTL | Zwykle 24h–7d | Configurowalne przez klienta, często krótsze |
| Rotacja | Odświeżane przy każdym żądaniu z ważnym sensorem | Częściej rotowane, bardziej restrykcyjne |
Kluczowa obserwacja: ciasteczko PX jest bound do fingerprintu urządzenia, które je wygenerowało. Przeniesienie _px3 z jednej przeglądarki do innej (lub zmiana IP bez odpowiedniego kontekstu) spowoduje unieważnienie — to fundamentalna różnica względem prostych WAF-ów.
Sygnały detekcji PerimeterX — szczegółowa analiza
1. Device fingerprinting: Canvas, WebGL, screen metrics
PerimeterX zbiera szeroki zestaw sygnałów z JavaScript API przeglądarki:
- Canvas fingerprint — PX renderuje ukryty element Canvas z określonym tekstem i gradientem, potem porównuje hash wynikowego imageData. Headless Chrome renderuje Canvas minimalnie inaczej niż pełna przeglądarka (różnice w anti-aliasingu, subpixel rendering). Nawet
faker.canvasw Playwright-Stealth nie zawsze jest wystarczający. - WebGL renderer i vendor — PX wywołuje
getParameter(RENDERER)igetParameter(VENDOR). Headless Chrome zwracaSwiftShaderjako renderer — to natychmiastowa flaga. Prawidłowy kontekst powinien pokazywać rzeczywisty GPU (np.ANGLE (NVIDIA, GeForce RTX 3080...)). - Screen metrics —
screen.width,screen.height,availWidth,colorDepth,pixelDepth,devicePixelRatio. Headless Chrome domyślnie mawidth: 800, height: 600— natychmiastowa detekcja. - WebRTC leak — PX sprawdza, czy WebRTC ujawnia lokalne IP (mDNS). Jeśli WebRTC jest wyłączone lub zwraca niespójne dane, to sygnał.
2. TLS fingerprinting: JA3 / JA4
PerimeterX klasyfikuje połączenia TLS na poziomie edge, zanim jakikolwiek HTTP request dotrze do serwera.
JA3 hash składa się z: TLS version, cipher suites, extensions, elliptic curves, point formats. Chrome 120 na Windows generuje inny JA3 niż Chrome 120 na Linuxie — różnice w supported_groups i ALPN extension.
JA4 (nowszy standard) dodatkowo uwzględnia: GREASE values, order of extensions, SNI presence. To sprawia, że proste manipulacje cipher suite nie wystarczą — cała struktura ClientHello musi być spójna.
Krytyczne konsekwencje:
- Python
requestsztls-clientma inny JA3 niż jakakolwiek prawdziwa przeglądarka — PX to wykryje. - Playwright z Chromium generuje poprawny JA3 tylko wtedy, gdy uruchomiony jest w trybie headed lub z odpowiednio skonfigurowanym kontekstem.
- Datacenter IP + niespójny JA3 = natychmiastowy block.
3. IP reputation i geolokacja
PerimeterX utrzymuje rozległą bazę reputacji IP, obejmującą:
- Datacenter ranges — AWS, GCP, Azure, OVH, DigitalOcean itd. Każdy IP z tych ranges dostaje automatycznie podwyższony score.
- ASN classification — ISP (residential/mobile) vs hosting provider. PX klasyfikuje ASN na podstawie publicznych baz.
- Geo-konsystencja — jeśli IP jest z DE, ale Accept-Language to
en-US, a timezone toAmerica/New_York— to sygnał niespójności. - Historyczne wzorce — IP, które widziały masowe requesty w przeszłości, dostają „sticky" penalty.
4. Behavioral signals: ruch myszą, timing, scroll patterns
To jest core differentiator PerimeterX. Ich sensor JS zbiera:
- Mouse movement events —
mousemove,mousedown,mouseup,click. PX analizuje krzywiznę ruchu (Bezier curve fitting), prędkość, akcelerację, i „naturalność" zygzaków. Boty generują idealnie proste linie lub sinusoidy — ludzie robią mikrokorekty. - Keyboard events —
keydown,keyup,keypress. PX mierzy interwały między keystrokes (keystroke dynamics). Boty mają stały interwał; ludzie mają rozkład log-normalny. - Scroll patterns — prędkość scrolla, „coasting" (naturalne zwalnianie), zmiana kierunku.
- Timing anomalies — czas między
DOMContentLoadeda pierwszymmousemove. Czas między załadowaniem strony a kliknięciem. Boty klikają natychmiast; ludzie potrzebują 200–800ms na lokalizację elementu. - Event sequence consistency —
focus→mouseover→mousedown→mouseup→click→blur. Brakujące eventy lub odwrócona kolejność to silny sygnał bot.
PerimeterX jest behavioral-first. Możesz mieć idealny Canvas fingerprint, poprawny JA3 i residential IP — ale jeśli Twój bot nie generuje naturalnych ruchów myszą, dostaniesz 403. To fundamentalna różnica względem DataDome i Akamai.
PerimeterX vs DataDome vs Akamai Bot Manager — porównanie
| Wymiar | PerimeterX (HUMAN) | DataDome | Akamai Bot Manager |
|---|---|---|---|
| Primary signal | Behavioral (mouse, keyboard, timing) | Device fingerprint + HTTP/2 fingerprint | TLS/JA3 + HTTP/2 + cookie binding |
| JS sensor complexity | Bardzo wysoka (~200KB minified) | Wysoka (~150KB) | Średnia-wysoka (~100KB) |
| TLS fingerprinting | JA3 + JA4 | Minimalne | JA3 + JA4 + HTTP/2 AKAMAI fingerprint |
| Canvas/WebGL | Tak, z hash comparison | Tak, bardzo agresywnie | Tak, ale mniejsza waga |
| Behavioral depth | Najgłębsza na rynku | Podstawowa (mouse only) | Średnia |
| IP reputation | Krytyczna — datacenter = auto-block | Ważna, ale nie determinująca | Ważna, z ASN scoring |
| CAPTCHA type | Custom interstitial + funcaptcha | Custom slider/puzzle | Custom challenge page |
| Cookie binding | _px3 / _pxhd bound do fingerprintu | dd_cookie, bound do IP+fingerprint | ak_bmsc, bound do sensor data |
Konkretne strategie mitigacji: residential proxies + Playwright Stealth + pacing
Warstwa 1: Residential proxy z odpowiednim geo-targetingiem
PerimeterX automatycznie blokuje datacenter IP. To nie jest sygnał „mniej ważny" — to hard block. Jeśli Twój request pochodzi z IP hostingu, PX nie dotrze nawet do etapu analizy behawioralnej.
Rozwiązanie: residential proxies z ISP ASN, najlepiej mobilne (mobile proxies mają najwyższą reputację). Przy ProxyHat:
# Podstawowe żądanie curl przez residential proxy z geo-targetingiem US
curl -x http://user-country-US:password@gate.proxyhat.com:8080 \
"https://www.united.com/" \
-H "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36" \
-H "Accept: text/html,application/xhtml+xml" \
-H "Accept-Language: en-US,en;q=0.9" \
-H "Accept-Encoding: gzip, deflate, br"
Kluczowe zasady wyboru proxy:
- Geo-konsystencja — jeśli scrapujesz united.com (US airline), użyj IP z USA z
Accept-Language: en-USi timezoneAmerica/New_York. - Sticky sessions — PX bindowa ciasteczko do IP. Zmiana IP w trakcie sesji = unieważnienie. Używaj sesji sticky na 10–30 minut.
- Rotacja po limicie — po 50–100 requestów z jednego IP, PX zaczyna podnosić score. Rotuj IP proaktywnie, nie reaktywnie.
# Sticky session z ProxyHat — ten sam IP przez 30 minut
# Format: user-session-{id}-country-US
curl -x http://user-session-abc123-country-US:password@gate.proxyhat.com:8080 \
"https://www.united.com/en/us/fly/" \
-H "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36"
Warstwa 2: Playwright Stealth z pełnym kontekstem przeglądarki
Sam residential IP nie wystarczy — musisz mieć przeglądarkę, która wygląda i zachowuje się jak prawdziwa. Playwright-Stealth (lub playwright-extra z stealth plugin) rozwiązuje większość fingerprintów, ale wymaga ostrożnej konfiguracji.
from playwright.sync_api import sync_playwright
from playwright_stealth import stealth_sync
import time, random
PROXY = {
"server": "http://gate.proxyhat.com:8080",
"username": "user-session-search1-country-US",
"password": "PASSWORD"
}
with sync_playwright() as p:
browser = p.chromium.launch(
headless=False, # headed mode = lepszy JA3 i Canvas
args=[
"--disable-blink-features=AutomationControlled",
"--window-size=1920,1080",
]
)
context = browser.new_context(
viewport={"width": 1920, "height": 1080},
screen={"width": 1920, "height": 1080},
locale="en-US",
timezone_id="America/New_York",
proxy=PROXY,
user_agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
"AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/125.0.0.0 Safari/537.36",
color_scheme="light",
device_scale_factor=1,
)
page = context.new_page()
stealth_sync(page)
# Nawigacja z naturalnym opóźnieniem
page.goto("https://www.united.com/en/us", wait_until="networkidle")
time.sleep(random.uniform(2.0, 4.5))
# Symulacja naturalnego ruchu myszą
page.mouse.move(
random.randint(200, 800),
random.randint(200, 600)
)
time.sleep(random.uniform(0.3, 0.8))
# Interakcja z elementem — pełna sekwencja eventów
element = page.locator("#search-input")
element.hover()
time.sleep(random.uniform(0.1, 0.3))
element.click()
time.sleep(random.uniform(0.05, 0.15))
element.type("SFO to JFK", delay=random.uniform(50, 150))
# Czekaj na wyzwania PX
page.wait_for_timeout(5000)
context.close()
browser.close()
Krytyczne szczegóły konfiguracji Playwright
- Headed mode — uruchomienie w trybie
headless=False(lub z Xvfb na serwerze) daje poprawny Canvas fingerprint i JA3. Headless Chrome ma charakterystyczne różnice w rendering. - Screen i viewport muszą być spójne —
screeniviewportwnew_context()muszą się zgadzać. 1920×1080 to najczęstszy desktop. - deviceScaleFactor = 1 — Retina displays (factor=2) są podejrzane na desktopach. Użyj 1.
- WebGL override — jeśli Chromium zwraca SwiftShader, użyj
--use-gl=angleflag lub pluginu do override'u WebGL renderer. - Nie nadpisuj navigator.webdriver — Playwright-Stealth robi to automatycznie, ale ręczne nadpisanie może być wykryte przez PX (sprawdzają, czy property descriptor się zmienił).
Warstwa 3: Pacing i naturalne wzorce zachowania
Nawet z idealnym fingerprintem i residential IP, PerimeterX wykryje bota po wzorcu czasowym:
- Randomizuj interwały — nie używaj
time.sleep(3). Użyjrandom.uniform(2.0, 5.0)z rozkładem log-normalnym. - Limituj concurrency — max 1–2 requesty na IP na sekundę. PX wykrywa burst patterns.
- Emuluj prawdziwą sesję — wejdź na homepage, poczekaj 3–5s, potem nawiguj do search, potem do wyników. Nie skacze bezpośrednio do deep URL.
- Dodaj „browsing noise" — co 5–10 requestów, odwiedź favicon.ico, załaduj CSS, wyślij request do /api/track. PX cross-validuje, czy wzorzec wygląda jak prawdziwy user.
- Rotuj sesje proxy — po 50–100 requestach lub po 20–30 minutach, zmień IP. Użyj sesji sticky ProxyHat.
Warstwa 4: Zarządzanie ciasteczkami PX
Ciasteczko _px3 lub _pxhd jest Twoim „biletem" — raz uzyskane, pozwala na kolejne requesty bez wyzwania. Optymalna strategia:
- Otwórz nową sesję przeglądarki z nowym residential IP.
- Nawiguj do strony — pozwól sensorowi PX się załadować i wysłać dane.
- Wykonaj naturalne akcje (ruch myszą, scroll, kliknięcie).
- Poczekaj na ciasteczko
_px3w odpowiedzi. - Zapisz ciasteczko i używaj go w kolejnych requestach (z tego samego IP).
- Po 50–100 requestów lub przy wzroście error rate, rotuj IP i ciasteczko razem.
Serwisy korzystające z PerimeterX / HUMAN Security
PerimeterX jest szczególnie popularny w branżach z wysoką wartością danych:
- Linie lotnicze — United Airlines, American Airlines, Delta Air Lines, JetBlue. Scrapowanie cen biletów to najczęstszy use case, ale też najcięcej broniony.
- Luxury e-commerce — Neiman Marcus, Saks Fifth Avenue. PX chroni przed botami kupującymi limited drops i price scrapers.
- Tickety — niektóre platformy ticketingowe używają PX do ochrony przed automated purchasing.
- Real estate — Zillow i podobne platformy (nie wszystkie, ale część korzysta z HUMAN).
Dla każdej z tych branż, PerimeterX konfiguruje różne progi — linie lotnicze mają najbardziej agresywne ustawienia (nawet 3–5 requestów z datacenter IP = permanent block na poziomie IP).
Etyczne i legalne ramy scrapingu
Każdy opisany w tym artykule mechanizm omijania zabezpieczeń należy stosować wyłącznie w ramach legalnej działalności:
- Autoryzowane pentesty — testowanie własnych serwisów lub serwisów klienta z wyraźnym zapisem w umowie.
- Scraping w ramach TOS — jeśli regulamin serwisu nie zabrania scrapingu (lub wyraźnie go pozwala).
- Badania bezpieczeństwa — analiza mechanizmów detekcji w celu poprawy własnych zabezpieczeń (bug bounty, responsible disclosure).
- Legalny monitoring cen — w jurysdykcjach, gdzie publicznie dostępne dane cenowe mogą być gromadzone na podstawie dozwolonego użytku (fair use, prawo cytatu).
Przestrzegaj robots.txt, honoruj Crawl-Delay, nie obciążaj serwerów docelowych ponad miarę, i zawsze weryfikuj czy Twoja działalność jest zgodna z obowiązującym prawem (GDPR, CCPA, CFAA, Ustawą o prawie autorskim). ProxyHat nie wspiera ani nie zachęca do nielegalnego scrapingu.
Więcej o etycznych aspektach scrapingu przeczytasz w naszym artykule o najlepszych praktykach web scrapingu.
Key Takeaways
- PerimeterX jest behavioral-first — idealny fingerprint i residential IP nie wystarczą, jeśli Twój bot nie generuje naturalnych ruchów myszą i realistycznych timingów.
- Datacenter IP = natychmiastowy block — residential lub mobile proxy to wymóg, nie opcja. ProxyHat oferuje oba typy z geo-targetingiem.
- JA3/JA4 musi być spójny — używaj Playwright w headed mode z właściwymi flagami, nie Python requests z tls-client.
- Canvas i WebGL fingerprinty muszą być realistyczne — headless Chrome z SwiftShader to natychmiastowa detekcja.
- Pacing jest krytyczny — 1–2 requesty/s na IP, randomizowane interwały, pełne sekwencje eventów (hover → click → type).
- Rotuj IP i ciasteczka razem — _px3/_pxhd jest bound do fingerprintu i IP. Zmiana jednego bez drugiego = unieważnienie.
- Zawsze działaj etycznie i legalnie — honoruj TOS, robots.txt i obowiązujące prawo.






