What Your Browser Headers Reveal About You

Updated 2026-08-137 min read5 sections
Advertisement
Short answer

Every HTTP request carries headers describing your browser, operating system, language preferences and where you came from. Individually they are unremarkable; combined, they typically identify a browser to within a few thousand others, and Accept-Language is usually the most revealing of them.

See your own headers first

Before theorising about what leaks, look at what your browser sends. Open the developer tools with F12 or Command-Option-I, go to the Network tab, reload the page, click the top-level document request, and read the Request Headers section. That is exactly what the server received.

For a copy you can compare against another browser, several services echo the headers back as JSON. The command-line equivalent shows what a bare client sends, which is a useful contrast: the difference between the two lists is the information your browser volunteers beyond what the protocol requires.

curl -s https://httpbin.org/headers
curl -s https://ifconfig.co/json

# compare a bare request against a browser-like one
curl -sD - -o /dev/null https://example.com
curl -sD - -o /dev/null -A "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36" https://example.com
note

Headers are sent in plaintext to the server but are encrypted in transit under TLS. Your ISP cannot read them. The server, every CDN and reverse proxy in front of it, and any third-party domain the page loads resources from, all can.

The headers that carry the most information

Not all headers are equally revealing. Ranked roughly by how much they narrow you down from the general population:

Accept-Language is frequently the most identifying header in a typical request, and almost nobody thinks about it. A value of en-US,en;q=0.9 is extremely common in the United States and carries little information. A value like en-GB,en;q=0.9,fr-CA;q=0.8,ja;q=0.7 reflects a specific person's configured preferences and is rare enough to be close to unique. It also directly contradicts a VPN exit in a country whose language is absent from your list, which is one of the cheapest geo-inconsistency checks a service can run.

User-Agent describes browser, engine, version and platform. It used to be the primary fingerprinting header; deliberate reduction has cut its entropy substantially, but it still distinguishes operating system, browser family and major version.

Accept and Accept-Encoding describe supported media types and compression. Modern browsers send near-identical values, so these carry little information for a real browser but instantly identify non-browser clients, which is why they matter for bot detection.

Referer reveals the previous page, including its full URL and any parameters in it unless a referrer policy trims them. This is a genuine content leak rather than a fingerprinting concern: it can expose search terms, internal document paths, and identifiers embedded in URLs.

Cookie is the direct identifier and needs no inference. Everything else in this article matters mainly because it works when cookies do not.

Header order itself is a signal. Browsers emit headers in a consistent sequence per engine and version, and a client that sends the right headers in the wrong order is detectable as automation regardless of the values.

Client Hints and User-Agent reduction

Chrome's User-Agent reduction froze the detailed parts of the string. The platform version is reported as a fixed value, the minor version digits are zeroed, and device model on Android is emptied. A modern Chrome User-Agent therefore carries much less information than it did, which is a real privacy improvement rather than a cosmetic one.

The replacement is User-Agent Client Hints, a set of Sec-CH-UA-* headers. Three are sent on every request by default because they are considered low entropy: Sec-CH-UA listing browser brands and major versions, Sec-CH-UA-Mobile as a boolean, and Sec-CH-UA-Platform naming the operating system.

The rest are high entropy and are sent only when a site explicitly requests them by returning an Accept-CH response header. These include Sec-CH-UA-Platform-Version, Sec-CH-UA-Arch, Sec-CH-UA-Bitness, Sec-CH-UA-Model and Sec-CH-UA-Full-Version-List.

The design intent is to make high-entropy disclosure an active, observable request rather than a passive default, which permits browsers and researchers to see which sites are asking. The practical effect for a user is that a site determined to fingerprint you can still obtain most of what the old User-Agent contained, by asking for it.

Note the brand list in Sec-CH-UA deliberately includes a fabricated brand with a randomised name, such as Not-A.Brand, to break naive string parsing. Seeing it is normal and not a sign of anything unusual.

  • Firefox and Safari do not implement the full Client Hints set, sending only a conventional User-Agent.
  • Client Hints are sent only over HTTPS and, for third-party requests, only when delegated by a Permissions-Policy.
  • A request with Sec-CH-UA-Platform: "Windows" and a User-Agent claiming macOS is an obvious inconsistency and is used as a bot signal.
# a site opts in to high-entropy hints with a response header
Accept-CH: Sec-CH-UA-Platform-Version, Sec-CH-UA-Model, Sec-CH-UA-Arch

# typical default hints sent by Chrome
Sec-CH-UA: "Chromium";v="141", "Not-A.Brand";v="8", "Google Chrome";v="141"
Sec-CH-UA-Mobile: ?0
Sec-CH-UA-Platform: "macOS"
Advertisement

The Sec-Fetch family and Global Privacy Control

The Sec-Fetch-* headers describe the context of a request rather than the client. Sec-Fetch-Site states whether the request is same-origin, same-site, cross-site or none. Sec-Fetch-Mode gives the request mode, such as navigate or cors. Sec-Fetch-Dest names what the result will be used for: document, image, script, style. Sec-Fetch-User is present only when a user gesture initiated a navigation.

They exist for security, giving servers a reliable way to reject cross-site requests they never intended to serve, which mitigates certain classes of cross-site attack. They also make automation detectable, because headless tooling frequently sends combinations a real browser never produces, such as Sec-Fetch-Dest: document on a subresource fetch, or omits Sec-Fetch-User on a navigation that should have had a gesture.

Global Privacy Control, sent as Sec-GPC: 1, is a legally weighted successor to Do Not Track. Where DNT was purely advisory and was ignored so consistently that browsers removed it, GPC is recognised as a valid opt-out signal under the California Consumer Privacy Act and several other US state privacy statutes. Businesses covered by those laws are required to honour it as a request to opt out of sale or sharing of personal information.

Enable it in Firefox under Settings, Privacy and Security, Website Privacy Preferences. Brave and DuckDuckGo send it by default. Chrome does not offer a built-in toggle and requires an extension. It is one of the few privacy signals with actual legal weight behind it, though enforcement remains uneven.

warning

Do Not Track (DNT: 1) is deprecated and has been removed from Firefox's interface. It was never binding, was widely ignored, and sending it added a fingerprinting bit while providing no protection. Send GPC instead.

What you can actually change, and what backfires

Normalise Accept-Language. If you have accumulated multiple languages in your browser preferences, trim the list to the one or two you use. In Chrome this is under Settings, Languages; in Firefox under Settings, General, Language, Choose. A common value blends in; an unusual one does not, and it also stops contradicting your apparent location.

Tighten the referrer policy. Chrome and Firefox default to strict-origin-when-cross-origin, which sends only the origin to other sites rather than the full URL. That is a reasonable default. Firefox users can go further by setting network.http.referer.XOriginPolicy to 2 in about:config, which sends a referrer only to the same base domain. Expect some sites to break.

Do not spoof your User-Agent with an extension. This is the most common mistake in this area. A spoofed string contradicts the JavaScript environment, the Client Hints values, the TLS fingerprint and the rendering behaviour, and the contradiction is more identifying than an honest string would have been. Consistency is what makes you common; inconsistency is what makes you memorable.

If you want meaningful header uniformity, use a browser that pursues it as a design goal. Tor Browser deliberately makes every user present an identical header set, which is only possible because it also standardises window size, disables high-entropy APIs and accepts the resulting usability cost. Firefox's privacy.resistFingerprinting applies a subset of the same approach, and breaks a corresponding subset of sites.

Finally, keep the relative weight in mind. Headers are one input among several. TLS fingerprinting operates below HTTP and cannot be edited from the browser, and canvas, font and audio fingerprinting run above it in JavaScript. Normalising headers is worth doing and is not sufficient on its own.

# Firefox about:config, meaningful and low-breakage
network.http.referer.XOriginPolicy = 2
network.http.referer.XOriginTrimmingPolicy = 2
privacy.globalprivacycontrol.enabled = true

# higher protection, expect breakage
privacy.resistFingerprinting = true

Frequently asked

Which HTTP header reveals the most about me?

Accept-Language, more often than not. A single common value like en-US,en;q=0.9 reveals little, but a list of several languages with custom quality weights is rare enough to be nearly unique, and it contradicts a VPN exit in a country whose language you do not list. Trim it to the languages you actually use.

Does changing my User-Agent protect my privacy?

Usually the opposite. A spoofed string contradicts your Client Hints, JavaScript environment, TLS fingerprint and rendering behaviour, and that inconsistency is itself highly identifying. Blending in requires internal consistency, which spoofing extensions cannot deliver. Leave it alone unless you are using a browser designed for uniformity.

What is Sec-GPC and should I enable it?

Global Privacy Control is a header signalling that you opt out of the sale or sharing of your personal information. Unlike Do Not Track it has legal force under the CCPA and several other US state laws, so covered businesses must honour it. Enable it in Firefox under Privacy and Security; Brave and DuckDuckGo send it by default.

Can my ISP see my HTTP headers?

No, not on HTTPS sites, which is essentially all of them. Headers are encrypted inside the TLS session. Your ISP sees the destination IP address and, unless Encrypted Client Hello is in use, the server name in the TLS handshake. The headers themselves are visible only to the server and its CDN or proxy.

Are Client Hints better or worse for privacy than the User-Agent?

Better in default posture, because high-entropy details are withheld unless a site explicitly requests them with an Accept-CH header, which makes the request observable. Worse in the sense that a determined site can still obtain nearly everything the old User-Agent contained simply by asking, and most users never see that it asked.

Advertisement

Related reading

Run the diagnostics on your own connection