Skip to content

[FEATURE] Anti-CDP-Detection Stealth Layer — port puppeteer-extra-stealth patches to Python #233

@Delqhi

Description

@Delqhi

Anti-CDP-Detection Stealth Layer

Why

When stealth-runner starts a Chromium process via CDP, the browser exposes:

  • navigator.webdriver === true (deadly fingerprint)
  • window.chrome differences from real Chrome
  • Permissions API behaving differently
  • Plugin/MimeType arrays incomplete
  • WebGL renderer string identifying as automation

Modern bot-detection (Cloudflare, DataDome, etc.) checks ALL of these in milliseconds and blocks the session before any user action.

Acceptance Criteria

  • New module survey-cli/survey/anti_detection/cdp_stealth.py
  • Apply puppeteer-extra-plugin-stealth-equivalent patches at page load
  • Spoofs navigator.webdriver to undefined
  • Normalizes window.chrome to match real Chrome
  • Patches navigator.plugins and navigator.mimeTypes
  • Patches navigator.permissions.query (notifications fix)
  • Spoofs WebGL renderer (configurable)
  • Hides document.$cdc_* and window.$cdc_* markers
  • All patches applied before page navigation (via Page.addScriptToEvaluateOnNewDocument)
  • Integration test: visit bot.sannysoft.com — pass all 17 checks

API Spec

from survey.anti_detection.cdp_stealth import StealthPatcher

patcher = StealthPatcher(
    preset="aggressive",  # "minimal", "standard", "aggressive"
    custom_webgl_renderer="Intel Iris OpenGL Engine",
)

# Apply at browser launch
await patcher.attach(cdp_client)

# All subsequent page loads are stealth-patched
await page.goto("https://heypiggy.com/")

Patch List (Inspired by puppeteer-extra-plugin-stealth)

  1. evasions/chrome.app — Adds Chrome browser object
  2. evasions/chrome.csi — Fixes Chrome csi() timing API
  3. evasions/chrome.loadTimes — Fixes chrome.loadTimes() API
  4. evasions/chrome.runtime — Adds Chrome runtime stubs
  5. evasions/iframe.contentWindow — Fixes iframe inheritance
  6. evasions/media.codecs — Standard codec support strings
  7. evasions/navigator.hardwareConcurrency — Matches real CPU count
  8. evasions/navigator.languages — Sets to ["en-US", "en"]
  9. evasions/navigator.permissions — Fixes notifications API
  10. evasions/navigator.plugins — Restores plugin array
  11. evasions/navigator.vendor — Sets to "Google Inc."
  12. evasions/navigator.webdriver — Hides webdriver flag
  13. evasions/sourceurl — Strips puppeteer signatures
  14. evasions/user-agent-override — Matches platform
  15. evasions/webgl.vendor — Spoofs GPU vendor strings
  16. evasions/window.outerdimensions — Fixes window size mismatch

Implementation Notes

Reference Implementation

JavaScript: https://github.com/berstend/puppeteer-extra/tree/master/packages/puppeteer-extra-plugin-stealth

Port these JS evasions to Python (they're ~50 LOC each):

# Example: navigator.webdriver patch
WEBDRIVER_PATCH = """
() => {
    Object.defineProperty(navigator, 'webdriver', {
        get: () => undefined
    });
}
"""

await cdp.send("Page.addScriptToEvaluateOnNewDocument", {
    "source": WEBDRIVER_PATCH
})

Testing

Use bot detection test pages:

Dependencies

  • No new packages — all patches are JS strings injected via CDP

Related

  • Required for deployment on protected sites
  • Optional for HeyPiggy (may already work without)
  • Required if FunCaptcha or Cloudflare Turnstile appear

Labels

enhancement, priority-high, anti-detection, stealth

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions