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.
navigator.webdriver detection
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)
Join the conversation
Sign in to share your opinion.
Sign InNo comments yet.