fix: id.sky.com tab crash on Windows headless=True (issue #18)

Two-part fix for the wrapper-repo issue #18 (tab crash on id.sky.com
and similar sites with cross-process navigation):

Part 1 (this commit, wrapper-side):
- _WIN_VIRT_DESKTOP_WORKAROUNDS adds security.sandbox.content.level=4.
  When the Chromium sandbox runs at content level >4 (default 6) it sets
  STARTUPINFO.lpDesktop=kAlternateWinstation for the content process,
  putting it on a different desktop than the browser process. Combined
  with our hidden alt-desktop (CreateDesktop) for headless windows
  hiding, that means cross-process navigations (Adobe AppMeasurement
  triggers a new origin -> new content process) can't reparent windows
  across desktops; the new content process exits cleanly and Playwright
  fires page.on('crash'). Lowering content sandbox to 4 keeps content
  processes on the parent's desktop. Level 4 still blocks file/registry/
  network access; only the alt-winstation isolation is dropped, which
  is what the desktop bug requires.
- README.md adds a Known Issues section pointing at issue #18 with
  the workaround (headless=False or Linux+Xvfb) for users on wrapper
  versions before firefox-7.

Part 2 (separate commit in invisible-firefox@2e17b4871f93):
- CanvasRenderingContext2D::GetImageDataArray moved the stealth pixel
  noise from rawData.mData (read-only DataSourceSurface::Map) to the
  JS Uint8ClampedArray's backing buffer. The original write to a
  read-only mapped surface segfaulted on GPU-backed canvases during
  browser.close() teardown.

Verified end-to-end with InvisiblePlaywright headless=True + Evomi UK
proxy on id.sky.com: page survives, no crash in loop, no crash at
teardown.

Reporter: @gamefireat123-eng.
This commit is contained in:
feder-cr 2026-05-21 20:20:58 -07:00
parent cf59e98fa9
commit 2e0adbde33
2 changed files with 33 additions and 0 deletions

View file

@ -203,6 +203,24 @@ invisible_playwright version # wrapper and binary versions
invisible_playwright clear-cache # remove all cached binaries
```
## Known issues
### `headless=True` on Windows can cause tab crashes on sites with heavy cross-process navigation
Reported as [#18](https://github.com/feder-cr/invisible_playwright/issues/18) (`id.sky.com` and similar). On Windows, `headless=True` runs Firefox headed on a hidden alt-desktop created via `CreateDesktop`. Some sites (id.sky.com, anything else loading Adobe AppMeasurement in a way that triggers cross-process navigation) end up firing `page.on('crash')` after about 10 seconds. The cause is a window-parenting interaction between the alt-desktop and the GPU/content processes; the workaround is one of:
```python
# Option A — keep the visible window (no alt-desktop)
with InvisiblePlaywright(seed=42, headless=False) as browser:
...
# Option B — run inside Xvfb on Linux (alt-desktop bug is Windows-only)
```
The visible window case works on every site we've tested. Linux + Xvfb is unaffected.
---
## Related projects
invisible_playwright takes a different angle than the major Firefox-hardening projects but stands on their shoulders:

View file

@ -384,6 +384,21 @@ _WIN_VIRT_DESKTOP_WORKAROUNDS: Dict[str, Any] = {
# Bugzilla refs: 1798091, 1524591, 1229829. Lowering the GPU sandbox to 0
# restores hardware compositor + functional WebGL on alt desktops.
"security.sandbox.gpu.level": 0,
# Same root cause as above, content process side. Wrapper repo issue #18
# (id.sky.com tab crash). Sandbox content level > 4 puts content processes
# on the sandbox's own kAlternateWinstation (see
# security/sandbox/win/src/sandboxbroker/sandboxBroker.cpp line 1113-1114:
# `if (aSandboxLevel > 4) config->SetDesktop(kAlternateWinstation)`).
# Combined with our CreateDesktop alt-desktop, that puts browser process
# and content processes on DIFFERENT desktops. Cross-process navigation
# (Adobe AppMeasurement → new origin → new content process on a new
# desktop) then fails window parenting between parent and child → content
# process exits cleanly (exitCode=0, signal=null) and Playwright fires
# page.on('crash') ~10s after page load. Lowering content sandbox to 4
# keeps content processes on the same desktop as the browser process,
# which is what we want here (and is still tight enough — level 4
# blocks file/registry write, network calls, hardware access).
"security.sandbox.content.level": 4,
}