Fingerprint self-check

What your browser reveals, in plain sight

Fingerprinting cross-references dozens of small details — your GPU, your fonts, your timezone — to recognize you without a cookie. This page shows you plainly what we already see, and what your browser exposes if JavaScript is on. No spoofed values, no third-party library, no external call.

Section A · With no JavaScript at all

What your connection already reveals

These values come straight from your HTTP request. They are visible to any server you contact, JavaScript on or off.

  • Source IP addresslive value

    216.73.217.145

    A near-unique per-session network identifier; for many households IPv4 stays stable for days/weeks and links all your requests together and to other sites' logs. On IPv6 the /64 prefix often identifies the subscriber line even when temporary addresses (RFC 8981) rotate.

  • ASN / org / IP geolocationlive value

    🇺🇸 US · AS16509 · Amazon.com, Inc.

    The ASN and network owner classify the IP (residential vs Hetzner/OVH/AWS, or a known VPN/Tor exit). Country/region are not an identifier alone but shrink the anonymity set and chiefly power inconsistency checks (timezone/language vs country). Resolved locally against a self-hosted CC0 database — no third-party call.

  • User-Agent headerlive value

    Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; ClaudeBot/1.0; +claudebot@anthropic.com)

    High-entropy string: browser family+version and OS family+version. An exact version within an IP range is strongly narrowing, and a non-standard UA (curl, library, old browser) stands out immediately. Entropy is falling due to Chrome UA Reduction but it is still a baseline.

  • Accept-Language headerlive value

    The language+region+order+q-values tuple is fairly distinctive, and it is the key input to the language↔IP-country mismatch check — which works without JavaScript since language is in HTTP headers. A missing or generic (en-US only) Accept-Language from a non-English IP is typical of automation/VPN.

  • Accept / Accept-Encoding headerslive value

    Accept: */* · Accept-Encoding: gzip, br, zstd, deflate

    The exact Accept value (ordering, q-values, image/avif, image/webp) and the Accept-Encoding list/order (gzip, br, zstd) vary by engine and version. Low entropy alone but a strong consistency oracle: a 'modern Chrome' without br, or an Accept that doesn't match the claimed UA, betrays a spoofed UA.

  • UA Client Hints (Sec-CH-UA*)live value

    Chromium sends low-entropy hints by default (Sec-CH-UA brand, -Mobile, -Platform). High-entropy hints (-Platform-Version, -Arch, -Model…) arrive only after server opt-in via Accept-CH — as a privacy-respecting operator we deliberately do NOT request them. Their absence on Firefox/Safari is itself an engine signal; a Sec-CH-UA-Platform vs UA mismatch betrays a spoof.

  • DNT / Sec-GPC headerslive value

    Paradox: sending a privacy header (DNT: 1, now deprecated, or Sec-GPC: 1 / Global Privacy Control) is rare and thus adds a distinguishing bit while flagging a privacy-conscious profile. Treat it as a legal signal you may want to honor regardless.

What the network can see (not measured here)

These vectors exist and are real, but are not observable at this origin: Traefik terminates TLS and Next.js normalizes headers. They would require a ClientHello-capturing proxy, packet capture, or a dedicated edge terminator. Shown for education.

  • TLS fingerprint (JA3 / JA4)not measured here

    A browser's TLS stack yields a characteristic ClientHello (version, cipher suites, extensions, curves, ALPN). JA3 (2023) was defeated by Chrome's extension-order randomization; JA4 sorts ciphers/extensions and resists it. It is the decisive counter to UA spoofing: a curl disguised as Chrome has a non-Chrome JA4. Not measurable here: Traefik terminates TLS, the app sees only the negotiated cipher, not the offered ClientHello.

  • HTTP/2 fingerprint (Akamai)not measured here

    HTTP/2 setup exposes implementation choices: SETTINGS frame values/order, WINDOW_UPDATE increment, PRIORITY frames, and pseudo-header order (:method :authority :scheme :path). A second layer beyond JA4. Not measurable here: Traefik normalizes frames to the backend.

  • HTTP header ordernot measured here

    Each engine (Chrome, Firefox, Safari, curl, httpx) emits headers in a fixed order the user cannot change. An order that doesn't match the claimed UA is a strong spoof signal. Not measurable here: Next.js's headers() lowercases into a Map and loses order; capturing it would need a custom Node server or capture at Traefik, neither present in this deployment.

  • HTTP/3 / QUIC fingerprintnot measured here

    The QUIC Initial packet carries the TLS 1.3 ClientHello (thus all JA4 features) plus implementation-specific transport parameters (Chrome's initial_max_data ≈ 15 MB, per-stream windows, connection-ID length), visible in the clear before app encryption. Not measurable here: needs a dedicated QUIC terminator.

  • TCP/IP stack fingerprint (TTL, window — p0f)not measured here

    The OS network stack yields a SYN signature (initial TTL, window size, MSS, TCP option order) from which p0f infers the OS with no probe. Residual TTL reveals hop count and can betray NAT/VPN. Not measurable at the app layer: needs packet capture/eBPF on the edge host.

  • DNS resolver / EDNS Client Subnetnot measured here

    If you are authoritative for a name the client resolves, EDNS Client Subnet (RFC 7871) hands a truncated client prefix (often /24) to authoritative servers, plus the resolver identity. A resolver↔IP divergence betrays a proxy/VPN. Not visible in the HTTP request: it lives in DNS logs, not the web request.

  • Reverse DNS (PTR)not measured here

    The IP’s PTR record often reveals the hosting provider or a predictable VPN-exit pattern (e.g. *.clients.your-server.de), confirming datacenter vs residential. Not performed here: an active PTR query per visit adds latency and leakage; the ASN database already approximates this verdict.

  • TLS session resumption / HTTP/2 connection reusenot measured here

    TLS session tickets / PSK (resumption, 0-RTT) and HTTP/2-3 connection coalescing let an origin link multiple requests to the same client, cookieless and even across the no-JS path, sometimes across an IP change. Not visible here: Traefik terminates TLS so the app cannot see resumption — but the edge terminator can.

Sections B & C · With JavaScript

What your browser additionally exposes

Each test below is written by us and runs entirely in your browser. Results are grouped by category. None is transmitted.

Two identities, not one

Your browser produces two very different fingerprints. The first changes from one browser to another and from one session to the next. The second describes the underlying hardware and stays largely the same whichever browser you open on the same machine. Both are computed below, in your browser, before anything is sent.

Fingerprint of THIS browser (volatile)

A hash of every browser signal. It flips between browsers and often between normal and private mode — what changes is mostly the storage/session surfaces and client hints (UA-CH), not canvas randomization (off by default). This is the 'this browser session' identity.

Hardware identity (cross-browser)

computing…

Derived only from the hardware/OS substrate every browser shares: GPU (perceptual hash of a fixed WebGL scene), audio DSP, OS fonts, emoji metrics, CPU cores, memory, timezone, platform family, screen dimensions. No storage signal, so switching to private mode does not move it. It narrows you to a small group on this machine — never a universal id.

This one is different: it sends data. We explain exactly what, then ask.

Your composite fingerprint

computing…

SHA-256 hash of all the signals above, computed via crypto.subtle in your browser. It is not transmitted to us. Two visitors with the same hash are indistinguishable; a rare hash singles you out.

Rendering (GPU / canvas)5
Empreinte Canvas 2Dneutral
Running tests…

Des instructions de dessin identiques (texte + formes) produisent des pixels légèrement différents selon le GPU, les pilotes, le moteur de polices de l'OS et l'anti-crénelage. Un readback haché de l'image donne un identifiant à ~8–10 bits, l'un des plus forts contributeurs. Tor renvoie un canvas uniforme (durcissement) ; Brave injecte un bruit déterministe par session+origine — deux lectures dans le même contexte donnent donc le MÊME hash : une lecture cohérente n'exclut pas Brave.

same value across browsersUniqueness: ~8–10 bits (estimation)
Vendeur & renderer WebGLneutral
Running tests…

La chaîne non masquée via WEBGL_debug_renderer_info nomme le modèle exact de GPU, le pilote et le backend (ANGLE). ~5–7 bits. Le vendeur doit rester cohérent avec les extensions WebGL, la taille max de texture et l'adaptateur WebGPU — toute non-correspondance expose un spoof.

same value across browsersUniqueness: ~5–7 bits
Hash de rendu WebGLneutral
Running tests…

Le hash d'une scène 3D rendue (dégradés/shaders) capture les particularités de virgule flottante et de rastérisation du GPU/pilote réel. ~5–8 bits, cœur du résultat cross-browser de Cao : même GPU → mêmes imperfections quel que soit le navigateur.

same value across browsersUniqueness: ~5–8 bits
Adaptateur & limites WebGPUneutral
Running tests…

GPUAdapterInfo + l'objet limits (~40 plafonds numériques corrélés) + la liste des features encodent la « tier » exacte du GPU, bien plus finement que la chaîne WebGL. Vecteur récent, important en 2026. Son absence (Firefox/Safari) est elle-même un signal.

same value across browsersUniqueness: élevée ; ~32 buckets max par spec
Minutage des unités GPU (DrawnApart)neutral
Running tests…

En chronométrant de nombreux courts programmes répartis sur les unités d'exécution du GPU, on révèle les micro-variations de fabrication propres à une puce — uniques même entre deux GPU de modèle identique. Seul vecteur atteignant la granularité de l'appareil individuel. Démonstration de la technique : la valeur ci-dessous est instable (les timers grossis par Tor/RFP l'émoussent) et n'est pas un identifiant stable par visite.

same value across browsersUniqueness: niveau puce individuelle ; +67 % de durée de traçage médiane (NDSS'22)
Hardware6
Empreinte AudioContextneutral
Running tests…

La sortie en virgule flottante d'une chaîne oscillateur→compresseur dans un OfflineAudioContext reflète la pile DSP audio, le comportement FP du CPU, les pilotes audio de l'OS et les maths du moteur. ~5–7 bits, vecteur de premier plan (aucune permission, exécution silencieuse). La part matérielle est cross-browser ; les deltas FP du moteur ajoutent une part propre au navigateur.

same value across browsersUniqueness: ~5–7 bits
Nombre de cœurs logiquesneutral
Running tests…

navigator.hardwareConcurrency révèle le nombre de threads logiques du CPU (~2–3 bits). Fait matériel ; certains navigateurs le plafonnent.

same value across browsersUniqueness: ~2–3 bits
Mémoire approximativeneutral
Running tests…

navigator.deviceMemory indique la classe de RAM par paliers {0.25,0.5,1,2,4,8} Go (~1–2 bits). API Chromium uniquement ; son absence sur Firefox/Safari est un signal de famille de moteur.

same value across browsersUniqueness: ~1–2 bits
Nombre de périphériques médianeutral
Running tests…

enumerateDevices() expose, sans permission, le nombre et le type (audioinput/audiooutput/videoinput) de périphériques — les libellés sont vides mais les comptes fuient (~2–4 bits). Une incohérence avec les capacités WebRTC est détectable.

same value across browsersUniqueness: ~2–4 bits (comptes)
API Battery (obsolète)neutral
Running tests…

level/charging : la combinaison niveau+décharge formait un quasi-identifiant éphémère. Retirée de Firefox (~2017), jamais implémentée par Safari, encore exposée dans Chromium sur origine sécurisée uniquement. Largement morte en 2026 — sa présence ne signale plus que « Chromium ».

browser-specificUniqueness: ~0–1 bit (quasi morte)
Pointeur & capacités tactilesneutral
Running tests…

maxTouchPoints, les media features pointer/hover et le support des touch-events distinguent écran tactile vs souris (~1–2 bits). Fait matériel, cross-browser ; doit cadrer avec la plateforme UA (Windows + maxTouchPoints=10 plausible ; iPhone + 0 est un indice).

same value across browsersUniqueness: ~1–2 bits
System & display13
Métriques de police & ClientRectsneutral
Running tests…

Les boîtes englobantes au sous-pixel du texte rendu via getBoundingClientRect() capturent police + GPU + lissage et hinting de l'OS. ~7,6 bits mesurés — l'un des vecteurs uniques les plus forts, piloté par le rastériseur OS + GPU donc fortement cross-browser. RFP arrondit les métriques — l'arrondi est lui-même détectable.

same value across browsersUniqueness: ~7,6 bits
Énumération de polices installéesneutral
Running tests…

L'ensemble des polices installées, sondé via la mesure des différences de largeur de repli, reflète l'OS, les logiciels (Office/Adobe) et la langue. Entropie élevée et très stable. Tor embarque un jeu fixe — une liste trop uniforme = Tor/RFP.

same value across browsersUniqueness: élevée, très stable
Rendu des emojineutral
Running tests…

Le hash des DOMRects d'un jeu d'emoji rendus en grande taille trahit l'OS et sa version : les jeux de glyphes diffèrent par fournisseur (Apple vs Noto vs Segoe). Fournie par la police emoji de l'OS donc cross-browser.

same value across browsersUniqueness: élevée, corrélée OS
Fuseau horaire & locale Intlneutral
Running tests…

Le fuseau (Intl.DateTimeFormat().resolvedOptions().timeZone), getTimezoneOffset() et le formatage nombre/date/devise localisent et différencient. Fait OS, cross-browser. Entrée clé du contrôle fuseau ↔ géoloc-IP — un des principaux indices d'incohérence VPN. Tor force UTC.

same value across browsersUniqueness: ~3–4 bits combinés
Langues préféréesneutral
Running tests…

navigator.languages + navigator.language : l'ordre de la liste est assez distinctif (~2–3 bits). Doit correspondre à l'en-tête Accept-Language et à la locale Intl — un désaccord est détectable.

same value across browsersUniqueness: ~2–3 bits
Résolution d'écranneutral
Running tests…

La taille d'écran et les marges UI (barre des tâches, chrome du navigateur) sont distinctives (~4–5 bits). Fait physique, cross-browser. Tor letterboxe vers des buckets de taille pour neutraliser cela.

same value across browsersUniqueness: ~4–5 bits
Ratio de pixels (devicePixelRatio)neutral
Running tests…

Le ratio pixels physiques:CSS (Retina=2, valeurs fractionnaires sur Windows mis à l’échelle) est distinctif (~1–3 bits). Doit cadrer avec la taille d’écran et les media queries de résolution.

same value across browsersUniqueness: ~1–3 bits
Profondeur, gamut & HDRneutral
Running tests…

screen.colorDepth ; color-gamut (srgb/p3/rec2020) et dynamic-range détectent les dalles HDR/large-gamut (~2–3 bits). HDR/P3 encore peu courant → forte distinctivité quand présent. Capacité de dalle, cross-browser.

same value across browsersUniqueness: ~2–3 bits
Profil de media queries CSSneutral
Running tests…

Le sondage de matchMedia énumère affichage + préférences : prefers-color-scheme, prefers-reduced-motion, prefers-contrast, forced-colors, pointer/hover (~3–5 bits agrégés). Préférences OS-level, donc cross-browser. RFP force thème clair / pas de reduced-motion — des valeurs uniformes signalent RFP.

same value across browsersUniqueness: ~3–5 bits agrégés
Voix de synthèse vocaleneutral
Running tests…

speechSynthesis.getVoices() liste les moteurs/voix TTS installés (OS + packs de langue + applications), trahissant l'OS, les langues et les logiciels. Voix fournies par l'OS donc cross-browser. Une liste vide/uniforme signale un durcissement (Brave/Tor).

same value across browsersUniqueness: modérée à élevée
Client Hints UA haute-entropie (JS)neutral
Running tests…

navigator.userAgentData.getHighEntropyValues() expose platform + platformVersion, architecture, bitness, model, fullVersionList — version exacte d'OS, architecture et modèle, redonnant ce que l'UA Reduction cachait. API Chromium uniquement ; absence = signal de moteur. Doit concorder avec WebGPU/platform/timezone.

same value across browsersUniqueness: significative (version OS + arch + modèle)
navigator.platform & vendorneutral
Running tests…

navigator.platform (MacIntel/Win32/Linux x86_64) indique la famille d'OS ; navigator.vendor distingue la famille de moteur ; navigator.oscpu (Firefox uniquement) trahit Firefox. Clés d'une incohérence courante : platform vs UA vs maxTouchPoints.

same value across browsersUniqueness: ~1–2 bits
Quota de stockageneutral
Running tests…

navigator.storage.estimate() renvoie quota (souvent une fraction du disque libre) et usage, modérément distinctif. Bucketisé dans les Chromium récents ; chaque navigateur le calcule différemment.

browser-specificUniqueness: faible à modérée
Engine & behavior3
Quirks moteur JS & mathneutral
Running tests…

Les résultats FP de Math.tan/sin/exp/pow divergent par moteur (V8/SpiderMonkey/JavaScriptCore). Faible entropie isolément mais classificateur fiable de moteur et oracle anti-spoof : un UA « Chrome » avec une signature math SpiderMonkey est un spoof certain — quasi impossible à truquer entièrement depuis JS.

browser-specificUniqueness: faible seule ; fort classificateur de moteur
Carte de détection de fonctionnalitésneutral
Running tests…

L'ensemble des API/objets présents (window.*), CSS @supports et drapeaux mappe navigateur + version + plateforme. Classificateur fort de version/moteur et recoupement de spoof — quasi impossible à truquer de manière cohérente sur des centaines de checks.

browser-specificUniqueness: modérée
Granularité de timing & performanceneutral
Running tests…

La résolution/gigue du timer, la granularité de performance.now() et performance.memory (Chromium) révèlent le moteur et alimentent les attaques de timing GPU/CPU. Tor/RFP grossissent volontairement les timers — des timers grossiers/quantifiés signalent RFP. Indicateur de durcissement, pas un ID stable.

browser-specificUniqueness: indirecte (habilite d’autres vecteurs)
Network2
API Network Informationneutral
Running tests…

navigator.connection : effectiveType (4g/3g), downlink, rtt, saveData. Entropie faible et instable. L'absence ne signifie PAS forcément non-Chromium : Firefox/Safari ne l'ont pas, mais un Chromium durci (Brave) le retire aussi — à recouper avec les oracles de moteur (math/features), pas à utiliser seul.

browser-specificUniqueness: faible, instable
WebRTC : candidats ICE / comportement mDNSneutral
Running tests…

Nous instancions RTCPeerConnection avec iceServers:[] — AUCUN serveur STUN externe. À noter : la CSP ne bloque PAS le STUN (WebRTC contourne connect-src) ; ne pas en mettre est donc un choix d'opérateur, pas une protection imposée par la CSP — d'où l'importance d'auditer son propre JS. Sans STUN, pas de fuite d'IP publique. Le signal réel est le comportement local : depuis 2019 tous les moteurs remplacent l'IP LAN par un hostname mDNS .local randomisé (UUID Chromium vs pseudo-candidats Firefox vs WebRTC désactivé) ; le compte et l'ordre des candidats distinguent le moteur. Le nom mDNS est randomisé par session (pas un ID stable inter-sessions) ; une IP LAN brute n'apparaît que sur des clients mal configurés/entreprise/vieux webviews.

browser-specificUniqueness: mDNS stable par session ; IP LAN quasi jamais exposée

Cross-checks & inconsistencies

Trackers cross-reference signals to spot contradictions. An inconsistency makes you MORE identifiable than the truth, because it is rare and memorable.

  • not assessable

    Fuseau horaire ↔ pays IP : le fuseau lu côté JS est comparé au pays déduit de l'IP. IP à New York + fuseau Tokyo ≈ VPN/proxy quasi certain. Nécessite JS ; en mode no-JS on retombe sur le contrôle langue↔IP.

  • not assessable

    Langue ↔ pays IP : l'en-tête Accept-Language (et la locale Intl côté JS) est comparé au pays de l'IP. Fonctionne SANS JavaScript — le contrôle le plus utile pour un visiteur sans JS. Un Accept-Language générique (en-US seul) depuis une IP non anglophone est typique d'automatisation/VPN.

  • not assessable

    navigator.languages ↔ Accept-Language : la liste de langues lue en JS doit correspondre, dans l'ordre, à l'Accept-Language vu côté serveur. Mentir sur l'un sans aligner l'autre est démasqué — contrôle interne client vs serveur, aucune géoloc requise.

  • not assessable

    Plateforme UA ↔ navigator.platform / maxTouchPoints : l'OS annoncé par le User-Agent doit concorder avec navigator.platform, navigator.oscpu (Firefox) et maxTouchPoints. UA « Windows » + platform « Linux », ou « iPhone » + maxTouchPoints=0, trahit un spoof.

  • not assessable

    UA ↔ moteur JS réel : le moteur impliqué par les quirks math et la carte de fonctionnalités doit correspondre au navigateur annoncé par le UA. Un UA « Chrome » avec une signature SpiderMonkey est un spoof certain — ces oracles sont quasi infalsifiables depuis JS.

  • not assessable

    GPU WebGL ↔ WebGPU : la chaîne renderer WebGL, les limites de l'adaptateur WebGPU, la taille max de texture et les extensions doivent décrire le même matériel. Un renderer falsifié qui ne concorde pas avec la tier WebGPU expose le spoof.

  • not assessable

    Écran ↔ fenêtre ↔ DPR : screen.width/height, availWidth/Height, window.outer/inner et devicePixelRatio doivent être cohérents (inner ≤ outer ≤ screen ; delta outer−inner = hauteur de chrome plausible). Des valeurs letterboxées trop rondes signalent Tor ; des ratios impossibles signalent un spoof.

  • not assessable

    Cohérence en relecture : canvas, hash WebGL et audio doivent hacher identiquement sur deux lectures dans le même contexte. Cela attrape les shims naïfs qui randomisent à chaque appel. ATTENTION : une paire COHÉRENTE n'exclut PAS Brave — le farbling de Brave est déterministe par session+origine, donc deux lectures concordent comme sur un navigateur non durci. Brave se détecte autrement (instabilité inter-sessions, divergence cross-origine).

  • not assessable

    Drapeau d'uniformité / durcissement : un faisceau de valeurs trop uniformes — canvas uniforme, liste de polices figée, fuseau UTC, thème clair forcé, timers grossiers, voix TTS vides — identifie le visiteur comme appartenant au bucket étroit Tor/RFP. Ce n'est pas une contradiction interne mais une signature de standardisation : « vous êtes dans la foule Tor », pas une erreur.

Demonstration

Cache and supercookies

Beyond fingerprinting, a site can re-identify you by stashing an id in browser corners. Both demos below run only on your own browser, same-origin, and are fully clearable.

Cache-timing re-identification

On the first visit we store a random id in the same-origin Cache API. On a later visit, a fast hit on that resource (a cache "hit") shows the browser still holds it — and we re-read the id. This is the state-based cousin of fingerprinting.

No cache marker yet.

Trivially defeated: clear the browser cache, use private mode, or click "Clear now" to remove the marker.

Demonstrate a supercookie (on yourself)

Opt-in: we write the SAME id into three same-origin stores at once — localStorage, IndexedDB and the Cache API. Clearing only cookies then is not enough: the stores resurrect each other on the next read. This is the "evercookie" principle.

No demo supercookie active.

Guarantee: this demo uses only same-origin web storage you control. "Reset everything" wipes all three stores; clearing site data in your browser also wipes them. No HSTS pinning, no favicon-cache abuse, no cross-site state: nothing here survives a site-data clear.

How real supercookies work

HSTS supercookie: a site encodes id bits by forcing (or not) strict HTTPS across a set of subdomains; on return, the presence of the HTTPS upgrade replays the bits. These pins are deliberately hard to clear because they are transport security state.

Favicon supercookie: the favicon cache is separate and long-lived; by mapping a distinct favicon per id and path, a site reconstructs the id from the missing favicon requests.

Tor Browser and Tails defeat these: double-keying (first-party isolation) of all caches and storage, per-origin isolated favicon cache, and fully ephemeral state destroyed on close. Do not hide, look like everyone else — and keep nothing.

TLS fingerprint (JA4)

Before a single HTTP byte, your TLS client has a signature — the order of cipher suites and extensions in its “ClientHello”. Measured by our own service (fp.onsecret.net), because the main server can’t see it (Traefik already terminated TLS).

Measuring…

Stable per browser/version and hard to change without dedicated tools; a JA4 that doesn’t match the advertised User-Agent betrays a spoofed client.

Section D · What to do

Recommendations

One principle governs everything else: blend into a large crowd instead of trying to hide. Spoofing values incoherently makes you more recognizable, not less.

The one principle: blend into a crowd, don't hide

Anti-fingerprinting is not about hiding your attributes — it is about being identical to a large crowd of users. The Tor Project's goal is to 'reduce the number of distinguishable buckets per metric.' Anything that makes you different from the default install of the same browser — a resized window, an added extension, a flipped setting, a spoofed value — removes you from the crowd and makes you MORE unique. This is the most-misunderstood point, and it governs every recommendation below. Corollary: a spoofed-but-inconsistent profile (Windows UA + curl TLS stack, or Tokyo timezone + New York IP) is more memorable than the truth, because detectors cross-check signals to spot exactly those contradictions.

Tor Browser — the gold standard, and its exact settings

Tor Browser is engineered so every user presents the same fingerprint: UA and OS forced into a few buckets, canvas extraction blocked/prompted, WebGL hardened, fonts limited to a bundled set, timers coarsened, timezone forced to UTC. Settings: (1) Security Level to Safer or Safest — Safest disables JavaScript everywhere, neutralizing all active fingerprinting (canvas, WebGL, AudioContext, font enumeration, timing). (2) Do NOT maximize or resize the window — letterboxing (grey bars, rounding to a multiple of 200×100 px) is the protection working. (3) Never install extensions — the bundled NoScript is part of the standard fingerprint; do not add uBlock. (4) Never touch about:config or preferences: the defaults ARE the anonymity set. (5) Keep Tor Browser updated — the crowd is defined per browser version.

Mullvad Browser — Tor-grade anti-fingerprinting without the Tor network

Mullvad Browser (co-developed by Mullvad VPN and the Tor Project) ships the same hardening as Tor Browser (letterboxing, 'all users look alike', masked fonts/canvas/hardware APIs, no telemetry) but does NOT route over Tor — it is meant to run behind a trustworthy VPN. Use it when Tor's latency is impractical but you still want a uniform fingerprint. Same discipline as Tor: default window size, no extensions, no settings changes. Honest limitation: it gives Tor-grade anti-fingerprinting but NOT Tor's network anonymity (your VPN sees one hop, not three) — a speed trade against a weaker network guarantee.

Buy the VPN anonymously: Monero over Tor

Mullvad issues a random 16-digit account number with no email, username, password or name, an explicit no-KYC policy, and accepts Monero. Generate the account number and settle the XMR invoice from within Tor Browser. Tor breaks the network link at purchase, Monero breaks the financial link; Monero's on-chain privacy (hidden amounts, sender and recipient) is far stronger than Bitcoin's transparent ledger for this purpose. Ordering matters: buying non-anonymously (card, home IP) links the account to you regardless of how cleanly you use it afterward.

Device-level entropy reduction (onsecret hardware)

GrapheneOS (Pixel) reduces device-side entropy vs stock Android: strips system Google services, per-app Sensors permission (cut accelerometer/gyroscope/barometer — motion-based fingerprinting vectors), per-app Network and Storage scopes. Pixels are required because GrapheneOS depends on their hardware roots of trust (verified boot, attestation). Combine with the crowd-blending browsers: the OS reduces device entropy, the browser web entropy. Tails (amnesic) on a hardened ThinkPad boots from USB, routes everything over Tor and leaves no trace — each session restarts identical to every other Tails user's. Qubes + Whonix adds compartmentalization: isolating personas in distinct qubes prevents linking one activity to another, and a compromise stays contained.

Mudi + blue-merle: network-identifier entropy

On cellular, the IMEI (device), IMSI (SIM) and the router's MAC are persistent hardware identifiers that fingerprint you at the carrier/Wi-Fi layer, independent of the browser. The blue-merle package randomizes the IMEI and does vendor-OUI-aware MAC mimicry rather than a fully random MAC. Why OUI matters — it is the same principle as the browser advice: a MAC with a random/invalid vendor prefix is itself anomalous and stands out; mimicking a plausible OUI keeps you in the crowd of legitimate devices instead of flagging you as 'a device trying to hide.' Pair IMEI randomization with a SIM swap: do not rotate the IMEI while keeping the same IMSI on the same cell, because that pairing is itself trackable.

Mistakes that make you MORE identifiable

(1) Spoofing that creates internal inconsistencies: a 'Windows' UA on a 'Linux' platform, a WebGL renderer that doesn't match the OS, fonts inconsistent with the platform are dead giveaways. A coherent profile blends in; an incoherent one screams 'spoofer.' (2) Stable lies = stable tracking: always spoofing the same way turns that combination into a durable fingerprint; per-load randomization is the mirror problem (a detectable red flag). (3) Language/timezone/IP mismatches: exiting via a German node while advertising en-US and a New York timezone is a classic tell; Tor deliberately standardizes locale and timezone (UTC) — leave them alone. (4) Unique window sizes: maximizing or fitting an ultrawide pushes you out of the letterboxing buckets. (5) Mixing identities on one session links the accounts — use 'New Identity' or separate personas. (6) Adding 'privacy' extensions (uBlock/Canvas-blocker) to Tor/Mullvad Browser makes you unique vs the stock crowd. (7) Buying the anonymity tool non-anonymously links the account to you.