Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support of UA client hints in Mobile-Detect #906

Open
kdeckard opened this issue Nov 23, 2022 · 5 comments
Open

Support of UA client hints in Mobile-Detect #906

kdeckard opened this issue Nov 23, 2022 · 5 comments

Comments

@kdeckard
Copy link

Issue description

Hi,

we are using Mobile-Detect in one of our projects and are currently investigating the impact of the upcoming reduced UA strings in Chromium and Chromium based browsers (https://www.chromium.org/updates/ua-reduction/).

As the Chromium-ecosystem as a whole will shift towards the new UA client hints, I wanted to ask if there are any plans to support the client hints any time soon?
I know that it was already asked over 2 years ago here, but are there maybe any updates to it?

Links for reference on the UA client hints:

User-Agent(s)
Suggestions

@serbanghita
Copy link
Owner

@kdeckard thank you for bringing this up again!

Client Hints enforce a model where the server must ask the browser for a set of data about the client (the hints) and the browser applies its own policies or user configuration to determine what data is returned.

I like the idea of the server to explicitly require for full/partial browser specs. eg. Accept-CH: Sec-CH-UA-Full-Version-List.
It's unclear to me if this requires two requests, or the first one is an OPTION request.

By default, the browser returns the browser brand, significant / major version, platform, and an indicator if the client is a mobile device:

Sec-CH-UA: "Chromium";v="93", "Google Chrome";v="93", " Not;A Brand";v="99"
Sec-CH-UA-Mobile: ?0
Sec-CH-UA-Platform: "macOS"

This is horrible.
The only advantage is that this is more explicitly declared in a key/value structure (HTTP headers).

Sec-CH-UA-Model | "Pixel 3" | The device model.

So Sec-CH-UA-Model will contain the device label (name) per-se, still from my experience with User-Agents, manufacturers will attempt to inject their own tokens/headers: https://github.com/serbanghita/Mobile-Detect/blob/5.x/tests/providers/vendors/ZTE.php#L7

I think there's the firmware build missing from the specs. There are multiple Android 12 builds https://github.com/serbanghita/Mobile-Detect/blob/5.x/tests/providers/vendors/Samsung.php#L253-L257

UA reduction Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.0.0 Mobile Safari/537.36

Sure this is a theoretic win to privacy but it doesn't make sense without weighting in pros/cons.
First Chrome/93.0.0.0.0 will be really confusing to debug when customers report UI bugs due to a minor browser update.
Second, replacing the device name SM-A205U with K can actually trigger false assumptions by existing sniffers. In Mobile_Detect case, we could no longer determine if the device is a tablet or a simple phone.

I would simply go with a backward compatible refactor of UA.

Old UA: Mozilla/5.0 (Linux; Android 9; SM-T810) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.1234.56 Safari/537.36

New UA: Chrome/93.0.1234.56 ; Android/9 ; Linux ; SM-T810 ; {{GARBAGE STRINGS}}

So the new structure will be Browser/ver ; OS/ver/build ; OS Family ; Device name ; {{GARBAGE STRINGS}}

@kdeckard
Copy link
Author

kdeckard commented Nov 25, 2022

Hi,

so the client hints will basically require subsequent requests after the first one, if the server needs more detailed information.

Roughly broken down:

The client only sends the so called low entropy headers on the first request, which contain information, which is considered non sensitive. These include the headers: Save-Data, Sec-CH-UA, Sec-CH-UA-Mobile and Sec-CH-UA-Platform.
I am also quite sure that a client could decide to bail out here and don't send any headers on the first request at all, which would leave the server without any information.

All other information need to be requested by the server on demand via the the Accept-CH. When the client then supports the hints, it can choose to append the information in subsequent requests.

Interestingly, there are mechanisms, which could be used like escape hatches. The proposal sums them up under the term client hint reliability.

A server can define the Critical-CH response header along with Accept-CH in it`s first response to a client. The client then should check if the "critical headers" were included in the first request. If not, it should re-send it automatically.

Example from MDN:

Server response:

HTTP/1.1 200 OK
Content-Type: text/html
Accept-CH: Sec-CH-Prefers-Reduced-Motion
Vary: Sec-CH-Prefers-Reduced-Motion
Critical-CH: Sec-CH-Prefers-Reduced-Motion

Client retry:

GET / HTTP/1.1
Host: example.com
Sec-CH-Prefers-Reduced-Motion: "reduce"

The emphasis here is on should, as for example Chrome supports it but Edge not (at least accordingly to DeviveAtlas and I could not find more on it in MS documentation).


Regarding your concerns about the reduced UA strings in Chrome:

In Mobile_Detect case, we could no longer determine if the device is a tablet or a simple phone.

Correct, that will be the case. They will completely remove the device information from the UAs and you can no longer make assumptions on it for mobile devices. The final rollout will be Chrome 113 with release scheduled for Tue, May 2, 2023 (https://chromiumdash.appspot.com/schedule).

Only platform not affected by it will be IOS / IpadOS and WebView.

@serbanghita
Copy link
Owner

@kdeckard thank you for driving the discussion!

so the client hints will basically require subsequent requests after the first one, if the server needs more detailed information.

The client only sends the so called low entropy headers on the first request, which contain information, which is considered non sensitive.

I like this idea of asking the client while the server can be configured by default to asking for more info or not.

I just don't like the implementation. I was expecting something much more simple.
This should be like the CORS "preflight" request, via OPTIONS, where the browser client asks "hey can I actually perform this request?".

Here is my understanding so far:

I believe that if you implement a detection solution at the PHP-level, you will have a round trip.
Most of websites are on shared hosting, say an Apache that might be configured in a conservative way (e.g. "don't request any additional headers by default"). So as a developer I have to make sure my index.php has an Accept-CH header with as many values as I need for detection to work: Device-Memory, DPR, Viewport-Width, ... and so on. Only after this, the library will be able to pick up details from the subsequent HTTP request headers.

My guts tells me that we're underestimating the power of the User-Agent header string, just like I underestimated the actual use case of the Mobile_Detect library ... I thought this will die in 2 years max since I took over the development.

We need to look inward to what we have rather then invent new HTTP headers and properties, which will lead to custom parsing techniques and opinionated rules anyway.

@serbanghita serbanghita self-assigned this Nov 25, 2022
@Maikuolan
Copy link
Contributor

We need to look inward to what we have rather then invent new HTTP headers and properties, which will lead to custom parsing techniques and opinionated rules anyway.

I strongly agree. Unfortunately, it seems reality is often more like this:

Standards

@digifa
Copy link
Contributor

digifa commented Nov 8, 2024

@serbanghita I suggest you should close the discussion here or in #942 it is confusing to follow the actual discussion. Also you should refer all other issues regarding to this problem to one discussion. At the moment it seems as if there are a lot of open issues all regarding to this topic.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants