TL;DR: Open any website and your browser immediately shares three layers of data: network information, HTTP headers and dozens of device properties readable via JavaScript — before any consent dialog exists. Combined, they form a fingerprint that re-identifies you with over 90% accuracy, without a single cookie. I built a banner for this site that shows each visitor this exact data live — computed locally, stored nowhere — and explains why, as a security professional, I refuse to fingerprint anyone.
The scenario
I keep auditing websites for a living, and there is one finding I almost never need a scanner for: the visitor itself. Most sites happily collect everything the protocol puts on the table, shrug, and call it "necessary". It is necessary — and that is exactly why it is dangerous.
So I asked myself the uncomfortable question I usually ask my clients: what does my own site reveal about you, right now, before any cookie banner exists? Instead of answering in a blog post with hand-waved percentages, I decided to show it. This site now displays a live banner under the navigation that reads your actual browser data in front of you — your IP, your headers, your GPU, your fonts, your canvas fingerprint — and then tells you exactly why I am not allowed to want that data.
The pattern
Your browser does not keep secrets. Every page load hands the server three layers of information without a single question being asked.
Layer 1: network information (protocol level)
This data is unavoidable — it is the transport itself:
- IP address — the unique address of your connection. From it, an approximate location (country, region, usually the city) and your ISP are derivable.
- Date and time — the exact timestamp of the request.
- Target URL and referrer — what you opened, and where you came from.
Layer 2: standard HTTP headers
Every request carries them, and they describe your setup precisely:
- User-Agent — browser, exact version, operating system, device class.
- Accept-Language — your language preferences and, often, your location.
- Accept / Accept-Encoding — supported formats and compression standards.
Layer 3: device properties & client hints (via JavaScript)
The moment the page loads, script can read dozens of system parameters — with or without cookies, with or without consent:
- screen resolution and color depth, window size, pixel ratio
- time zone, language list
- CPU cores (
navigator.hardwareConcurrency), estimated memory (navigator.deviceMemory) - GPU and renderer via WebGL (
WEBGL_debug_renderer_info) - installed fonts (measurable via canvas)
- battery status, network type (WiFi vs mobile, downlink, RTT)
- canvas fingerprint, touch points, platform, cookies enabled
The problem: browser fingerprinting
Taken individually, these values are dull. Combined, they are an identity. Browser version × OS × hardware × resolution × time zone × fonts is so individual that tracking services re-identify visitors with over 90% accuracy — without cookies, without identifiers, without consent.
What I built: a live transparency banner
The banner in the navigation of this site shows exactly that. Three moving parts:
1. The server echo (/api/client-info)
One tiny API route reflects what the request already transmitted: IP, geo headers, User-Agent, Accept-Language, referrer and timestamp. Nothing is logged, the response is no-store.
export async function GET(request: NextRequest) {
const h = request.headers;
const forwarded = h.get('x-forwarded-for');
const info = {
ip: forwarded ? forwarded.split(',')[0].trim() : h.get('x-real-ip'),
country: h.get('x-vercel-ip-country'),
city: decode(h.get('x-vercel-ip-city')),
userAgent: h.get('user-agent'),
acceptLanguage: h.get('accept-language'),
referer: h.get('referer'),
time: new Date().toISOString(),
};
return NextResponse.json(info, { headers: { 'Cache-Control': 'no-store' } });
}
2. The client census
A small script — still running in your browser — collects what JavaScript can read anyway: screen, time zone, cores, memory, WebGL renderer, font detection over canvas, battery, connection type, touch points, DNT flag. It then derives one additional value: a canvas fingerprint hash.
3. The local fingerprint
All browser-side values are combined into a single hash — computed locally, displayed in the panel, never transmitted. That one line is the point of the whole exercise: a fingerprint is not a hypothetical. It is twenty plain values you produce on every page load, and one hash a tracker would compute the same way.
Where it stops
The banner is a mirror, not a collector:
- everything is computed and rendered in the visitor's browser
- nothing is stored — no cookies, no localStorage, no logs
- the only server contact is the echo of data the browser transmits anyway
- no fingerprint hash ever leaves the page
For honesty's sake the banner says it: the site runs Vercel Web Analytics — cookieless, anonymous counts, no re-identification, no profile.
Reproducing it in the lab
I verified the banner the same way I verify audit findings: headless browser, fresh profile, no interaction. The panel filled with real values instantly — Chrome version, macOS, Europe/Berlin, 10 cores, 32 GB memory, ANGLE (Apple, ANGLE Metal Renderer: Apple M1 Max), 14 fonts detected, a canvas hash, battery at full charge. Every value came from the machine that asked for the page. That is the point: nobody needed permission for any of it.
The experiment also documents its own limits: Do Not Track is not set by default, the geo layer is only as precise as the hosting provider's database, and browsers disable parts of the API surface (for example, reading memory or battery) differently.
How you protect yourself
| Measure | What it breaks |
|---|---|
| Brave / hardened Firefox (resist fingerprinting) | Reported canvas/WebGL values become generic |
| Canvas and font blocking extensions (uBlock, CanvasBlocker) | Canvas hash and font list stop being unique |
| VPN or trusted residential proxy | IP-derived location and ISP disappear |
| Spoofed time zone / language | Another entropy source falls away |
| Browser updates | Old-version entropy disappears |
How site owners do it better
- Don't collect what you don't need — the cheapest data protection is deletion.
- Don't request client hints (
Accept-CH) — they turn opt-in entropy into default transmission. - Send a strict
Referrer-Policyand cut referrer leakage to third parties. - Consent first, tracking only after opt-in — anything else is a regulatory accident.
- Be transparent by default: if a visitor can see what a page reads about them, the site has already told the truth.
The bottom line
Browsers are built for convenience, not discretion. As long as that stays true, fingerprinting will remain the background radiation of the web — and the best defense is not another tool, but understanding: what is transmitted, what can be derived, and who is allowed to combine it. My banner simply makes the invisible legible.
If you visit this site, you can see it yourself — right under the navigation.