Saltar al contenido principal
en/blog/obscura/research/js-api-fingerprinting/

obscura/research/js-api-fingerprinting

3 min read

Overview

Browser JavaScript APIs expose a wide range of system and browser information. These signals can be intercepted and modified via JS injection at the proxy level.

API Vectors

Navigator API

Property Leaked Info Spoofable via JS
navigator.userAgent Browser/OS string Yes
navigator.platform OS platform Yes
navigator.language Primary language Yes
navigator.languages Language preferences Yes
navigator.hardwareConcurrency CPU core count Yes
navigator.deviceMemory RAM in GB Yes
navigator.maxTouchPoints Touch support Yes
navigator.webdriver Automation detection Yes
navigator.plugins Installed plugins Limited
navigator.mimeTypes MIME support Limited
navigator.cookieEnabled Cookie status Yes
navigator.doNotTrack Privacy preference Yes
navigator.pdfViewerEnabled PDF support Yes

Screen API

Property Leaked Info Spoofable via JS
screen.width Screen resolution Yes
screen.height Screen resolution Yes
screen.availWidth Available width Yes
screen.availTop Window position Yes
screen.colorDepth Color depth Yes
screen.pixelDepth Pixel depth Yes
screen.orientation Orientation Yes

Other APIs

API Leaked Info Spoofable via JS
Intl.DateTimeFormat().resolvedOptions().timeZone Timezone Yes
performance.now() Timer precision Yes (reduced)
Date.now() Clock skew Yes
navigator.connection Network type/RTT Yes
navigator.getBattery() Battery level Yes
navigator.mediaDevices Camera/mic count Yes

Spoofing Strategy

Via Injected JS

// Override navigator properties via Object.defineProperty
Object.defineProperty(navigator, 'userAgent', {
  get: () => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) ...'
})

Object.defineProperty(navigator, 'platform', {
  get: () => 'Win32'
})

Object.defineProperty(navigator, 'hardwareConcurrency', {
  get: () => 8
})

Challenges

  1. Timing: The injected script must execute before the page's own scripts. Requires injection at the very beginning of <head>.


  2. Frameworks: Some frameworks (Next.js, Angular) use SSR or inline scripts that run before injected JS.



  3. Service Workers: SWs can intercept and modify responses before the injection.


  4. Detection: A site can detect overrides by checking Object.getOwnPropertyDescriptor() or comparing multiple signals for inconsistencies.

Conclusions

  • ~25 JS API signals are spoofable via proxy JS injection
  • Requires careful injection at the HTML parse stage
  • Timing is critical (inject before any page script)
  • Cannot override all APIs (some are C++ backed in the browser)
  • Must maintain cross-signal consistency (e.g., Win32 platform + Windows User-Agent)