<!-- retoor <retoor@molodetz.nl> -->
# Stealth patches and limits

What stealthii changes about stock headless Chromium, how it is
verified, and where the protection ends. Transcribed from
`STEALTH_PATCHES.md` and `PERFORMANCE.md` of the source repo.

## Launch flags

- `--disable-blink-features=AutomationControlled`: removes the
  `navigator.webdriver` flag at engine level.
- `ignore_default_args=["--enable-automation"]`: suppresses
  Playwright's automation infobar behavior.
- `--no-sandbox` and `--disable-dev-shm-usage`: container operability,
  not stealth.
- `--disk-cache-size` / `--media-cache-size`: bound on-disk cache
  growth, set from `disk_cache_bytes`.

## JS patches

Injected via `add_init_script` on every context before any page script
runs: `navigator.webdriver` redefined to `undefined`; a shaped
`window.chrome` object when absent (including same-origin iframes);
`permissions.query` for notifications aligned with
`Notification.permission`; a five-entry `PluginArray` with matching
MIME types; `deviceMemory` and `hardwareConcurrency` set to 8; WebGL
vendor/renderer rewritten from SwiftShader to an NVIDIA discrete GPU
string; every patch function wrapped so `toString()` still reports
native code.

## Verification

- Full `bot.sannysoft.com` detection table passes on every repo test
  run, including the WebDriver, Chrome, plugin-type, and WebGL rows.
- The fast path carries JA3/JA4 hashes distinct from plain `aiohttp`
  against the same TLS echo endpoint, proving real Chromium TLS.
- Steady-state fast-path overhead versus `aiohttp` is about 15-20ms
  per request; 20 concurrent requests on one context complete in
  about 2s against a 1s-delay endpoint, so nothing serializes.

## Hard limits

- Fast path negotiates HTTP/1.1 even against HTTP/2 servers. A
  detector cross-checking TLS fingerprint against protocol version
  can spot this. Renders are unaffected.
- No defense against IP reputation, rate limiting, or behavioural
  layers such as managed challenges. Those need clean IPs, proxies,
  warm sessions, and human-like pacing.
- Patches assume current Chromium defaults. Re-run the sannysoft
  regression test after any Playwright/Chromium version bump.

## Session warm-up

For guarded targets, solve the challenge once under a named session
and reuse its cookies from the fast path afterwards. Both directions
share the same underlying context, so warm-up and reuse compose in
either order.
