Skip to content

fix: add reCAPTCHA v3 detection to navigate response#49

Closed
LuminDev wants to merge 9 commits into
mainfrom
fix/recaptcha-v3-detection
Closed

fix: add reCAPTCHA v3 detection to navigate response#49
LuminDev wants to merge 9 commits into
mainfrom
fix/recaptcha-v3-detection

Conversation

@LuminDev

Copy link
Copy Markdown
Collaborator

Summary

Detect invisible Google reCAPTCHA v3 (score-based) on pages. Unlike v2 (visible checkbox widget, already handled by CDN block detection), v3 has no visual feedback — form submissions are silently rejected when the headless browser scores too low. This adds detection so users are warned.

Changes

  • recaptcha_detected field on FetchedPage struct — surfaced in MCP navigate response
  • looks_like_recaptcha_v3() — checks HTML for Google reCAPTCHA CDN scripts (www.google.com/recaptcha/api.js / www.gstatic.com/recaptcha/releases/), excludes v2 visible widgets
  • Detection runs on both HTTP fetch and browser escalation paths
  • 5 unit tests covering positive detection, negative, v2 overlap, case insensitivity

E2E Verification

  • ✅ DoraHacks login page (recaptcha_detected: true) — the page from the issue
  • ✅ example.com (false)
  • ✅ github.com (false)
  • ✅ Wikipedia (false)

Test Results

cargo test -p browser -- recaptcha  → 5/5 passed
cargo test -p browser               → 161 passed, 0 failed
cargo test -p agent -- navigate      → 31 passed, 0 failed
cargo build --release                → success

Closes #48

Detect invisible reCAPTCHA v3 (score-based) on pages by checking
for Google's reCAPTCHA CDN scripts in the raw HTML. Unlike v2
(visible widget, already handled by CDN block detection), v3 has
no visual feedback when it silently blocks headless browser form
submissions.

Changes:
- Add recaptcha_detected field to FetchedPage struct
- Add looks_like_recaptcha_v3() detection function in fetch.rs
- Populate recaptcha_detected in both HTTP and browser fetch paths
- Include recaptcha_detected in navigate MCP response JSON
- Add 5 unit tests covering positive, negative, v2 overlap, and
  case-insensitive detection

Closes #48
@Mingye-Lu

Copy link
Copy Markdown
Owner

Closing in favor of a cleaner approach. The core design of adding recaptcha_detected: bool to FetchedPage doesn't scale — every new anti-bot service would require a new struct field and new JSON key. A follow-up PR will instead surface reCAPTCHA v3 silent rejections as a ToolExecutionError that routes through the existing FailureCategory::CaptchaDetected infrastructure, keeping the API surface clean and the behavior consistent with how all other CAPTCHA challenges are handled.

@Mingye-Lu Mingye-Lu closed this Jun 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

reCAPTCHA v3 silently blocks headless browser — no detection or reporting

2 participants