| Surface | Hooked API | Mitigation |
|---|---|---|
| 2D Canvas | HTMLCanvasElement.toDataURL, toBlob |
Shifts exported RGB channel values deterministically per navigation seed before encoding |
| WebGL GPU | WebGLRenderingContext, WebGL2RenderingContext |
Masks unmasked vendor (0x9245) and renderer (0x9246) strings and perturbs float vertex buffers |
| Web Audio PCM | AudioBuffer.prototype.getChannelData |
Applies deterministic sub-audible sample offsets (±5e-8) across channel buffers |
| DOM Bounding Boxes | Element / Range getBoundingClientRect |
Adds sub-pixel micro-offsets (1e-5..9e-5 px) while preserving native DOMRect instances |
| Font Metrics | HTMLElement.prototype.offsetWidth, offsetHeight |
Alters layout readouts once rapid font-probing thresholds (> 300 queries) are reached |
| Viewport Geometry | window.screen.availHeight |
Derives a session-scoped pixel offset from the active viewport width |
| CPU Concurrency | Navigator.prototype.hardwareConcurrency |
Clamps reported logical processor counts to standard buckets (2, 4, 8) |
| Media Enumeration | MediaDevices.prototype.enumerateDevices |
Scrubs hardware label, deviceId, and groupId fields from returned descriptors |
| Battery Telemetry | Navigator.prototype.getBattery |
Resolves a static full-charge stub (level: 1, charging: true) |
| Browser Plugins | Navigator.prototype.plugins |
Returns a frozen empty plugin collection (length: 0) |
| HID Gamepads | Navigator.prototype.getGamepads |
Returns a frozen empty controller array |
| WebRTC Peers | window.RTCPeerConnection |
Wraps peer connection construction via Proxy and records origin telemetry |
- Clone the repository:
git clone https://github.com/rizzn/SpecterJS.git
- Open
chrome://extensions/in any Chromium browser and enable Developer mode. - Click Load unpacked and select the
extension/folder.
Licensed under the Apache License, Version 2.0 (LICENSE).
