Skip to content

Repository files navigation

ManagedCode.Playwright.Stealth (.NET)

ManagedCode.Playwright.Stealth applies a curated set of init scripts to Microsoft.Playwright contexts to reduce common bot-detection signals. It adapts the original playwright_stealth scripts for .NET with ManagedCode conventions.

Install

dotnet add package ManagedCode.Playwright.Stealth

Quick Start

usingMicrosoft.Playwright;usingManagedCode.Playwright.Stealth;usingvarplaywright=awaitPlaywright.CreateAsync();// One-call launch with stealth args + context pre-configured:var(browser,context)=awaitplaywright.Chromium.LaunchStealthAsync();varpage=awaitcontext.NewPageAsync();awaitpage.GotoAsync("https://www.browserscan.net/bot-detection");

Manual Setup

If you need more control over launch options:

usingvarplaywright=awaitPlaywright.CreateAsync();awaitusingvarbrowser=awaitplaywright.Chromium.LaunchAsync(newBrowserTypeLaunchOptions{Headless=true,Args=PlaywrightStealthExtensions.StealthArgs// recommended Chrome flags});varcontext=awaitbrowser.NewContextAsync();// Apply stealth before creating pages.awaitcontext.ApplyStealthAsync();varpage=awaitcontext.NewPageAsync();awaitpage.GotoAsync("https://www.browserscan.net/bot-detection");

Configuration

varconfig=newStealthConfig{NavigatorHardwareConcurrency=8,NavigatorDeviceMemory=16,NavigatorMaxTouchPoints=1,NavigatorUserAgentValue="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",Vendor="Intel Inc.",Renderer="Intel Iris OpenGL Engine"};awaitcontext.ApplyStealthAsync(config);

Apply stealth on a page (if you already have a page instance):

varpage=awaitcontext.NewPageAsync();awaitpage.ApplyStealthAsync();awaitpage.GotoAsync("https://www.browserscan.net/bot-detection");

Disable individual patches:

varconfig=newStealthConfig{WebDriver=false,WebglVendor=false,CanvasFingerprint=false,AudioContext=false,PerformanceJitter=false};awaitcontext.ApplyStealthAsync(config);

Patched Signals

The configuration can patch 31 detection vectors across these categories. Defaults preserve native navigator values where current Chromium already exposes a normal value.

Navigator Properties

PatchDescriptionConfig
navigator.webdriverReturns false instead of trueWebDriver
navigator.plugins / mimeTypesFake plugin array (Chrome PDF Plugin, etc.)NavigatorPlugins
navigator.languagesPreserves native values by default; configurable language array when suppliedNavigatorLanguages
navigator.userAgentStrips headless markers from UA stringNavigatorUserAgent
navigator.vendorPreserves native value when already "Google Inc."; configurable otherwiseNavigatorVendor
navigator.platformConfigurable platform stringNavigatorPlatform
navigator.hardwareConcurrencyPreserves native value by default; configurable CPU core count when suppliedNavigatorHardwareConcurrency
navigator.deviceMemoryPreserves native value by default; configurable device memory in GB when suppliedNavigatorDeviceMemory
navigator.connectionPreserves native value when present; mocks NetworkInformation when missingNavigatorConnection
navigator.permissionsNormalizes Notification permission stateNavigatorPermissions
navigator.maxTouchPointsPreserves native value by default; configurable touch point count when suppliedNavigatorMaxTouchPoints
navigator.pdfViewerEnabledPreserves native value when present; mocks it when missingNavigatorPdfViewer

Chrome APIs

PatchDescriptionConfig
window.chrome / chrome.runtimeFull Chrome extension API mockChromeRuntime
chrome.appChrome App API mockChromeApp
chrome.csiChrome CSI timing mockChromeCsi
chrome.loadTimesPreserves the native headful API when present; mocks it when missingChromeLoadTimes

Graphics & Rendering

PatchDescriptionConfig
WebGL vendor/rendererSpoofs UNMASKED and standard WebGL params; hides ANGLE/SwiftShaderWebglVendor
Canvas fingerprintAdds session-stable noise to canvas renderingCanvasFingerprint
Broken image dimensionsFixes 16x16 headless artifact to 0x0BrokenImage

Audio & Media

PatchDescriptionConfig
AudioContext fingerprintAdds noise to audio frequency/channel dataAudioContext
Media codecsCorrect codec support responsesMediaCodecs
Speech synthesisMock voice list for getVoices()SpeechSynthesis

Window & Screen

PatchDescriptionConfig
window.outerWidth/HeightRealistic outer dimensionsOuterDimensions
screen.* dimensionsConsistent screen width/height/colorDepthScreenDimensions

Anti-Detection & Timing

PatchDescriptionConfig
CDP detectionMasks Chrome DevTools Protocol tracesCdpDetection
Automation propertiesRemoves cdc_*, $cdc_*, domAutomationControllerAutomationProperties
Performance jitterAdds realistic timing noise to performance.now() and requestAnimationFramePerformanceJitter

DOM & Internals

PatchDescriptionConfig
iframe contentWindowFixes iframe proxy behaviorIframeContentWindow
Hairline detectionFixes Modernizr offsetHeight checkHairline

Public API

Extension Methods

// Apply to browser context (recommended)awaitcontext.ApplyStealthAsync();awaitcontext.ApplyStealthAsync(customConfig);// Apply to individual pageawaitpage.ApplyStealthAsync();awaitpage.ApplyStealthAsync(customConfig);// One-call launch with stealth pre-configuredvar(browser,context)=awaitplaywright.Chromium.LaunchStealthAsync();var(browser,context)=awaitplaywright.Chromium.LaunchStealthAsync(config,launchOptions,contextOptions);

Stealth Chrome Arguments

// Access recommended Chrome args for manual launch setupstring[]args=PlaywrightStealthExtensions.StealthArgs;

Configuration Reference

Toggle Options (bool)

WebDriver, WebglVendor, ChromeApp, ChromeCsi, ChromeLoadTimes, ChromeRuntime, IframeContentWindow, MediaCodecs, Hairline, OuterDimensions, NavigatorLanguages, NavigatorPermissions, NavigatorPlatform, NavigatorPlugins, NavigatorUserAgent, NavigatorVendor, NavigatorConnection, NavigatorPdfViewer, BrokenImage, SpeechSynthesis, ScreenDimensions, CdpDetection, AutomationProperties, CanvasFingerprint, PerformanceJitter, AudioContext

Numeric Options (int)

  • NavigatorHardwareConcurrency (default: 0 to preserve native value, set >0 to spoof)
  • NavigatorDeviceMemory (default: 0 to preserve native value, set >0 to spoof)
  • NavigatorMaxTouchPoints (default: -1 to preserve native value, set >=0 to spoof)

String Options

  • NavigatorUserAgentValue - Custom user agent string
  • NavigatorPlatformValue - Custom platform (e.g., "Win32")
  • NavigatorVendorValue - Vendor name (default: "Google Inc.")
  • Vendor - WebGL vendor (default: "Intel Inc.")
  • Renderer - WebGL renderer (default: "Intel Iris OpenGL Engine")
  • Languages - Language array (default: empty to preserve native values)
  • RunOnInsecureOrigins - Allow stealth on http:// origins

Testing

Integration tests target 9 bot-detection sites:

These sites can change at any time. If a site changes, update the corresponding test assertions.

Run tests (Playwright browsers install automatically on first run):

dotnet test --solution ManagedCode.Playwright.Stealth.slnx -c Release

On Linux CI runners, set PLAYWRIGHT_INSTALL_DEPS=1 to install system dependencies (playwright install --with-deps) when tests start.

Google search verification is optional (Google may block automated traffic). Enable it with:

RUN_GOOGLE_SEARCH_TESTS=1 dotnet test --solution ManagedCode.Playwright.Stealth.slnx -c Release

Attribution

This project uses code from the original playwright_stealth repository and adapts it for .NET: https://github.com/AtuboDad/playwright_stealth

License

MIT. See LICENSE.

About

Stealth evasion library for Microsoft.Playwright (.NET). Applies 31 init-script patches that mask headless Chrome fingerprints — navigator properties, WebGL, canvas, audio, CDP traces, automation markers and more. Validated against 9 public bot-detection sites.

Topics

Resources

Stars

7 stars

Watchers

1 watching

Forks

Releases

Used by

Contributors

Languages