What it does
FingerprintJS reads what the browser reports. Benny measures what the hardware does.
Every signal it collects is tagged either hardware-bound (properties of the physical device and OS, stable across Chrome, Safari, Firefox, and Brave on the same machine) or engine-bound (properties of how the browser engine processes or renders content, differing between engines even on identical hardware). That split is the wedge.
Two fingerprints, one collection pass
| Field | Source | Stable across browsers? | Use it for |
|---|---|---|---|
| fingerprint | All 26 signals fused | No. Engine signals differ per browser | Recognising a returning user in the same browser |
| hardwareFingerprint | 6 hardware signals fused | Yes | Cross-browser device matching, MFA, anti-fraud, license enforcement |
The 26 signals at a glance
Seventeen signals run by default (tier 1). Seven more are opt-in for broader coverage (tier 2). Two are niche, low-entropy (tier 3).
Signal catalogue
| # | Signal | Binding | Tier | Added |
|---|---|---|---|---|
| 1 | audio | engine | 1 | 1.0.0 |
| 2 | canvas | engine | 1 | 1.0.0 |
| 3 | webgl_gpu_identity | hardware | 1 | 1.0.0 |
| 4 | webgl_params | engine | 1 | 1.0.0 |
| 5 | screen | engine | 1 | 1.0.0 |
| 6 | platform | hardware | 1 | 1.0.0 |
| 7 | timezone | hardware | 1 | 1.0.0 |
| 8 | fonts | hardware | 1 | 1.0.0 |
| 9 | math | engine | 1 | 1.0.0 |
| 10 | css_probe | engine | 2 | 1.0.0 |
| 11 | media_devices | hardware | 2 | 1.0.0 |
| 12 | webgl_gpu_trace | engine | 2 | 1.0.0 |
| 13 | webgpu | engine | 2 | 1.0.0 |
| 14 | speech_voices | engine | 3 | 1.0.0 |
| 15 | storage_quota | engine | 3 | 1.0.0 |
| 16 | architecture | hardware | 1 | 1.5.0 |
| 17 | apple_pay | engine | 1 | 1.5.0 |
| 18 | audio_base_latency | engine | 1 | 1.6.0 |
| 19 | screen_frame | engine | 1 | 1.6.0 |
| 20 | js_heap_size_limit | engine | 1 | 1.7.0 |
| 21 | font_preferences | engine | 1 | 1.7.0 |
| 22 | webgl_pixel_readback | engine | 2 | 1.8.0 |
| 23 | user_agent_data | engine | 1 | 1.9.0 |
| 24 | error_stack_engine | engine | 1 | 1.19.0 |
| 25 | permissions | engine | 2 | 1.21.0 |
| 26 | webrtc_sdp | engine | 2 | 1.23.0 |
Three independent risk tracks
Every result includes three scoring blocks that should be reasoned about independently, because the evidence sets barely overlap. Consistency catches anti-detect browsers that spoof signals to look like a real human (Consistency flags feeding spoofLikelihood). Automation catches drivers like Puppeteer, Playwright, and Selenium that just want to work (Automation flags feeding automationLikelihood). Incognito is informational only. Private browsing is a legitimate feature, not evidence of fraud (Incognito flags feeding incognitoLikelihood).
Consistency flags
Consistency flags cover cross-signal contradiction checks (e.g. WebGL renderer OS string vs. navigator.platform, installed fonts vs. reported OS), per-call noise detection (canvas, WebGL, audio), UA cross-checks, and browser-specific suppression patterns such as Brave farbling and Firefox resistFingerprinting. A subset of flags feeds directly into the spoofLikelihood computation; others are informational. Illustrative examples: canvas_noise_uniform (canvas noise is uniformly +-1, an anti-detect tool pattern) and brave_shields_active (Brave per-eTLD+1 farbling signature detected, auto-suppressed from spoofLikelihood for real Brave users).
Native Android & iOS
Benny ships native Android and iOS SDKs alongside the web library. They run the same fusion algorithm over the same hardware-bound signals, so a native app produces a hardwareFingerprint comparable to the one the web library produces for the same physical device. The result is cross-surface device matching: recognising that a browser visit and a native-app session came from the same hardware, with no manual identity stitching by the developer.
The Android SDK is available now on Maven Central (requires minSdk 24). Beyond the cross-surface fingerprint it adds mobile-native capabilities with no web equivalent: tamper and emulator detection, hardware-backed attestation, and a reinstall-persistent device ID. The iOS SDK is in preview — reach out for early access.
repositories {
mavenCentral()
}
dependencies {
implementation("io.github.miri-san-so:doorman-benny:0.1.0")
}Android — app build.gradle.kts (transitive dependencies resolve automatically)
Where to go next
Read Install & Quick Start to ship the library in five minutes. Read Configuration for tier / timeout / exclude options. Browse the API Reference for the four public functions. Open any Signal page to see exactly what is collected, how it is hashed, and which anti-fingerprinting tools defeat it.
Last reviewed 2026-06-18

