Explainers

Как reCAPTCHA обнаруживает автоматизацию и как работают API-решатели

Флаг WebDriver, canvas-сигнатура, скорость движения курсора, TLS-подпись клиента — reCAPTCHA складывает эти сигналы в единый score ещё до того, как пользователь вообще увидел чекбокс.

Проверка идёт в пять слоёв: JS-окружение, Canvas/WebGL, поведение, сеть/IP и память между сессиями. Ниже — как устроен каждый слой и почему API-решатели вроде CaptchaAI не запускают ни один из них, отправляя запрос напрямую в отдельную решающую среду.

Слой Что проверяет reCAPTCHA Типичный сигнал
1. JS-окружение headless-признаки браузера navigator.webdriver
2. Canvas/WebGL сигнатура рендеринга GPU vendor/renderer
3. Поведение мышь, клавиатура, скролл ритм и траектория
4. Сеть/IP/TLS репутация IP, TLS-подпись JA3/JA4
5. Кросс-сессии память между сайтами повторяющиеся паттерны

Флаг WebDriver: что видит reCAPTCHA

Первым делом reCAPTCHA прогоняет набор JS-проверок, которые отличают headless-браузер и фреймворки автоматизации от обычного Chrome. Главный индикатор автоматизации:

// Selenium/Puppeteer set this automatically
navigator.webdriver === true  // → Automation detected

// Real browser
navigator.webdriver === undefined  // or false → Normal browser

Как только флаг WebDriver возвращает true, reCAPTCHA сразу помечает сессию как автоматизированную — обычно это даёт score 0,1 и ниже.

Это первая и самая грубая проверка: она отсекает автоматизацию до того, как reCAPTCHA вообще начинает смотреть на поведение или сеть.

Каких браузерных API не хватает в headless-режиме

reCAPTCHA опрашивает API, которые headless-браузеры либо не реализуют, либо реализуют иначе:

// Probes reCAPTCHA performs (simplified)
const checks = {
    // Chrome-specific object
    hasChrome: !!window.chrome,
    hasChromeRuntime: !!(window.chrome && window.chrome.runtime),

    // Plugin and MIME type arrays
    pluginCount: navigator.plugins.length,
    mimeTypeCount: navigator.mimeTypes.length,

    // Notification permission
    notificationPermission: Notification.permission,

    // Speech synthesis voices
    speechVoices: window.speechSynthesis.getVoices().length,

    // Performance observer
    hasPerformanceObserver: typeof PerformanceObserver !== "undefined",
};
Проверка Ожидаемое значение (обычный Chrome) Headless Chrome Результат
window.chrome объект undefined или минимальный набор автоматизация
navigator.plugins 2–5 плагинов пустой массив автоматизация
navigator.permissions объект с методом query() может выбросить ошибку или отсутствовать автоматизация
Notification.permission "default" может выбросить ошибку автоматизация
window.speechSynthesis объект со списком голосов пуст или отсутствует автоматизация

Подмена методов через прототипы

Продвинутые инструменты автоматизации переопределяют браузерные API, чтобы спрятать своё присутствие. reCAPTCHA проверяет именно это вмешательство:

// reCAPTCHA may check if native functions were modified
const nativeToString = Function.prototype.toString;
const pluginsToString = navigator.plugins.toString();

// Overridden functions have different toString output:
// Native: "function get plugins() { [native code] }"
// Overridden: "function () { return [...fakePlugins] }"

Canvas-сигнатура окружения

reCAPTCHA рисует скрытые элементы на canvas и считывает пиксели обратно. Результат зависит от ОС, GPU, движка рендеринга шрифтов и настроек сглаживания — то есть от конкретной машины:

// Simplified canvas сигналы браузера
const canvas = document.createElement("canvas");
const ctx = canvas.getContext("2d");
ctx.textBaseline = "alphabetic";
ctx.font = "14px Arial";
ctx.fillStyle = "#f60";
ctx.fillRect(125, 1, 62, 20);
ctx.fillStyle = "#069";
ctx.fillText("CaptchaTest,!", 2, 15);

const fingerprint = canvas.toDataURL();
// Unique per browser/OS/GPU combination

На что смотрит reCAPTCHA:

Наблюдение Вывод
одна и та же сигнатура при разных заявленных ОС/браузерах похоже на спуфинг
canvas возвращает однородные или пустые данные признак headless-среды
сигнатура совпадает с известным паттерном headless Chrome сессия помечается как автоматизация

WebGL: vendor и renderer

const gl = document.createElement("canvas").getContext("webgl");
const debugInfo = gl.getExtension("WEBGL_debug_renderer_info");

const vendor = gl.getParameter(debugInfo.UNMASKED_VENDOR_WEBGL);
const renderer = gl.getParameter(debugInfo.UNMASKED_RENDERER_WEBGL);

// Real browser: "ANGLE (NVIDIA GeForce RTX 3060 Direct3D11 vs_5_0 ps_5_0)"
// Headless Chrome: "Google Inc. (Google SwiftShader)" ← Strong bot signal

SwiftShader — программный GPU-рендерер Google, который включается, когда нет доступного физического GPU. Само его наличие — сильный сигнал headless-среды.


Движения курсора

Поведенческий анализ — самый сильный уровень детекции reCAPTCHA: он снимает поведение пользователя от загрузки страницы до отправки формы.

reCAPTCHA records:
  ├─ Mouse coordinates at ~60fps intervals
  ├─ Velocity and acceleration at each point
  ├─ Trajectories between clickable elements
  ├─ Hover patterns over links and buttons
  ├─ Micro-movements while "stationary"
  └─ Natural overshoot when targeting elements

Human pattern:

  - Curved paths with variable speed
  - Natural acceleration/deceleration (Fitts's Law)
  - Random micro-jitter during hovering
  - Occasional overshoot and correction

Bot pattern:

  - Zero mouse events (no mouse simulation)
  - Straight lines at constant speed
  - Perfect targeting (no overshoot)
  - Identical patterns across sessions

Клавиатурный почерк

reCAPTCHA records:
  ├─ Inter-key interval for each key pair
  ├─ Key hold duration (keydown to keyup)
  ├─ Error rate (backspace frequency)
  ├─ Typing rhythm consistency
  └─ Input method (keyboard vs paste vs JavaScript)

Human pattern:

  - Variable intervals (80-300ms typical)
  - Faster for common character pairs
  - Occasional errors and corrections
  - keydown → keypress → keyup sequence

Bot pattern:

  - Constant intervals or instant input
  - No keypress events (value set via JS)
  - Zero errors
  - All characters appear simultaneously

Тайминг взаимодействия со страницей

reCAPTCHA records:
  ├─ Time from page load to first interaction
  ├─ Time from CAPTCHA rendering to click
  ├─ Scroll events and depths
  ├─ Focus/blur events on form fields
  └─ Tab between fields vs click between fields

Suspicious patterns:

  - First interaction < 1 second after page load
  - CAPTCHA clicked immediately after rendering
  - No scroll events before interacting with below-fold content
  - All form fields filled in <500ms

Репутация IP-адреса в базе reCAPTCHA

reCAPTCHA также анализирует сеть, IP-адрес и TLS-рукопожатие. У Google есть обширная база данных по IP:

Признак Пример
Диапазоны дата-центров AWS (52.x.x.x, 54.x.x.x), GCP, Azure, DigitalOcean
Прокси/VPN-провайдеры NordVPN, ExpressVPN, коммерческие прокси
Выходные узлы Tor публичный список, обновляется регулярно
История злоупотреблений IP, ранее замеченные в спаме, парсинге, массовом решении CAPTCHA
Гео-паттерны резкая смена локации между запросами → VPN-перескок

TLS-сигнатура (JA3/JA4)

Каждый HTTP-клиент оставляет уникальную подпись TLS-рукопожатия:

Chrome 120:    JA3 = 771,4865-4866-4867-49195-49199-49196..
Python/requests: JA3 = 771,4866-4867-4865-49196-49200..
curl/libcurl:  JA3 = 771,49196-49200-159-52393-52392..

reCAPTCHA сверяет, соответствует ли TLS-сигнатура заявленному User-Agent. Chrome в User-Agent при Python-подписи TLS — прямой повод пометить сессию как автоматизацию.

HTTP-заголовки

Real Chrome headers:
  Accept: text/html,application/xhtml+xml,application/xml;q=0.9,...
  Accept-Language: en-US,en;q=0.9
  Accept-Encoding: gzip, deflate, br
  Sec-CH-UA: "Not_A Brand";v="8", "Chromium";v="120"
  Sec-CH-UA-Platform: "Windows"
  Sec-Fetch-Dest: document
  Sec-Fetch-Mode: navigate

Automation headers (missing or different):

  - Missing Sec-CH-UA headers
  - Missing Accept-Language
  - Non-standard Accept header
  - Missing Sec-Fetch-* headers

Память reCAPTCHA между сайтами и сессиями

reCAPTCHA сопоставляет паттерны сразу по нескольким сессиям и сайтам.

Корреляция сессий

Один и тот же браузерный профиль, делающий быстрые запросы на множестве сайтов подряд, — заметный сигнал. Правильные ответы, приходящие в стабильно одинаковые интервалы времени, тоже выделяются: у живого человека время решения всегда «плавает».

  • Несколько сессий решают идентичные задачи за считаные секунды.
  • Много свежих сессий с одного IP без сохранения cookie между заходами.

Как API-решатели проходят все пять слоёв

API-решатели вроде CaptchaAI не пытаются обмануть детектор в вашем окружении — они вообще не появляются в нём. Задача решается в отдельной инфраструктуре решателя:

Your automation:
  Extracts sitekey + pageurl from target page
      ↓
  Sends to CaptchaAI API (HTTPS request to ocr.captchaai.com)
      ↓
CaptchaAI's solver environment:
  ├─ Real browser with genuine сигналы браузера (not headless)
  ├─ Human-like behavioral patterns
  ├─ Clean residential IP
  ├─ Valid cookies and session history
  ├─ Matching TLS/header fingerprints
  └─ Solves the challenge with human-like behavior
      ↓
  Returns valid g-recaptcha-response token
      ↓
Your automation:
  Submits token to target website
      ↓
Target website validates token with Google
  → Google sees a legitimate solve from a trusted environment
  → Token validated: success = true

Главное: ваш код никогда не взаимодействует с reCAPTCHA напрямую — всю работу со средой, поведением и прохождением задачи берёт на себя решатель. От кода требуется только отправить готовый токен в форму.

Практический пример: QA-тестирование чекаута

Команда, которая гоняет regression-тесты интернет-магазина в headless Chrome, обычно первой ловит reCAPTCHA v2 на форме оплаты — headless-флаг убивает сценарий раньше, чем тест успевает дойти до логики корзины. Вместо патчей браузера тесты просто отправляют sitekey и pageurl в API CaptchaAI и ждут токен: для одного CI/CD-пайплайна хватает BASIC ($15/мес, 5 потоков), для параллельных прогонов — STANDARD ($30/мес, 15 потоков). Если тест заодно собирает логи со страницы, ограничьте сбор минимумом — разумная гигиена и по 152-ФЗ, и по GDPR.

Пример на Python

import requests
import time

API_KEY = "YOUR_API_KEY"

# Your automation only needs sitekey and pageurl
submit = requests.post("https://ocr.captchaai.com/in.php", data={
    "key": API_KEY,
    "method": "userrecaptcha",
    "googlekey": "6LcR_RsTAAAAAN_r0GEkGBfq3L7KmU5JbPHJtwNp",
    "pageurl": "https://staging.example.com/qa-login",
    "json": 1,
})

task_id = submit.json()["request"]

# Poll for token
for _ in range(60):
    time.sleep(5)
    result = requests.get("https://ocr.captchaai.com/res.php", params={
        "key": API_KEY,
        "action": "get",
        "id": task_id,
        "json": 1,
    }).json()

    if result.get("status") == 1:
        token = result["request"]
        # Submit this token to the target site's form
        print("Token received — submit to target form")
        break

Пример на Node.js

const axios = require("axios");

async function solveRecaptcha(sitekey, pageurl) {
    const API_KEY = "YOUR_API_KEY";

    const { data: submit } = await axios.post(
        "https://ocr.captchaai.com/in.php",
        new URLSearchParams({
            key: API_KEY,
            method: "userrecaptcha",
            googlekey: sitekey,
            pageurl: pageurl,
            json: 1,
        })
    );

    const taskId = submit.request;

    for (let i = 0; i < 60; i++) {
        await new Promise(r => setTimeout(r, 5000));
        const { data: result } = await axios.get(
            "https://ocr.captchaai.com/res.php",
            { params: { key: API_KEY, action: "get", id: taskId, json: 1 } }
        );

        if (result.status === 1) return result.request;
    }

    throw new Error("Timeout");
}

Частые вопросы

Влияет ли API-решение на итоговый score reCAPTCHA v3?

Да, но не в худшую сторону, если решатель отработал честно. reCAPTCHA v3 не даёт бинарного «прошёл/не прошёл» — она возвращает score от 0 до 1 по тем же пяти слоям. Если среда решателя вела себя как обычный браузер, Google засчитывает нормальный сеанс, и score получается не хуже, чем при обычном визите.

Обнаруживает ли reCAPTCHA обычный Selenium без дополнительных настроек?

Да, почти мгновенно — из-за WebDriver = true, отсутствующих Chrome API и заголовков ChromeDriver. Маскировка (undetected-chromedriver, доп. плагины) снижает риск, но не убирает его полностью. Решение через API снимает проблему целиком: reCAPTCHA вообще не видит ваш браузер.

Нужно ли моей автоматизации самой имитировать движения мыши и ввод с клавиатуры?

Нет — если задача уходит на решение через API, все поведенческие сигналы (мышь, клавиатура, скролл) генерирует среда решателя, а не ваш скрипт. Вашему коду достаточно передать sitekey и pageurl, дождаться готового g-recaptcha-response и подставить его в форму.

Как долго можно ждать с отправкой полученного токена?

Токен reCAPTCHA действителен ограниченное время — не кешируйте его «про запас», запрашивайте перед самой отправкой формы и отправляйте сразу после получения. Если между получением и сабмитом проходят десятки минут, запросите новый.

Как часто reCAPTCHA обновляет методы детекции, и не устареет ли этот разбор?

Google обновляет эвристики детекции постоянно, крупные изменения выходят раз в несколько месяцев. Новые способы вычислять headless-браузеры обычно закрываются в течение нескольких недель после релиза инструмента. Решатели вроде CaptchaAI подстраиваются сразу, потому что сами поддерживают свою решающую среду, а не полагаются на статичный набор патчей.


Итог

reCAPTCHA считает score по пяти слоям: JS-окружение (headless-детекция), Canvas/WebGL-сигнатура, поведение (мышь, клавиатура, скролл), репутация сети/IP и память между сессиями. API-решатели вроде CaptchaAI закрывают все пять слоёв разом, решая задачу в отдельной подготовленной среде и возвращая уже валидный токен. Код автоматизации не соприкасается с reCAPTCHA напрямую — детектировать нечего.

Похожие статьи

Комментарии для этой статьи отключены.