Category: Hardware / Processor Architecture
1. Description
CPU fingerprinting measures characteristics of the processor and platform that are exposed through JavaScript and WebAssembly. These signals derive from:
- Floating-point unit (FPU) behavior
- CPU instruction set extensions (SIMD, AES-NI, AVX, BMI, POPCNT)
- Cache hierarchy and timing
performance.now()resolution (hardware timer)- WebAssembly execution speed (relative benchmark)
2. Vectors
2.1 Math / FPU Fingerprinting
// Floating-point precision differences
function mathFingerprint() {
const inputs = [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0]
return inputs.map(x => {
// Operations that expose precision differences
return Math.sin(x) * Math.cos(x) + Math.tan(x) - Math.asin(x) * Math.atan(x)
}).join(',')
}
// Different CPUs produce subtly different results
Entropy: ~4-6 bits
Stability: Very High CPU FPU behavior is fixed
Mechanism: IEEE 754 compliance varies slightly between CPU vendors and models. Fused multiply-add (FMA) instructions produce different results than separate multiply+add operations.
2.2 WebAssembly Feature Detection
// Wasm module that tests CPU feature support
const wasmCode = new Uint8Array([
0x00, 0x61, 0x73, 0x6d, // magic
0x01, 0x00, 0x00, 0x00, // version
// ... SIMD, AES-NI detection via wasm instructions
])
const module = await WebAssembly.instantiate(wasmCode)
const result = module.instance.exports.test()
Detectable features:
- SIMD (128-bit vector instructions)
- Sign extension operations
- Mutable globals
- Bulk memory operations
- Reference types
- Tail calls
- Fixed-width SIMD
Entropy: ~8-12 bits (which features are supported)
Stability: Very High CPU features are fixed
2.3 Performance.now() Resolution
// Measure timer resolution
const t1 = performance.now()
const t2 = performance.now()
const resolution = t2 - t1 // Minimum measurable interval
Entropy: ~2-3 bits
Stability: Moderate OS and browser can change resolution
2.4 WebAssembly Benchmarking
// Relative CPU speed benchmark
const start = performance.now()
// Run CPU-intensive wasm code
const elapsed = performance.now() - start
// Relative speed is identifying
Entropy: ~4-8 bits
Stability: Low-Moderate affected by CPU throttling, background processes, power management
3. Attacker's Strengths
| Strength | Explanation |
|---|---|
| Hardware-locked | CPU features cannot be changed without replacing hardware |
| Wasm is fast | Feature detection in <1ms |
| No permissions needed | Wasm and Math APIs require no user consent |
| Cross-browser | Same CPU produces similar fingerprints across browsers |
| Passive | No user interaction required |
4. Attacker's Weaknesses
| Strength | Explanation |
|---|---|
| Low entropy per vector | Math fingerprint alone is insufficient |
| Browser reduces timer precision | performance.now() resolution is intentionally reduced |
| Wasm can be blocked | Browser settings can disable WebAssembly |
| Benchmark variance | CPU throttling makes measurements noisy |
| Groups users by CPU class | All users with same CPU look the same |
5. Detection of Tampering
| Technique | How It Works |
|---|---|
| Math result comparison | Overridden Math methods return suspicious values |
| Wasm execution time | Blocked Wasm is detectable (instantiation fails) |
| Timer resolution | Unusually round resolution suggests override |
6. Mitigations for Obscura
6.1 What Obscura Can Do
| Mitigation | Effectiveness | Detectability | Implementation |
|---|---|---|---|
Override performance.now() precision |
Low | Low | Round to 100ms |
| Block Wasm entirely | High | Medium | JS: WebAssembly undefined |
Override hardwareConcurrency |
High | Low | JS injection (already in controllable list) |
Override deviceMemory |
High | Low | JS injection (already in controllable list) |
6.2 What Obscura Cannot Do
| Cannot | Why |
|---|---|
| Change FPU behavior | CPU hardware executes instructions directly |
| Prevent Wasm CPU detection | Wasm runs natively, proxy cannot intercept |
| Normalize execution speed | CPU speed is physical |
| Remove timing side channels | Any JS execution reveals timing |
6.3 Recommended Approach
1. Override hardwareConcurrency + deviceMemory (already planned)
2. Override performance.now() precision (low effort, partial benefit)
3. Accept math FPU + Wasm CPU detection (low individual entropy)
7. Research References
- Mowery, K. et al. (2011). "Are These Your Keys? Using Cryptographic Fingerprints to Detect Malicious Applets." IEEE S&P 2011.
- Mulazzani, M. et al. (2013). "Fast and Reliable Browser Fingerprinting." ACSAC 2013.
- Olejnik, L. et al. (2015). "The Web Never Forgets: Persistent Tracking Mechanisms in the Wild." CCS 2014 (CPU timing section).