Sign up below to view device data and get your trial account.

We communicate via email to process your request in line with our privacy policy. Please check the box to give us your permission to do this.

Cancel

Obtaining high-entropy User-Agent Client Hints in the first request

In certain cases it may be possible to obtain high entropy User-Agent Client Hints in the first request from a browser.

One of the biggest issues with User-Agent Client Hints (UA-CH) is that, by their nature, they are sent by browsers only after being requested to do so by a web server. This means that they are necessarily only available on requests subsequent to the first one from a given client. This limitation is by design but severely disrupts many web use cases such as server-side adapation and analytics. This limitation of client hints has been one of the most controversial aspects of the proposal since its inception. Indeed, this is the subject of issue #2 lodged against the proposal (by DeviceAtlas).

Google are aware of this issue and have proposed two mitigations:

  • A Critical-CH response header. This response header asks the browser to retry the request if it agrees to furnish the addiitonal requested UA-CH headers. This is not particularly useful since it doesn't help at all with the additional round trip required.
  • A TLS handshake mechanism. This is a more useful mitigation in that it can make UA-CH headers available on the first request with certain limitations.

The TLS handshake mechanism uses an extension to the TLS protocol called Application-Layer Protocol Settings or ALPS. As the name suggests, ALPS allows for application-layer protocol settings to be agreed at the TLS level prior to any HTTP requests taking place. ALPS is a Google-led proposal and is being managed in the IETF as an Internet Draft.

 

ALPS TSL sequence diagram

Source: Google

BoringSSL and NGINX

At present there is only one TLS library that supports ALPS: BoringSSL, a Google fork of OpenSSL designed to be easier to maintain. BoringSSL is currently the SSL library in use in Chrome/Chromium and Android.

It is possible to compile NGINX against BoringSSL rather than OpenSSL. This, along with some additional configuration directives in a forked verison of NGINX, enables full control of high-entropy User-Agent Client Hints at a TLS level. Once configured correctly this permits high-entropy UA-CHs to be available in the first request from a newly-seen browser. 

Implementors should be aware that this TLS ALPS approach does have the limitation that it works only at a global level for a particular domain. As an example, you cannot configure this method to request different UA-CHs for example.com/pathA and example.com/pathB.

Example implementation

Boring-nginx is a version of NGINX built on BoringSSL rather than OpenSSL. Aaron Tagliaboschi has put together a Docker image of BoringNginx with some additional configuration parameters to enable high-entropy UA-CHs to be requested at the TLS level. This is a good starting point for testing implementations of TLS ALPS in conjunction with UA-CH.

DeviceAtlas has tested this approach and can confirm that it works correctly with Chrome.