← All tests

Incognito Detection via Timing Side-Channels

Three methods that exploit timing differences between disk-backed (normal) and in-memory (private/incognito) storage to detect browsing mode. In normal mode, operations that flush to disk are measurably slower. In incognito mode, all storage is in-memory, so these operations complete much faster.

How to use: Run each method individually. Compare verdicts between a normal window and a private window.

Reported by @1Jesper1 in brave-browser#56009. Original detection techniques from crbug.com/515090580.

Method 1: IndexedDB Strict/Relaxed Pair Ratio

Writes 4 KB to IndexedDB with durability: "strict" (fsync to disk) and durability: "relaxed" (OS buffer only), then computes the ratio of strict-to-relaxed write times. In normal mode the ratio is high (>2.0) because strict actually flushes. In incognito, both are in-memory so the ratio approaches 1.0.

Thresholds: ratio < 1.20 = incognito, ratio > 2.00 = normal, otherwise neutral.

Method 2: OPFS SyncAccessHandle Flush Timing

Uses a Web Worker with the Origin Private File System to write 512 KB chunks and measure flush() latency. In normal mode, flush forces data to disk (>0.80 ms). In incognito, storage is in-memory so flush is nearly instant (<0.05 ms).

Thresholds: median flush < 0.05 ms = incognito, > 0.80 ms = normal, otherwise neutral.

Method 3: CacheStorage Open Timing

Opens and immediately deletes CacheStorage entries in sequential bursts, measuring the per-operation cost. In normal mode, cache operations use a disk-backed backend (slower). In incognito, the backend is entirely in-memory (faster). Two burst sizes: single (6 ops) and batch (18 ops), each sampled 3 times.

Thresholds: ms/op < 0.35 = incognito, ms/op > 0.45 = normal, otherwise neutral.