跪拜 Guibai
← Back to the summary

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:

"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:

Diagram - Modern browser: normal mode vs incognito mode sandbox isolation principle

┌────────────────────────────────────────────────────────────────────────┐
│        【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:

  1. It creates a temporary sandbox in memory; when the window closes, it discards any temp cookies, localStorage, and sessionStorage.
  2. 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:

Diagram - 30 lines JS hardware fingerprint extraction, results from normal and incognito windows are identical

/* 【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:

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:

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":

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:

Diagram - Cross-network proxy trailing and WebRTC leak exposing LAN topology

┌────────────────────────────────────────────────────────────────────────┐
│        【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:

  1. 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;
  2. 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":

Diagram - 2026 geek digital privacy defense classification decision tree and practical checklist

┌────────────────────────────────────────────────────────────────────────┐
│                   【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"

② 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:

③ 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.