Від JA3 до JA4+: Як сучасні WAF ідентифікують антидетект-браузери на мережевому рівні
Готові захистити свою цифрову особистість?
Оберіть тариф і запускайте непомітні профілі вже сьогодні.
Щоразу, коли браузер відкриває HTTPS-з’єднання, пакет TLS Client Hello транслює відбиток, що однозначно ідентифікує програмне забезпечення, яке ініціює запит. Протягом багатьох років JA3 був стандартом де-факто для захоплення цього відбитка. Але у 2023 році Джон Олтхауз — один із трьох співавторів JA3 (разом із Джеффом Аткінсоном та Джошем Аткінсом із Salesforce) — опублікував JA4+, сімейство методів фінгерпринтингу, яке миттєво зробило більшість існуючих технік обходу антидетект-браузерами застарілими. Якщо ваша система мультиакаунтингу досі покладається на рандомізацію JA3, вас майже напевно позначають на мережевому рівні ще до того, як ваш JavaScript почне виконуватися.
У цій статті ми розберемо технічну еволюцію від JA3 до JA4+, пояснимо, чому наївні стратегії рандомізації не працюють проти нового стандарту, і що повинен робити правильно спроектований антидетект-браузер для збереження невидимості на мережевому рівні.
Як працює фінгерпринтинг JA3
JA3 обчислює MD5-хеш із п’яти полів, витягнутих із повідомлення TLS Client Hello:
- Версія TLS — версія протоколу, оголошена клієнтом
- Набори шифрів (Cipher Suites) — список підтримуваних алгоритмів шифрування в порядку переваги
- Розширення (Extensions) — список кодів типів TLS-розширень у порядку слідування
- Еліптичні криві (Supported Groups) — оголошені іменовані криві
- Формати точок еліптичних кривих — підтримувані типи форматів точок
Ці поля конкатенуються через кому та хешуються:
JA3 = MD5(TLSVersion,CipherSuites,Extensions,EllipticCurves,ECPointFormats)
Реальний рядок JA3 для Chrome 120 може виглядати так:
771,4865-4866-4867-49195-49199-49196-49200-52393-52392-49171-49172-156-157-47-53,
0-23-65281-10-11-35-16-5-13-18-51-45-43-27-17513-21,29-23-24,0
Результуючий MD5-хеш стає відбитком JA3. Кожна ідентична збірка браузера на одній ОС видає однаковий хеш, що дозволяє тривіально відрізняти Chrome від Firefox або реальний браузер від сесії Python requests.
Чому рандомізація JA3 здавалася робочою
Хеш JA3 залежить від порядку. Перемішування наборів шифрів або розширень повністю змінює хеш. Ранні антидетект-браузери експлуатували це:
- Рандомізуючи порядок наборів шифрів для кожної сесії
- Ін’єктуючи фіктивні розширення (наприклад, GREASE-значення)
- Варіюючи оголошені підтримувані групи
Це працювало, тому що правила WAF на основі JA3 зазвичай підтримували allowlist’и відомих хешів. Рандомізований хеш не збігався з жодним відомим браузером, але й з жодним відомим ботом — тому часто проходив як «невідомий», а не «заблокований».
Фундаментальний недолік: рандомізація породжує відбитки, які не збігаються з жодним реальним браузером. Щойно захисники почали відзначати невідомі відбитки, а не лише блокувати відомо погані, рандомізація стала проблемою.
JA4+: Принципово новий підхід
JA4+ — це не одиничний відбиток, а ціле сімейство методів фінгерпринтингу:
| Відбиток | Що захоплює |
|---|---|
| JA4 | TLS Client Hello (заміна JA3) |
| JA4S | TLS Server Hello (заміна JA3S) |
| JA4H | HTTP-відбиток клієнта |
| JA4L | Відстань / затримка (latency) |
| JA4X | X.509 TLS-сертифікат |
| JA4SSH | Відбиток SSH-трафіку |
| JA4T | TCP-відбиток |
| JA4TS | TCP Server Response |
Ядро — відбиток JA4 — вирішує слабкості JA3 трьома архітектурними рішеннями, що роблять рандомізацію безглуздою.
1. Канонічне сортування усуває залежність від порядку
JA4 сортує набори шифрів та розширення в алфавітному порядку перед хешуванням. Два клієнти, що пропонують однаковий набір шифрів у різному порядку, генерують однаковий JA4-відбиток. Одна ця зміна інвалідує найпоширенішу техніку обходу JA3.
# JA3: порядок має значення
Ciphers: 4865,4866,4867,49195 → hash_A
Ciphers: 49195,4867,4866,4865 → hash_B (різний!)
# JA4: канонічне сортування
Ciphers: 4865,4866,4867,49195 → hash_X
Ciphers: 49195,4867,4866,4865 → hash_X (однаковий!)
2. Структурований префікс для швидкої класифікації
JA4 передує хеш-частині людиночитабельним префіксом:
JA4 = t13d1516h2_8daaf6152771_e5627efa2ab1
│││ ││││││
││└──┘│││││
││ ││││└─ ALPN: перший+останній символ
││ │││└── Кількість розширень (hex)
││ ││└─── Кількість наборів шифрів (hex)
││ │└──── Наявність SNI (d=domain, i=IP)
││ └───── Версія TLS
│└────────── Протокол (t=TCP, q=QUIC)
└─────────── (зарезервовано)
Цей префікс неможливо рандомізувати без зміни реальних можливостей TLS-стеку. Не можна заявити підтримку 22 наборів шифрів, перелічивши лише 15 — лічильник обчислюється з фактичного вмісту Client Hello.
3. Виключення GREASE-значень
GREASE (Generate Random Extensions And Sustain Extensibility) — це placeholder-коди розширень та шифрів, які браузери ін’єктують для перевірки толерантності серверів. JA4 видаляє всі GREASE-значення перед побудовою відбитка, тому впровадження випадкових GREASE-кодів — ще одна популярна техніка обходу JA3 — не дає жодного ефекту на хеш JA4.
Як WAF використовують JA4+ на практиці
Сучасні WAF (Cloudflare, Akamai, F5) розгортають відбитки JA4+ у багаторівневій детекції:
Рівень 1: Перевірка консистентності протоколу
Префікс JA4 розкриває версію TLS та кількість можливостей. Запит, що стверджує через User-Agent, що він Chrome 124, але представляє JA4-префікс, характерний для Python-бібліотеки urllib3, негайно підозрілий. WAF навіть не потрібно обчислювати повний хеш.
Рівень 2: Зіставлення з відомими браузерами
Кожна версія великого браузера на кожній великій ОС генерує невеликий набір JA4-відбитків (зазвичай 1-3 на комбінацію версія/ОС). WAF підтримують бази цих відбитків. Запит від «Chrome на Windows», чий JA4 не збігається з жодним відомим відбитком Chrome-на-Windows, отримує підвищений рівень перевірки.
Рівень 3: Крос-сигнальна кореляція (JA4H)
JA4H фінгерпринтить HTTP-рівень: порядок заголовків, патерни Accept-Language та інші HTTP-сигнали. З’єднання може мати валідний JA4 TLS-відбиток, але неузгоджений JA4H HTTP-відбиток — що виявляє, що TLS-стек і HTTP-стек належать різному ПЗ.
Рівень 4: Поведінка мережі (JA4L, JA4T)
JA4T захоплює характеристики TCP (розмір вікна, TTL, MSS), що корелюють з ОС. JA4L вимірює затримку round-trip для оцінки фізичної відстані. «Користувач у Токіо», чия JA4L-затримка відповідає маршрутизації з датацентру US East Coast, буде позначений.
# Псевдокод: багаторівнева валідація JA4+
def validate_request(request):
ja4 = extract_ja4(request.tls_client_hello)
ja4h = extract_ja4h(request.http_headers)
ja4t = extract_ja4t(request.tcp_metadata)
# Перевірка TLS-відбитка vs заявлений браузер
claimed_browser = parse_user_agent(request.headers['User-Agent'])
if ja4 not in KNOWN_FINGERPRINTS[claimed_browser]:
return ELEVATED_RISK
# Крос-перевірка HTTP-поведінки
if ja4h not in EXPECTED_HTTP_PATTERNS[claimed_browser]:
return ELEVATED_RISK
# Верифікація консистентності ОС через TCP-стек
claimed_os = parse_sec_ch_ua_platform(request.headers)
if ja4t.os_family != claimed_os:
return BLOCK
return PASS
Чому поширені стратегії обходу не працюють проти JA4+
Стратегія 1: Рандомізація наборів шифрів
Результат: Неефективна. JA4 сортує канонічно. Однаковий набір шифрів завжди дає однаковий хеш, незалежно від порядку.
Стратегія 2: Ін’єкція розширень
Результат: Частково детектується. Додавання розширень змінює лічильник розширень у JA4-префіксі, який повинен збігатися з профілями відомих браузерів. Реальний Chrome 124 має рівно N розширень — додавання або видалення будь-якого змінює префікс на незбіжне значення.
Стратегія 3: Реальний браузерний рушій з модифікованими заголовками
Результат: Детектується через крос-сигнальний аналіз. Якщо ви використовуєте TLS-стек Chromium, але модифікуєте HTTP-заголовки, JA4 і JA4H будуть неузгоджені. TLS-відбиток каже «Chrome», а HTTP-відбиток — «кастомний клієнт».
Стратегія 4: Проксування через TLS-стек реального браузера
Результат: Детектується через JA4T і JA4L. TCP-відбиток видає ОС проксі (часто Linux, коли заявляється Windows), а вимірювання затримки показують маршрутизацію через датацентр.
Що повинен робити правильний антидетект
По-справжньому невиявлюваний антидетект-браузер повинен забезпечувати консистентність за всіма вимірами JA4+ одночасно. Це вимагає архітектурних рішень, що виходять далеко за межі конфігурації.
Повний контроль над браузерним рушієм
Антидетект-браузер повинен використовувати реальний рушій (Gecko, Blink), що відповідає заявленій ідентичності. Santiago використовує модифікований рушій Camoufox (Firefox/Gecko), що означає справжній TLS-стек Firefox — який генерує автентичні JA4-відбитки без будь-якої симуляції.
Цілісність мережевого стеку
TLS-конфігурація не повинна ін’єктуватися через проксі або middleware. Розширення на кшталт encrypted_client_hello, application_layer_protocol_negotiation та signature_algorithms повинні надходити від самого браузерного рушія, а не від обгортки, що перехоплює та модифікує Client Hello.
Консистентність TCP на рівні ОС
Параметри TCP (розмір вікна, TTL, MSS, фактор масштабування вікна, підтримка SACK) повинні відповідати заявленій операційній системі:
# Windows 10/11 — типовий TCP-відбиток
TTL: 128, Window: 65535, MSS: 1460, WScale: 8, SACK: permitted
# macOS — типовий TCP-відбиток
TTL: 64, Window: 65535, MSS: 1460, WScale: 6, SACK: permitted
# Linux — типовий TCP-відбиток
TTL: 64, Window: 29200, MSS: 1460, WScale: 7, SACK: permitted
Кореляція розширень з пристроєм
Оголошені TLS-розширення повинні відповідати профілю пристрою. Наприклад, профіль Chrome на Android не повинен оголошувати розширення server_name з патерном, типовим для десктопного Chrome, і повинен включати мобільні значення ALPN.
Обізнаність щодо QUIC/HTTP3
Сучасний Chrome використовує QUIC для багатьох з’єднань. JA4+ включає фінгерпринтинг QUIC (префікс q). Антидетект-браузер, що заявляє себе як Chrome, але ніколи не ініціює QUIC-з’єднання — або ініціює QUIC з не-Chrome відбитком — створює аномалію, яку можна виявити. Браузер повинен або коректно реалізувати QUIC з правильним відбитком, або стабільно вимикати його способом, що відповідає реалістичній мережевій конфігурації (наприклад, корпоративний файрвол, що блокує UDP 443).
База даних JA4+: масштаб проблеми
Проєкт JA4+ підтримує відкриту базу відбитків із внесками від великих CDN та вендорів безпеки. Станом на початок 2026 року ця база містить:
- ~1 200 унікальних JA4-відбитків для основних комбінацій браузер/ОС
- ~400 відбитків для поширених інструментів автоматизації (Playwright, Puppeteer, Selenium)
- ~800 відбитків для HTTP-клієнтських бібліотек (requests, aiohttp, curl тощо)
Це означає, що WAF можуть позитивно ідентифікувати більшість інструментів автоматизації до виконання будь-якого JavaScript. Відбиток вбудований у найперший пакет TLS-хендшейку — немає можливості перехопити або модифікувати його постфактум.
Практичне тестування: перевірка свого JA4-відбитка
Ви можете перевірити JA4-відбиток свого браузера кількома способами:
Через Wireshark
Wireshark 4.2+ включає нативну дисекцію JA4. Захопіть трафік на своєму інтерфейсі, відфільтруйте пакети TLS Client Hello та вивчіть поле ja4:
tls.handshake.type == 1
Через CLI-інструменти ja4+
Офіційні інструменти JA4+ можуть аналізувати PCAP-файли:
# Захоплення трафіку
tcpdump -i eth0 -w capture.pcap -c 100
# Аналіз через ja4
ja4 --pcap capture.pcap --json | jq '.[] | {ja4, ja4h, ja4t}'
Через онлайн-сервіси
Сервіси на кшталт tls.browserleaks.com та tls.peet.ws відображають ваш JA4-відбиток у реальному часі, дозволяючи порівняти його з базами відомих браузерів.
Висновок
Перехід від JA3 до JA4+ являє собою парадигмальний зсув у мережевому фінгерпринтингу браузерів. Стратегії рандомізації, що працювали проти JA3, не просто неефективні проти JA4+ — вони активно шкодять, породжуючи відбитки, які кричать «спроба обходу» будь-якому сучасному WAF.
Єдиний життєздатний підхід — автентичність: використання реального браузерного рушія з немодифікованим мережевим стеком, забезпечення консистентності на рівнях TLS, HTTP, TCP та застосунку. Будь-який антидетект-браузер, що розглядає мережевий фінгерпринтинг як проблему конфігурації, а не архітектури, буде виявлений JA4+ — не іноді, а кожного разу.
Готові захистити свою цифрову особистість?
Оберіть тариф і запускайте непомітні профілі вже сьогодні.
Отримуйте 15% довічну комісію з кожного реферала.
Стати партнером →