Explainers

How reCAPTCHA Detects Automation and How API Solvers Work

reCAPTCHA uses a multi-layered detection system that goes far beyond the visible checkbox or image challenge. It runs a sophisticated fingerprinting and behavioral analysis engine that identifies automated tools before the user even interacts with the CAPTCHA. This guide breaks down every detection method reCAPTCHA uses and explains how API-based solvers like CaptchaAI handle all of them.


Detection layer 1: JavaScript environment probing

reCAPTCHA executes JavaScript probes to detect headless browsers and automation frameworks.

The primary automation indicator:

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

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

When navigator.webdriver is true, reCAPTCHA immediately flags the session as automated, typically resulting in a score of 0.1 or lower.

Missing browser APIs

reCAPTCHA probes for APIs that headless browsers omit or implement differently:

// 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",
};
Probe Expected (real Chrome) Headless Chrome Detection
window.chrome Object undefined or minimal Automation
navigator.plugins 2-5 plugins Empty array Automation
navigator.permissions Object with query() May throw or be missing Automation
Notification.permission "default" May throw Automation
window.speechSynthesis Object with voices Empty or missing Automation

Prototype chain tampering

Sophisticated automation tools override browser APIs to hide their presence. reCAPTCHA tests for tampering:

// 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] }"

Detection layer 2: Canvas and WebGL fingerprinting

Canvas fingerprint

reCAPTCHA renders hidden elements on a canvas and reads back pixel data. The result varies by OS, GPU, font rendering engine, and anti-aliasing settings:

// Simplified canvas fingerprint
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

Detection signals:

  • Same fingerprint across different reported OS/browsers → Spoofing detected
  • Canvas operations return uniform/blank data → Headless environment
  • Fingerprint matches known headless Chrome pattern → Automation flagged

WebGL fingerprint

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 is Google's software GPU renderer used when no hardware GPU is available — a clear headless environment indicator.


Detection layer 3: Behavioral analysis

This is reCAPTCHA's strongest detection layer. It monitors user behavior from page load through form submission.

Mouse movement analysis

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

Keyboard analysis

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

Timing and interaction sequence

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

Detection layer 4: Network and IP analysis

IP reputation database

Google maintains extensive IP intelligence:

  • Known data center ranges: AWS (52.x.x.x, 54.x.x.x), GCP, Azure, DigitalOcean, etc.
  • Known proxy/VPN providers: NordVPN, ExpressVPN, commercial proxy services
  • Tor exit nodes: Public list, updated regularly
  • Abuse history: IPs involved in spam, scraping, or CAPTCHA farming
  • Geographic patterns: Rapid location changes flag VPN hop patterns

TLS fingerprinting

Each HTTP client produces a unique TLS handshake fingerprint (JA3/JA4):

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 validates that the TLS fingerprint matches the declared User-Agent. A Chrome User-Agent with a Python TLS fingerprint is flagged as automation.

HTTP header analysis

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

Detection layer 5: Cross-session intelligence

reCAPTCHA tracks patterns across multiple sessions and sites:

  • Session fingerprint correlation: Same browser fingerprint making rapid requests across many sites
  • Solve pattern analysis: Correct answers within consistent time windows (human solve times are variable)
  • Challenge response correlation: Multiple sessions solving identical challenges within seconds
  • Cookie timeline: Multiple fresh sessions from the same IP with no cookie persistence

How API-based solvers handle detection

API-based solvers like CaptchaAI bypass reCAPTCHA's detection system by operating in a completely separate environment:

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 fingerprint (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

Key insight: Your automation never interacts with reCAPTCHA directly. The solver handles all fingerprinting, behavioral analysis, and challenge completion in an environment optimized to pass every detection layer. Your code only needs to submit the resulting token.

Python example

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://example.com/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 example

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");
}

Frequently asked questions

Can reCAPTCHA detect that an API solver was used?

reCAPTCHA validates the token against its own records. If the solver environment produced a legitimate solve with human-like behavior, the token is valid. Google sees a normal human solve, not a third-party service. The token itself does not carry information about how it was generated.

Does using Selenium always trigger reCAPTCHA detection?

Default Selenium with default ChromeDriver is detected immediately due to navigator.webdriver = true, missing Chrome APIs, and ChromeDriver HTTP headers. Stealth-configured Selenium (undetected-chromedriver, stealth plugins) can reduce detection but does not eliminate it. API-based solving avoids the problem entirely by not interacting with reCAPTCHA in your browser.

How quickly does reCAPTCHA update its detection methods?

Google updates reCAPTCHA's detection heuristics continuously. Major updates occur every few months. New headless browser detection methods are typically deployed within weeks of a new automation tool release. API solver services like CaptchaAI adapt to these changes immediately because they maintain their own optimized solving environments.

Does reCAPTCHA share detection data across websites?

Yes. reCAPTCHA's risk analysis incorporates cross-site signals through the _GRECAPTCHA cookie and Google's server-side intelligence. Poor behavior on one reCAPTCHA-protected site can lower scores on other sites using the same browser profile.


Summary

reCAPTCHA detects automation through five layers: JavaScript environment probing (headless detection), canvas/WebGL fingerprinting, behavioral analysis (mouse, keyboard, scroll), network/IP reputation, and cross-session intelligence. API-based solvers like CaptchaAI handle all five layers by solving challenges in a separate, optimized environment and returning a valid token. Your automation code never directly interacts with reCAPTCHA, making it invisible to the detection system.

Discussions (0)

No comments yet.