The Incognito Placebo: 30 Lines of JS Extract a Hardware Fingerprint That Survives Private Windows and Proxy IPs
Is the browser's "incognito mode" the biggest placebo of our time? I extracted a hardware fingerprint with 30 lines of JS, and I can still pinpoint you across networks and proxies.
In the subconscious of all modern internet users, there is a "digital invisibility cloak" that has been worshipped for nearly two decades:
The browser's "incognito mode" (Incognito / InPrivate / private browsing).
When you press Ctrl + Shift + N in Chrome, Safari, Edge, or various domestic dual-core browsers (on Mac it's Cmd + Shift + N), the bright and clean interface instantly switches to a mysterious dark gray-black tone, often with a stylized spy icon wearing sunglasses and a lowered trench coat collar.
Under the protection of this dark interface, countless people develop a nearly superstitious sense of psychological security:
- At night, hiding under the covers watching "unmentionable movies" or special sites, the first instinct to avoid tomorrow's history records is to deftly press the incognito shortcut;
- When quietly searching private topics, even sensitive conditions that are hard to mention, incognito is on;
- When buying plane tickets or booking hotels to avoid platform big-data price discrimination, incognito is on;
- When switching to a secondary account to browse forums and post controversial opinions you wouldn't normally say, incognito is on;
- Even when logging into a personal account on a public computer at an internet cafe or a borrowed device, you think that simply closing the incognito window is enough to "walk away without a trace, hiding your glory."
"I've turned on incognito mode, all cookies are cleared, history is gone. How could a website know who I am?"
Yet this is the most widespread and self-deceiving technical placebo on the modern internet.
It's like walking into a fully transparent glass room, casually turning off your own small flashlight, and naively believing the whole world outside the glass room can't see you.
In 2024, Google officially settled a massive class-action lawsuit that lasted nearly four years (Brown v. Google LLC), not only updating the official disclaimer for Chrome's incognito mode globally but also promising to destroy tens of billions of "private browsing data" collected during incognito sessions.
But did the underlying tracking technology stop after the lawsuit?
Not at all.
Today, in the lab of Station 404, we refuse empty conceptual debates. We'll use real code and the underlying mechanisms of browsers to tell you directly: Why what you think is invisibility is, in the eyes of modern websites and ad tracking systems, not even the "Emperor's New Clothes."
We use only 30 lines of pure front-end JavaScript, without requesting any system permissions or writing any local cookies, to instantly extract the unique "hardware digital fingerprint" at the bottom of your device. Even if you turn on incognito, close the browser, or even switch a global proxy IP, the backend algorithm can pull you out of the sea of humanity in 5 milliseconds.
1. What exactly does incognito mode protect against? The harsh truth the official docs never tell you
To understand why incognito mode can't block tracking, we first need to give it a "proper name": figure out what problem browser vendors originally intended it to solve.
Opening the kernel specifications of any mainstream browser (W3C RFC and Chromium source), the physical definition of incognito mode is extremely straightforward and narrow:
┌────────────────────────────────────────────────────────────────────────┐
│ 【Normal vs Incognito Mode in Modern Browsers】 │
│ │
│ [ Normal Window Session ] │
│ ├── Disk Cache ──────────────► Permanently stores images, JS, CSS │
│ ├── State Persistence (Cookie / Storage) ──► Long-term login tokens, preferences │
│ └── History Database ─────────► Permanently records every URL │
│ │
│ [ Incognito Window Session ] │
│ ├── Memory Sandbox ──────────► Closing the window destroys in-memory cookies │
│ ├── History not written to disk ──► Local History DB gets no new entries │
│ └── Core flaw ────────────────► Hardware APIs and network stack exposed to the outside are 100% identical │
│ │
│ 【Conclusion】: Incognito mode protects against "the roommate/spouse/colleague behind you", not "the website across the wire". │
└────────────────────────────────────────────────────────────────────────┘
Everything incognito mode does happens entirely inside your local device:
- It creates a temporary sandbox in memory; when the window closes, it discards any temp cookies, localStorage, and sessionStorage.
- It does not write browsing history or form autofill data to the local SQLite database.
In other words: The sole purpose of incognito mode is to prevent a colleague or partner who borrows your computer the next day from seeing what you searched yesterday.
But network communication is never a single-player game. The moment you press Enter, every mouse movement, every network handshake, every frame of image rendering is continuously sending to the target server enough hardware traits to sketch your digital skeleton.
In the traditional era, websites recognized you by placing a "small note" (Cookie) in your computer; you tore up the note (turned on incognito) and thought the other party wouldn't recognize you.
But modern industrial-grade risk-control and ad-tracking systems have long evolved to the stage of "recognizing people by their body." You can change your clothes or tear off your name badge, but your fingerprint, pupils, gait, and bone proportions are still permanently welded to your body.
This is the overwhelming weapon of modern tracking: Device Fingerprinting.
2. Extracting a hardware fingerprint in 30 lines of JS: the astonishing match between incognito and normal windows
To verify the power of device fingerprints, we set up a minimal fingerprint probe locally. No need to install any heavy third-party libraries or hacking tools—just using the public, legal, and even unkillable graphics and audio APIs in modern HTML5:
<!DOCTYPE html>
<html>
<head><meta charset="utf-8"><title>404 Workstation Hardware Fingerprint Test</title></head>
<body>
<div id="output"></div>
<script>
async function getHardwareFingerprint() {
const traits = {};
// 1. Canvas 2D rendering pipeline microscopic pixel fingerprint
const canvas = document.createElement('canvas');
canvas.width = 280; canvas.height = 60;
const ctx = canvas.getContext('2d');
ctx.textBaseline = 'top';
ctx.font = "14px 'Arial', 'Helvetica', 'Times New Roman', sans-serif";
ctx.fillStyle = "#f60";
ctx.fillRect(125, 1, 62, 20);
ctx.fillStyle = "#069";
ctx.fillText("Station404: 🤖, i18n & \ud83d\ude03", 2, 15);
ctx.fillStyle = "rgba(102, 204, 0, 0.7)";
ctx.fillText("Station404: 🤖, i18n & \ud83d\ude03", 4, 17);
const dataURI = canvas.toDataURL();
// Compute Canvas physical render hash
let hash = 0;
for (let i = 0; i < dataURI.length; i++) {
hash = ((hash << 5) - hash) + dataURI.charCodeAt(i);
hash |= 0;
}
traits.canvasHash = '0x' + (hash >>> 0).toString(16);
// 2. WebGL physical GPU hardware direct read
const gl = canvas.getContext('webgl') || canvas.getContext('experimental-webgl');
const debugInfo = gl.getExtension('WEBGL_debug_renderer_info');
traits.gpuVendor = gl.getParameter(debugInfo.UNMASKED_VENDOR_WEBGL);
traits.gpuRenderer = gl.getParameter(debugInfo.UNMASKED_RENDERER_WEBGL);
// 3. AudioContext sound card floating-point processing fingerprint
const audioCtx = new (window.OfflineAudioContext || window.webkitOfflineAudioContext)(1, 44100, 44100);
const osc = audioCtx.createOscillator();
const comp = audioCtx.createDynamicsCompressor();
osc.type = 'triangle'; osc.frequency.setValueAtTime(10000, audioCtx.currentTime);
comp.threshold.setValueAtTime(-50, audioCtx.currentTime);
osc.connect(comp); comp.connect(audioCtx.destination); osc.start(0);
const rendered = await audioCtx.startRendering();
const samples = rendered.getChannelData(0);
let audioSum = 0;
for (let i = 4500; i < 5000; i++) audioSum += Math.abs(samples[i]);
traits.audioFingerprint = audioSum.toFixed(8);
// 4. System environment parameters
traits.cpuCores = navigator.hardwareConcurrency;
traits.ramGB = navigator.deviceMemory || 'N/A';
traits.screen = `${screen.width}x${screen.height}x${screen.colorDepth}`;
traits.timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
document.getElementById('output').innerText = JSON.stringify(traits, null, 2);
}
window.onload = getHardwareFingerprint;
</script>
</body>
</html>
We deployed this code in a test environment. First, we opened the page with Chrome in normal mode and recorded the captured data; then we pressed the shortcut to open a completely separate incognito window and opened it again.
The console-printed results are enough to shatter all illusions about incognito mode:
/* 【Normal window results】 */
{
"canvasHash": "0x244f4e0d",
"gpuVendor": "Google Inc. (Apple)",
"gpuRenderer": "ANGLE (Apple, ANGLE Metal Renderer: Apple M4, Unspecified Version)",
"audioFingerprint": "124.04347480",
"cpuCores": 10,
"ramGB": 16,
"screen": "1512x982x24",
"timezone": "Asia/Shanghai"
}
/* 【Incognito window results】 */
{
"canvasHash": "0x244f4e0d",
"gpuVendor": "Google Inc. (Apple)",
"gpuRenderer": "ANGLE (Apple, ANGLE Metal Renderer: Apple M4, Unspecified Version)",
"audioFingerprint": "124.04347480",
"cpuCores": 10,
"ramGB": 16,
"screen": "1512x982x24",
"timezone": "Asia/Shanghai"
}
From canvasHash to audioFingerprint, from the real GPU chip to floating-point audio features, every bit, every hex character, is 100% identical!
You think you've changed to a clean, new identity, but in the server-side fingerprint matching algorithm:
0x244f4e0d hits 0x244f4e0d, costing 0.1 milliseconds.
The backend tracking engine doesn't even need to care whether you have a cookie; the cold database behind the screen just logs a line:[INFO] Hit known device fingerprint ID: DEV_404_M4_9A2F, current session automatically linked to user: 10404.
Many people might be stunned by the audioFingerprint above:
"My computer has earbuds plugged in and muted, not a sound. How can the page measure my 'voiceprint'?"
This is the chilling part of modern Web APIs: It doesn't need you to turn on the microphone, nor does it need you to play audio.
This code virtually generates a 10,000 Hz high-frequency wave deep in the browser's memory using pure math, then commands the CPU to compute the dynamic compression and attenuation values when that wave passes through a virtual filter. Because each processor's microarchitecture has extremely subtle physical precision differences when handling microsecond-level floating-point operations, this purely algorithm-derived number is the unique "digital birthmark" welded inside your chip!
3. Under the hood: why does the hardware fingerprint not change even one bit?
Many people will wonder: since incognito mode resets everything, why can the Canvas image hash lock across windows?
The answer lies in the physical layers of computer graphics and hardware manufacturing.
1. Canvas 2D fingerprint: nanoscale rasterization differences
When the browser executes ctx.fillText("Station404: 🤖", 2, 15), it looks like it's just drawing a few characters and an emoji on screen. But to turn vector text into pixels, the OS and hardware go through an extremely complex relay:
┌────────────────────────────────────────────────────────────────────────┐
│ 【Canvas fingerprint generation path】 │
│ │
│ JavaScript drawing command: ctx.fillText() │
│ │ │
│ ▼ │
│ [ OS font rasterization engine ] │
│ ├── macOS: CoreText (smoothing, anti-aliasing, color weighting) │
│ ├── Windows: DirectWrite / ClearType (sub-pixel anti-aliasing) │
│ └── Linux: FreeType (glyph outline interpolation) │
│ │ │
│ ▼ │
│ [ Graphics intermediate abstraction layer ] │
│ └── Google ANGLE (translates OpenGL to Metal / DirectX / Vulkan) │
│ │ │
│ ▼ │
│ [ Physical GPU shader and driver ] │
│ └── Apple M4 / NVIDIA RTX 4070 / Intel Iris │
│ (float rounding rules, texture rasterization units, microarch differences) │
│ │ │
│ ▼ │
│ Final pixel array (Base64 export) ──► generates globally unique hash: 0x244f4e0d │
└────────────────────────────────────────────────────────────────────────┘
"Rasterization" sounds like high-sounding jargon. Here's an analogy: It's like having three calligraphers from different schools copy the same Chinese character from the same model.
Even if you give them exactly the same model, each calligrapher's wrist bone structure and stroke force habits differ. Under a 1000x microscope, the microscopic burrs and ink spreading at the edges of the ink will absolutely not be identical:
- macOS's brush (
CoreText) pursues rounded, elegant, soft rendering; - Windows's pen (
DirectWrite) likes to use sub-pixel anti-aliasing to force clean edges for ordinary displays; - Linux's plotter (
FreeType) has yet another unique vector outline interpolation algorithm.
Add your physical GPU (Apple Silicon or NVIDIA CUDA) with its microscopic nanosecond-level deviations in floating-point rounding at the transistor level, and in the tens of thousands of pixels, if even a single pixel's RGB differs by 1/255, after the hash algorithm amplifies it, the resulting hash becomes a unique "machine palm print" in the whole world!
And every time you open an incognito window, your computer's M4 chip doesn't become a Qualcomm Snapdragon, and your macOS certainly doesn't become Windows. Hardware and drivers are physical objects; they don't change with a software "incognito switch."
2. WebGL interface: directly stripping off the GPU's disguise
In the code above, there is a highly lethal line:
const debugInfo = gl.getExtension('WEBGL_debug_renderer_info');
const gpu = gl.getParameter(debugInfo.UNMASKED_RENDERER_WEBGL);
In normal web browsing, browsers almost completely hand over your physical GPU model to the webpage:
- If you're on a Mac, the page directly gets:
ANGLE (Apple, ANGLE Metal Renderer: Apple M4, Unspecified Version); - If you're on a Windows gaming laptop, the page gets:
ANGLE (NVIDIA, NVIDIA GeForce RTX 4070 Laptop GPU Direct3D11 vs_5_0 ps_5_0).
Among the several thousand people in China who visit this page at the same second, how many of them simultaneously have "10-core CPU + 16GB RAM + Apple M4 GPU + 1512x982 viewport resolution + Asia/Shanghai timezone"?
According to the EFF's famous Panopticlick / Cover Your Tracks algorithm model: A single hardware feature might not identify a person, but when Canvas, WebGL, sound card floating point, screen color depth, timezone, and installed font list are combined, the information entropy is as high as 33 to 36 bits.
Many people find "33 bits of information entropy" abstract: how can a mere 33 bits identify 8.5 billion people?
In information theory, each effective bit is like "halving the suspect pool":
- Determine if you're Mac or Windows? Halves the people (1 bit);
- Determine your display viewport resolution? Cuts 80% more people (a few bits);
- Determine whether your GPU is Apple M4 or RTX 4070? Cuts 95% more people;
- Add in the unique Canvas microscopic font burrs and CPU/memory topology...
2^33 ≈ 8.583 billion
After 33 consecutive "halvings," the search space is compressed to 1 in 8.5 billion!
This means: even if you brought all 8.5 billion living people on earth online at this moment, you couldn't find a second device whose software/hardware state completely overlaps with yours.
4. Escalating the fight: Why does it still pierce through even after switching to a global proxy IP?
Some readers with a little more security knowledge might sneer:
"What if I not only turn on incognito but also run a global proxy VPN, switching my exit IP to the US or Hong Kong? IP and location are all different now. Can the site still recognize me?"
Reality is crueler than you think.
In real black-market countermeasures and commercial big-data tracking scenarios, this behavior doesn't just fail to clean you; it actually gives the algorithm an even rarer set of features.
1. Cross-network "trailing" and account linkage chains
Large e-commerce, social platforms, and rogue ad networks often work like this:
┌────────────────────────────────────────────────────────────────────────┐
│ 【Cross-IP and cross-incognito device fingerprint linkage】 │
│ │
│ 10:00 AM [Normal mode] │
│ • Real IP: 120.245.xx.xx (Beijing Unicom) │
│ • Logged-in account: User A (with login cookie) │
│ • Extracted hardware fingerprint: 0x244f4e0d (Apple M4 / 16G / canvas unique) │
│ └─► Server DB records: [fingerprint 0x244f4e0d] bound to [User A] │
│ │
│ 15:00 PM [Incognito + proxy IP] │
│ • Proxy IP: 104.28.xx.xx (Cloudflare, US) │
│ • Cookie: empty (incognito works) │
│ • Extracted hardware fingerprint: 0x244f4e0d (unchanged) │
│ └─► Server triggers risk control rule: │
│ SELECT user_id FROM user_devices WHERE fp = '0x244f4e0d'; │
│ ──► instantly hits [User A]! │
│ │
│ 【Result】: proxy IP becomes ineffective camouflage; all incognito behavior is silently merged into the main account profile │
└────────────────────────────────────────────────────────────────────────┘
Even if you shift your IP to Antarctica, as long as your fingerprint hash doesn't change, in the server's knowledge graph this is just an ordinary "known device roaming from a foreign IP."
Here's an analogy:
It's like a wanted fugitive thinking he's changed into a new coat (incognito clearing cookies), takes a taxi from the east side to an internet cafe on the west side (proxy IP), and even wears a mask (pretending to be anonymous). The bank wouldn't recognize him.
But the moment he presses his palm against the counter glass, the fingerprint reader in the back lets out a crisp "beep":【ALERT】Hit the palm print of fugitive Zhang San! The new coat color and the new internet cafe location have been automatically merged into Zhang San's file.
See, switching a proxy IP doesn't protect you; it's like proactively reporting to the tracking system: "Sir, Zhang San went for a stroll to the Seattle node today!"
That's why many people watch an "unmentionable movie" in incognito at night, or browse some embarrassing niche content on a private site, thinking that closing the tab will make all traces vanish; But the next morning while browsing news or shopping in a normal window, highly related special products or targeted ads suddenly appear in the feed! Many people's first reaction is a chill down the spine: "Did my phone mic eavesdrop on me?" No need for eavesdropping. All your incognito browsing from last night, which you thought was invisible, was stitched into your daytime real user profile by the cross-site tracking alliance through that unchanged hardware fingerprint.
Moreover, because you're running a proxy, if the page triggers WebRTC (Web Real-Time Communication) during load, your real network topology suffers a fatal "second exposure."
2. WebRTC STUN traversal: the Achilles' heel of proxy protocols
Many so-called "global proxies" actually only take over the OS's TCP traffic or HTTP/HTTPS protocol stack.
Modern browsers natively include the WebRTC framework to support web audio/video calls. WebRTC is like a dedicated ventilation pipe secretly drilled into a load-bearing corner. You put a thick proxy shield on the front door (TCP/HTTP), but the ventilation pipe (UDP) directly connects to the outside road. To traverse NAT routers and establish end-to-end communication, WebRTC sends UDP-based probe messages directly to public STUN servers (like Google or other public gateways).
A webpage only needs to quietly execute a few lines of code:
const pc = new RTCPeerConnection({
iceServers: [{ urls: 'stun:stun.l.google.com:19302' }]
});
pc.createDataChannel('');
pc.createOffer().then(offer => pc.setLocalDescription(offer));
pc.onicecandidate = (event) => {
if (event && event.candidate) {
// Directly extract real private and public IPs from candidate packet fields
console.log("【Leaked real network candidates】:", event.candidate.candidate);
}
};
Many proxy tools don't intercept or cannot intercept this underlying signaling. The browser sends the UDP packet directly through the physical network card, and the STUN server parrots back your real public IP and LAN private subnet (like 192.168.3.102) in the message.
You think you're in Seattle; the page runs and slaps your Hangzhou home router subnet on the public screen.
5. Geek reflection and defense manual: How to truly take back digital privacy?
After reading this, many people feel deep helplessness and absurdity: Is privacy protection really just a deceptive game staged by tech giants for the masses? Can an ordinary person still have an unmasked identity on the internet?
The answer is: You must establish a clear security threat model, abandon illusions, and adopt the correct defensive posture.
1. Deadly misconception: installing a "Canvas random confusion plugin"?
In tech circles, some try to fight magic with magic: since fingerprints are unique, why not install a "Canvas mask / random noise injection" extension from the Chrome Web Store? Every time a page reads the canvas, we add tiny random noise to the pixels, making the hash different each time. Isn't that breaking the loop?
Wrong! In security this is called the "Fingerprint Paradox."
It's like seeing everyone on the street walking normally, and to avoid a surveillance camera on the corner, you tie a flashing red alarm light to your forehead, or deliberately trip and fall every three steps.
The camera indeed can't see your face clearly, but among thousands of normal people on the street, that "anomalous behavior of walking with a red light on your head and falling" instantly becomes the rarest, most standout super-fingerprint in the world.
In real risk control, the same logic applies: Normal human Canvas fingerprints differ from person to person, but on the same model of Mac or the same ThinkPad configuration, because the batch hardware is identical, there are thousands of completely identical "fingerprint clusters." Once you inject random noise into Canvas:
- Your fingerprint changes every time: risk control can detect in a second that "this visitor redrew the same page twice and the hash changed," instantly marking you as a high-risk malicious crawler or hacker scanner, triggering a slider CAPTCHA or even blocking you;
- You become the most visible target: in a crowd where 99.9% don't install such niche plugins, the "always draws with microscopic noise" trait itself is the most unique identifier worldwide.
2. Real effective geek privacy defense solutions
To completely cut the link between hardware fingerprints and web tracking, you must approach it from "eliminating individual differences, merging into the largest group" or "physical environment isolation":
┌────────────────────────────────────────────────────────────────────────┐
│ 【Tiered Privacy Defense Decision Tree】 │
│ │
│ Requirement level Best practices & recommended tools │
│ │
│ Lv.1 Everyday anti-tracking ─────► Enable Safari's "Advanced Tracking and Fingerprint Protection" │
│ (native support on iOS 17+ / macOS Sonoma) │
│ │
│ Lv.2 Deep anti-fingerprint ─────► Use Brave browser or enable Firefox's │
│ privacy.resistFingerprinting (standardized spoofing) │
│ │
│ Lv.3 High-risk anonymous combat ─► Use Tor Browser (onion routing) │
│ (unified locked viewport, fonts, Canvas standardization) │
│ │
│ Lv.4 Physical-level total isolation ─► Run a lightweight VM / containerized incognito system │
│ (QEMU / UTM virtual GPU, destroy after use) │
└────────────────────────────────────────────────────────────────────────┘
① First tier: embrace browsers with "native fingerprint standardization"
- Apple Safari (macOS Sonoma / iOS 17 and above):
InSettings -> Privacy & Security -> Advanced, Apple has natively introduced "Advanced Tracking and Fingerprint Protection." Unlike third-party violent random noise, Apple's strategy is to "smooth out differences" — all devices with this feature enabled return sanitized, standardized hardware parameters to untrusted scripts, greatly reducing single-device entropy; - Brave Browser:
Natively integrates theFarblingalgorithm. Its brilliance is not random mutation but a fixed pseudo-random seed per specific domain, keeping a stable fingerprint within the same site and breaking across sites, destroying cross-site tracking chains; - Firefox native geek mode:
In the address bar typeabout:configand enable:privacy.resistFingerprinting = true
When enabled, Firefox forces screen resolution to report standardized rounded values, forces timezone to UTC zero, and restricts Canvas extraction to explicit user permission prompts. This is one of the most hardcore anti-fingerprinting switches in the open-source world.
② Second tier: plug the WebRTC leak backdoor
If you often use a proxy for network debugging, be sure to block WebRTC's ability to bypass the proxy:
- Chrome/Edge users: install a WebRTC Leak Shield extension, or in the proxy client be sure to enable "TUN virtual network card mode" and intercept all UDP traffic, never just a plain system HTTP proxy;
- Firefox users: go to
about:configand setmedia.peerconnection.enabledtofalseto completely disable WebRTC.
③ Ultimate: physical sandbox isolation
If you're performing extremely sensitive operations, checking classified material, or as a developer doing adversarial testing: Never trust any browser window on the host machine.
Open a lightweight VM (e.g., UTM, VirtualBox) on your Mac or PC, and run a clean Debian or Alpine Linux inside. The virtualized GPU is a fictitious Red Hat VirtIO GPU, and the sound card and CPU topology are all faked by the virtualization layer. When done, just click "restore snapshot" or "discard without saving."
At that moment, even the most advanced commercial fingerprint probe can only capture a virtual ghost that lived for ten minutes and then vanished in the physical world.
Conclusion: Don't fool yourself in a transparent glass house
The essence of technological civilization is the process of hiding complexity behind polished exteriors.
Browser vendors gave the public a black interface, drew a sunglasses-wearing spy, and told everyone "it's safe here." This low-barrier psychological comfort has led hundreds of millions of users to believe they have a shield against the entire internet tracking system.
But as a geek, a developer, or a conscious individual responsible for your digital assets, you must understand:
Code has no warmth, and algorithms don't believe in masks.
As long as your physical hardware is powered on, as long as your rasterization rendering runs, every footprint you make in the digital world is traceable. Tearing off this false placebo called "incognito" and seeing the cold technical truth underneath is not to move toward nihilism or panic, but to regain the clear digital initiative that belongs to us in an age fully surrounded by algorithms.
Copyright notice: This article was first published on the WeChat official account 《第404号工位》 (WeChat ID:
workstation404). It focuses on dissecting tech hot topics and hardcore practice. Unauthorized commercial reproduction is prohibited.