A lightweight, self-hosted browser fingerprinting and bot detection library. Designed with real-world constraints in mind: anti-replay, payload encryption, optional obfuscation, and strong, low-noise signals.
Client-side detection of strong automation signals: navigator.webdriver, CDP markers, Playwright artifacts, Selenium properties, and more.
Short-lived fingerprint designed for attack detection, clustering, and session correlation. JA4-inspired structured fingerprint ID.
Optional payload encryption to prevent trivial forgery. The encryption key is injected at build time, not shipped in plaintext.
Optional obfuscation to raise the cost of reverse-engineering and make it harder to forge valid fingerprints without executing the code.
Detects inconsistencies across JavaScript execution contexts: main page, iframes, and web workers.
Built-in timestamp and nonce to prevent captured fingerprints from being replayed at scale.
| Detection | Signal | Frameworks |
|---|---|---|
| hasWebdriver | navigator.webdriver === true | Selenium, Puppeteer, Playwright |
| hasWebdriverWritable | webdriver property descriptor | Puppeteer, Playwright |
| hasSeleniumProperty | document.$cdc_, $wdc_ | Selenium WebDriver |
| hasCDP | CDP runtime markers | Chrome DevTools Protocol |
| hasPlaywright | __playwright, __pw_* | Playwright |
| hasWebdriverIframe | webdriver in iframe context | Cross-context bots |
| hasWebdriverWorker | webdriver in web worker | Cross-context bots |
The fsid is a JA4-inspired, locality-preserving fingerprint identifier.
Unlike a simple hash, it is structured into semantic sections, making it both
human-readable and useful for partial matching, similarity detection, and clustering.
See FPScanner in action. The demo collects your browser fingerprint, sends the encrypted payload to the server for decryption, and displays the full results.
Run the Live Demo