Repository navigation
Anti Fingerprinting
Modern bot-detection scripts (like F5, PerimeterX, or Cloudflare) don't just look at your IP or headers. They execute complex JavaScript to "fingerprint" your browser by checking:
- Hardware leaks: CPU cores, device memory, GPU renderer strings.
- Canvas/WebGL: Rendering unique pixels to identify your hardware.
- AudioContext: Analyzing how your sound card processes audio.
-
API behavior: Checking for
navigator.webdriveror inconsistent prototype chains.
osn-selenium provides a powerful module (javascript.fingerprint) to monitor these checks and spoof the results with high-entropy, realistic data.
The fingerprinting system is built on three pillars:
A massive internal map of over 200+ sensitive JavaScript APIs. It includes navigator properties, screen dimensions, Intl locale settings, webgl parameters, and audio nodes. Each entry defines:
-
Target: The object or prototype to hook (e.g.,
window.navigator). -
Method/Property: The specific attribute (e.g.,
userAgent). - Type: Whether it is a method, a property getter, or a constructor.
Rules define how a value should be modified. You can apply everything from static overrides to complex mathematical noise.
The framework generates a highly optimized JavaScript block that is injected into every document before any site scripts can execute (page.add_script_to_evaluate_on_new_document).
| Rule Type | Behavior | Best Use Case |
|---|---|---|
StaticItemSetRule |
Replaces a value with a fixed constant. | Overriding navigator.platform. |
RandomItemSetRule |
Picks a random value from a list or range. | Spoofing deviceMemory. |
StaticItemNoiseRule |
Adds or multiplies a fixed amount of noise. | Subtle modification of sensor data. |
RandomItemNoiseRule |
Injects randomized mathematical noise. | Canvas & Audio fingerprinting. |
ArrayNoiseRules |
Applies noise to data arrays (e.g., WebGL buffers). | Deep graphics protection. |
CustomRule |
Allows you to write raw JS logic for the hook. | Complex conditional logic. |
A common mistake in botting is having random values change every time a script calls them.
Most rules in osn-selenium support the persist=True flag. When enabled:
- A random value is generated the first time the site checks it.
- The value is saved in a session-wide internal storage.
- Every subsequent check by the site returns the exact same value, making the "human" identity appear consistent.
When used within the DevTools context, the library doesn't just spoof data—it watches the trackers.
-
Real-time Alerts: If a script tries to read a sensitive API (like
getImageDatafrom a Canvas), the browser sends a report back to Python. -
Detailed Logs: The
TargetLoggersaves these attempts intofingerprint_log.txt, including the specific API used and the JavaScript stacktrace of the calling script. -
Modes: You can set
detect_events_modeto"always","not_spoofed", or"disable".
from osn_selenium.javascript.fingerprint import FingerprintSettings
from osn_selenium.javascript.fingerprint.spoof.rules import StaticItemSetRule, RandomItemNoiseRule
from osn_selenium.javascript.fingerprint.spoof.noise import RandomNoise
from osn_selenium.javascript.fingerprint.registry.models import RegistryItem
from osn_selenium.webdrivers.trio_threads.chrome import ChromeWebDriver
from osn_selenium.dev_tools.settings import DevToolsSettings
# 1. Define custom stealth settings
stealth_cfg = FingerprintSettings(
optimize_events=True, # Don't spam the same log twice
registry={
# Override specific properties
"Navigator.hardwareConcurrency": RegistryItem(
target="window.navigator",
name="hardwareConcurrency",
api="navigator",
type="prop",
spoofing_rule=StaticItemSetRule(value=8)
),
# Add random noise to Canvas pixel data (Add +/- 0.001 to values)
"CanvasRenderingContext2D.getImageData": RegistryItem(
target="CanvasRenderingContext2D",
name="getImageData",
api="canvas",
type="method",
spoofing_rule=RandomItemNoiseRule(
value=RandomNoise(value=(-0.001, 0.001), operation="add"),
persist=True
)
)
}
)
# 2. Pass settings to the driver
# (In trio_threads mode, this happens automatically via DevTools)
driver = ChromeWebDriver(
webdriver_path="./chromedriver",
devtools_settings=DevToolsSettings(fingerprint_settings=stealth_cfg)
)