Skip to content

fingerprint

Fresh

Source: BIBLE.md (fingerprint-lite, fingerprint-store), bible/understand-everything.md (detection problem section)

Two core modules handle fingerprinting: fingerprint-lite.mjs (the runtime evasion) and fingerprint-store.mjs (per-account encrypted persistence).

fingerprint-lite.mjs

15-vector fingerprint evasion. Inherited from V1.

Vectors

VectorDetails
WebGLrenderer string, unmasked vendor
Canvasrendering noise per-account
AudioAudioContext fingerprint
Fontsenumerated font list
Pluginsplugins list
Screen1366x768 hard-lock
Timezonefrom geo
Languagefrom country
navigatoruserAgent, platform, vendor, hardwareConcurrency
Connectiondownlink, downlinkMax, effectiveType
MemorydeviceMemory
WebRTClocal IP leak protection
DNSleak protection via proxy
Batteryrandomized
Permissionsspoofed answers per origin

Screen lock

Screen size is hard-locked at 1366x768. This avoids Google's "Verify it's you" trigger from mismatched window vs screen sizes.

Source: core/fingerprint-lite.mjs, constant PHYSICAL_SCREEN = { width: 1366, height: 768 }.

randomizeFingerprint(email, os)

Deterministic per-account fingerprint variations:

  • CPU cores: 4, 8, or 16 (deterministic from email hash)
  • Device memory: 4, 8, or 16 GB
  • Connection downlink: realistic max
  • Device pixel ratio: from OS profile

Variations are deterministic so each account has a consistent fingerprint across launches.

fingerprint-store.mjs

Per-account encrypted fingerprint persistence.

Storage path: ./data/mini-engine-v2/fingerprints/{email-hash}.json

Encrypted with AES-256-GCM, keyed by email hash.

Encryption key: machine-derived by default, override with MINI_ENGINE_KEY.

Why "less is more"

V1's Golden 6 score went from ~70 to 98 of 100 by deleting 30 Chrome launch arguments down to 4. Adding flags makes detection easier, not harder.

The minimal launch arg list:

--disable-blink-features=AutomationControlled
--disable-features=IsolateOrigins,site-per-process,Translate
--no-default-browser-check
--no-first-run

No custom user-agent override. No --disable-web-security. No --use-fake-ui-for-media-stream.

The CreepJS fix

Do not use Object.defineProperty(navigator, 'webdriver', {get: () => undefined}). CreepJS detects the property tampering via lieProps['Navigator.webdriver'].

Use the Chrome flag instead: --disable-blink-features=AutomationControlled. This prevents Blink from setting navigator.webdriver=true at the C++ level. No JS patching needed, no lie detection triggered.

ContentIndex / ContactsManager stubs

Added to reduce CreepJS "like headless" from 25% to 6%:

  • ContentIndex stub
  • ContactsManager stub
  • navigator.connection.downlink set to realistic max

These APIs exist in real Chrome but are missing in Puppeteer's Chromium build.