Skip to content

About

Who do websites think you are? A privacy self-check: every sniffer any site can run, the portrait they paint, and the contradictions that give away a VPN or proxy

Topics

Resources

Stars

225 stars

Watchers

2 watching

Forks

Repository files navigation

Who Are You

English · 简体中文

Who do websites think you are? Who Are You runs the sniffers any site can run the moment you open it, without a single permission prompt, and writes down the result as a paragraph with the blanks filled in: your likely nationality, the city you're in, your language and time zone, your device, browser, screen and graphics card, your network, your preferences, what your fonts say about your work, and your browser fingerprint.

It then checks those readings against each other the way a site would to spot a disguise, and lists all 86 sniffers with how each one reads and what it read.

Live: https://who.1ms.dog · topic pages: browser fingerprint test, DNS leak test, Browser Environment Check, Time Zone Check, Proxy Check, Browser Language Check, Canvas Fingerprint Test, User Agent Check, Browser Extension Check, WebRTC leak test (same tool, that result first; text in src/pages.mjs)

More from 1ms.dog, all free and open source (hover a name to see what it answers)

Speed & connectivity: 1ms.dog · Network X-Ray · Speed Test · DNS Test · IPv6 Test · CDN Radar · Reach Check

IP & privacy: EgressLens · IP Quality Test · ASN Lookup · Streaming & AI Unlock Check

Cloud & costs: Me2Cloud · Lightsail Cost Saver · Cloud Cost Planner

Command line: httpslatency · vps2cloud · dnstest

What it shows

  • The portrait. One paragraph, every blank filled from the sniffers. Hover a blank to see which sniffers it came from (their rows light up). Age is the one blank it leaves open: nothing in a browser says it, and the page says so instead of guessing.

  • What a site makes of it: three blanks of the portrait are conclusions rather than readings: what the machine looks like it's for (graphics card, refresh rate), whether everything lines up (if not, a site will likely guess a proxy), whether clearing cookies helps (a stable fingerprint).

  • Against last time: kept in your browser only; rerun after changing settings and it shows "last time 8, this time 7, fixed: …". When the fingerprint changes, it says whether the browser was updated or which parts moved.

  • The last runs: the count of the last ten runs as a small line, each point's time on hover, kept in your browser only.

  • Copy as text: the portrait, the twelve checks and the connection protocols as text to paste into a post, with the city, the network and addresses masked, and a link to this page.

  • Fixes for your system: the DNS and WebRTC fixes name the clients and settings of Windows, macOS, iPhone or Android, whichever you're on.

  • HarmonyOS: its browsers (ArkWeb) claim Windows or Android in the user agent for compatibility; the OpenHarmony, HarmonyOS or ArkWeb token tells it apart.

  • Where to seem to be: pick a target region (by default the one the IP is in) and see, item by item, whether the IP, the system time zone, the browser language, the DNS resolver and WebRTC match it, and how to fix what doesn't.

  • The disguise check, twelve rows that matter when you want to hide, and an A–F grade for the environment:

    • system time zone vs. the IP's time zone
    • browser language vs. the IP's country
    • System language vs IP: the language packs a Windows system installed, from its supplemental fonts, local voices and keyboard layout (other systems ship every language's fonts and voices)
    • DNS leak: the country of the resolver that actually looked you up vs. the IP's
    • split routing: a site in mainland China, an IP service abroad, ChatGPT, Claude, Cloudflare and this site seeing different exits
    • WebRTC: public addresses STUN servers see that this site sees neither over IPv4 nor over IPv6
    • Round trip: the browser's round trip much longer than the one Cloudflare measures on its own connection means another hop in between, like a proxy (a residential IP doesn't hide it)
    • data center network (clouds, hosting, VPN providers)
    • user agent vs. the system the client hints and WebGL renderer give away
    • Tampered environment: navigator properties redefined, drawing or audio functions replaced, a JS engine that isn't the user agent's, a language in JavaScript the request header doesn't have, Date and Intl disagreeing on the time zone
    • whether the fingerprint is stable (trackable) or randomized
    • automation (navigator.webdriver)

    Every check that gives you away has a How to fix tip (Clash fake-ip / TUN for DNS leaks, limiting WebRTC, matching the time zone…), and a link to the 1ms.dog tool that looks deeper when the host announces it (<meta name="dns">, "egress", "ipqs").

  • Connection protocols, under the checks: judged the same way but not counted, since they say how the connection is made, not who you are:

    • HTTP/3: this site's /cdn-cgi/trace asked again a few times; one answer over QUIC means it works. When none comes, WebRTC's STUN (UDP) decides: no UDP at all means it's blocked or the proxy doesn't carry it, otherwise the browser just hasn't switched yet
    • ECH: this site publishes its ECH keys in its DNS HTTPS record, so the trace's sni=plaintext means the browser didn't use them; the likeliest reason by browser (Safari lacks it, Firefox needs DNS over HTTPS, otherwise DNS gave no HTTPS record, as with a proxy's fake-ip)
    • Post-quantum key exchange: a browser that offers it by default (Chromium 124, Firefox 132, Safari 26 on) ending up with a classical one points to something in between that makes its own TLS
    • WARP and Gateway: shown, not judged
  • The fingerprint ID card, with your previous visit: kept in your browser only, it shows when you were last here and whether the fingerprint was the same, which is how a site that never set a cookie still recognizes you.

  • Sharing. 1ms.dog's shared share dialog (public/assets/share/, copied verbatim from 1ms-shell) with an image card drawn in the browser and a link, /<lang>/r/<version>.<code> (no folder for English; older /r/<code> links still open), that opens the same portrait in the viewer's language and previews with the result in its title and image (the Worker writes them; format and version: src/share.mjs). Neither carries your address or fingerprint; city and network only if you tick the box. Shortened when the host announces a shortener (<meta name="shortener">). Someone opening a shared portrait gets a "Check mine" card where the fingerprint would be, and a filled button at the bottom.

  • Every sniffer, grouped:

    • What the server sees: IP, Cloudflare geolocation (city, coordinates, ASN, time zone), reverse DNS, nearest edge and TCP RTT, HTTP/TLS version and cipher, post-quantum key exchange and ECH, Cloudflare WARP, a TLS ClientHello fingerprint, your clock's offset, the DNS resolver (edns.ip-api.com), WebRTC public and local addresses
    • Exits: the address each kind of destination sees, plus your IPv4 and IPv6 exits (Cloudflare Radar)
    • Request headers: User-Agent, Accept-Language, Sec-CH-UA, platform, encodings, DNT/GPC, referrer
    • Language and region: navigator.languages, locale, time zone, 12/24-hour clock, first day of the week, number and date format, keyboard layout, speech voices
    • Device: OS and version, browser, architecture, screen, refresh rate, number of screens, GPU (WebGL and WebGPU), CPU threads, memory, touch, battery, connection, cameras and microphones (counted, never opened), video codecs, DRM systems, storage quota; new: window and system bar, WebGL capabilities, audio hardware (sample rate, channels), biometrics (whether Windows Hello / Touch ID is available, asked, never used), Bluetooth adapter
    • Browser settings: color scheme, reduced motion, color gamut and HDR, DNT/GPC, cookies, permissions already granted or blocked, PDF viewer, webdriver, ad blocker, extensions that leave a mark (crypto wallets, developer tools, Grammarly, Dark Reader, Immersive Translate), tab history, installed fonts; new: accessibility preferences (high contrast, forced colors, reduced transparency, inverted colors), how the page was opened (tab, installed app, full screen)
    • Fingerprints: canvas, WebGL, audio, font list, the combined fingerprint, and whether the browser randomizes them; new: the JavaScript engine (V8, SpiderMonkey or JavaScriptCore, from the wording of an error, which changing the user agent doesn't change)

Rows are drawn before anything is read and filled the moment each sniffer answers; the paragraph is filled once, when every blank is in, so the page doesn't jump. A button blurs the address and location for screenshots.

Privacy

To find your exits and DNS resolver the page asks a few outside services directly (named in each row: IPIP.NET, IP.SB, the Cloudflare trace on chatgpt.com, claude.ai and www.cloudflare.com, Cloudflare Radar, ip-api's DNS server, two STUN servers); they see your address as any site does. Everything else is read in the browser and stays there. The Worker answers one request, GET /api/me, with what it already sees in that request: the address, Cloudflare's request.cf data for it, the headers (cookies and Cloudflare's own left out), the address's PTR record and the server's clock, and keeps no log. After a check the page also sends its trait values (system, browser, screen, graphics card, time zone, first language, the first 8 characters of each fingerprint hash) and results to POST /api/seen, which adds one to anonymous counters (src/tally.mjs) and answers how many checks had each value: no address, no full fingerprint, no record of a single visit. "Don't count me" on the page turns it off; Global Privacy Control is honoured.

Run it yourself

git clone https://github.com/yt1988/who-are-you
cd who-are-you
npm ci
npm run dev          # wrangler dev on http://localhost:8865 (geolocation comes from Cloudflare even locally)
npm test             # public/ is up to date, and the unit tests
npm run smoke        # every language page in headless Chrome or Edge: all rows, blanks and checks filled, sharing works
npm run og           # re-render the link-preview images (public/og/)
npx wrangler deploy  # deploy the Worker "who"; then add a custom domain in the dashboard

npm run build regenerates public/ from src/. Set SITE_URL for your own domain (canonical links, sitemap, llms.txt). npm run tz refreshes the time zone → country table from the tz database.

Layout

src/worker.js     GET /api/me: what the server sees
src/sniffers.mjs  every sniffer row, the portrait's blanks and the checks
src/infer.mjs     what the readings mean: OS, browser, GPU, keyboard, data centers, nationality, checks (unit tested)
src/app.js        the page: runs the sniffers, fills the rows, the paragraph and the checks
src/i18n/         10 languages
scripts/build.mjs builds public/ (one page per language, CSP, sitemap)

License

MIT

About

Who do websites think you are? A privacy self-check: every sniffer any site can run, the portrait they paint, and the contradictions that give away a VPN or proxy

Topics

Resources

Stars

225 stars

Watchers

2 watching

Forks

Releases

Packages

Contributors

Languages