Skip to content

Browser Fingerprinting

The tracker script generates a stable browser fingerprint to identify returning visitors even without cookies.

Signals Used

The fingerprint is a SHA-256 hash of these combined signals:

SignalSource
User Agentnavigator.userAgent
Languagenavigator.language
Platformnavigator.platform
CPU Coresnavigator.hardwareConcurrency
Device Memorynavigator.deviceMemory
Screen Resolutionscreen.width × screen.height
Color Depthscreen.colorDepth
Pixel Ratiowindow.devicePixelRatio
Timezone OffsetDate().getTimezoneOffset()
CanvasRendered text/shapes → toDataURL()
WebGLUnmasked vendor + renderer strings
AudioOfflineAudioContext oscillator output sum

Persistence

  • Fingerprint is cached in localStorage under _pg_fp to avoid recalculation
  • Visitor ID (derived from fingerprint) is cached under _pg_vid
  • Private browsing mode is handled gracefully (fingerprint regenerated each session)

Identity Derivation

On the server side, identityService.ts derives stable IDs:

  • visitor_id = SHA-256("visitor:" + fingerprint_id) — same across all sessions
  • device_id = SHA-256("device:" + user_agent + "|" + fingerprint_id) — unique per browser+device

Identity Network

Each session start records the fingerprint → IP → ASN mapping in the identity_network D1 table. This builds a graph over time showing which fingerprints have been seen from which networks — useful for fraud detection and VPN identification.

D1 Record

The fingerprints table tracks per-fingerprint aggregates:

ColumnDescription
first_seenTimestamp of first observation
last_seenTimestamp of most recent session
total_sessionsCumulative session count
total_ipsDistinct IPs observed
total_asnsDistinct ASNs observed
vpn_suspectedVPN suspicion score