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

Ability to detect browser variant / fork #503

Open
carlosjeurissen opened this issue Dec 6, 2023 · 17 comments
Open

Ability to detect browser variant / fork #503

carlosjeurissen opened this issue Dec 6, 2023 · 17 comments
Labels
inconsistency Inconsistent behavior across browsers proposal Proposal for a change or new feature supportive: chrome Supportive from Chrome supportive: firefox Supportive from Firefox supportive: safari Supportive from Safari

Comments

@carlosjeurissen
Copy link
Contributor

carlosjeurissen commented Dec 6, 2023

Issue description

For extension developers, being able to detect what kind of browser the extension is running in is very useful for several reasons:

  • Extensions can be installed from various stores and do not always have a 1:1 relationship
  • Certain browsers have different UI/UX considerations. For example, Firefox does not have an "options" context menu on the action icon. And the Arc Browser opens extension popups in a tab rather than as an extension popup.

As some will probably mention in this thread, generally speaking, for feature detection, it is bad practice to base code on what kind of browser is detected. However as some examples above tells us, sometimes there is no alternative and we have to rely on browser detection.

The issue: currently detecting browsers is very hacky. We can base it upon the user agent, however many browsers, especially forks use the user agent of the main browser to prevent web pages from reducing the performance (in a broad sense) of their website for a specific browser. Examples of such browsers are Vivaldi and Arc.

Potential solutions

1: Extend and standardise browser.runtime.getBrowserInfo

Currently Mozilla Firefox supports the browser.runtime.getBrowserInfo, this could be extended with variant information. See: https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/Runtime/getBrowserInfo

The only downside would be it's async nature. The variant detection is often used by developers for flags.

2: Extended userAgent for extensions

Basically serve a different userAgent string to extensions which include more info than browsers are willing to send to webpages. Downside for this is the fact it becomes harder for extensions to get the original userAgent which is sent to normal webpages.

3: Extended userAgentData for extensions

Basically serve userAgentData brands to extensions which include more info than browsers are willing to send to webpages. Downside for this is the fact it becomes harder for extensions to get the original userAgentData which is sent to normal webpages.

4: Introduce a browser.runtime.variants which could contain an Array of keywords which specify variants. In the case of Vivaldi, this could be:

["CHROMIUM", "VIVALDI"]

In the case of Thunderbird, this could be:

["GECKO", "THUNDERBIRD"]

This way a developer could do a check like browser.runtime.variants.includes("CHROMIUM").

End words

In general the concept is to make sure we do this in a cross browser and in an elegant way. The reason for starting this discussion now is that it seems the developers of Orion plan to implement some kind of detection in there browser. See the following thread:
https://orionfeedback.org/d/5549-extensions-are-unable-to-detect-orion-as-a-browser

@carlosjeurissen carlosjeurissen added inconsistency Inconsistent behavior across browsers proposal Proposal for a change or new feature and removed needs-triage labels Dec 6, 2023
@bershanskiy
Copy link
Member

Could you please clarify the specific browser you are not able to identify? Web platform already has navigator.userAgent and navigator.userAgentData (Chromium-based browsers) for this exact purpose. There are some issues with this approach (e.g., for Vivaldi), but it works rather well.

@dotproto
Copy link
Member

dotproto commented Dec 6, 2023

I was also going to ask if navigator.userAgentData.brands provided the information you're after, @carlosjeurissen. Current browser support is limited to Chromium, but if theres interest from this group we might want to follow up with WICG ua-client-hints to see how this is progressing.

const brands = navigator.userAgentData.brands.map(entry => entry.brand.toLowerCase());
if (brands.includes("chromium") {
    if (brands.includes("chrome") {/*...*/}
    else if (brands.includes("microsoft edge") {/*...*/}
    else if (brands.includes("vivaldi") {/*...*/}
    else if (brands.includes("vivaldi") {/*...*/}
    else if (brands.includes("chrome") {/*...*/}
    else {/* Chromium and forks that don't identify themselves (e.g. Arc) */}
} else {/* handle non-chromium browsers */}

@tophf
Copy link

tophf commented Dec 6, 2023

Some browsers like Vivaldi or Orion intentionally don't expose themselves in userAgent and userAgentData.brands, so I don't see why they would suddenly do it in this new API.

@carlosjeurissen
Copy link
Contributor Author

carlosjeurissen commented Dec 7, 2023

Could you please clarify the specific browser you are not able to identify? Web platform already has navigator.userAgent and navigator.userAgentData (Chromium-based browsers) for this exact purpose. There are some issues with this approach (e.g., for Vivaldi), but it works rather well.

Thanks for pointing out the navigator.userAgentData. This indeed helps with many of the browser variants. The browsers which seems still to be undetectable (and support browser extensions in some form) are:
Vivaldi (tested on MacOS), potentially because of WICG/ua-client-hints#293
Arc (tested on MacOS)
Orion (tested on MacOS)
Kiwi (tested on Android)

I was also going to ask if navigator.userAgentData.brands provided the information you're after, @carlosjeurissen.

See above. Not all browsers are detectable currently with userAgentData.

but if there's interest from this group we might want to follow up with WICG ua-client-hints to see how this is progressing.

Good one. Depending on how the conversation goes in this issue, having a conversation specifically on the extension use-case could turn out to beneficial.

Some browsers like Vivaldi or Orion intentionally don't expose themselves in userAgent and userAgentData.brands, so I don't see why they would suddenly do it in this new API.

My current impression being browsers decide not to expose this specifically to websites. @tophf are you aware some browsers intentionally try to hide themselves for browser extensions?

Again to clarify, the goal of the issue is to find a workable solution for extension developers specifically. Not sure how the userAgentData works under the hood. But would it be easy for a browser to serve different userAgentData information to extensions versus normal webpages?

@tophf
Copy link

tophf commented Dec 7, 2023

Their (apparently naive) logic applies to extensions just as well, i.e. I don't see any reason why they would exclude them.

@yankovichv
Copy link

yankovichv commented Dec 7, 2023 via email

@carlosjeurissen
Copy link
Contributor Author

Their (apparently naive) logic applies to extensions just as well, i.e. I don't see any reason why they would exclude them.

@tophf So far I do not know of any extension purposely using the userAgent information to block a specific browser. What specific logic would apply to extensions as well?

Browsers hide their agents to hide their real marker share. And extensions are the main providers of analytical data. So I'm sure that none of the browsers listed above will reveal their agent to the extension.

@yankovichv at least Orion seems supportive of exposing themselves to extensions in some form.

@yankovichv
Copy link

yankovichv commented Dec 7, 2023 via email

@tophf
Copy link

tophf commented Dec 7, 2023

So far I do not know of any extension purposely using the userAgent information to block a specific browser. What specific logic would apply to extensions as well?

I don't understand how this is related to what I wrote. I'll try to rephrase: some browser makers consider the idea of exposing their brand in UA string bad because they [naively] think it only encourages bad programming patterns. I argued that the same logic would apply to extensions just the same, i.e. I don't see any reason for these makers to consider extensions any different.

A more realistic solution might be to add a method to question which UI elements are present e.g. chrome.runtime.getUiFeatures that returns an object, probably asynchronously.

@oliverdunk
Copy link
Member

oliverdunk commented Dec 7, 2023

As a note, a (definitely unideal) solution already implemented for Brave is navigator.brave.isBrave(): https://github.com/brave/brave-browser/wiki/Detecting-Brave-(for-Websites)

@carlosjeurissen
Copy link
Contributor Author

@oliverdunk Thanks for noting.

As dino mentioned in https://orionfeedback.org/d/5549-extensions-are-unable-to-detect-orion-as-a-browser/5, it seems one can currently detect orion with window.KAGI. I have not tested this yet so can't confirm right now.

@Rob--W
Copy link
Member

Rob--W commented Jan 4, 2024

Under the assumption that browser vendors are more willing to expose detailed browser info to extensions than web pages, option 1 would be preferable. However, there is only value in offering such a method if it were to be adopted by all forks of interest.

@dotproto is going to reach out to some other vendors and comment on this issue.

@dotproto
Copy link
Member

I spoke with an Arc engineer and they indicated that making their browser more easily identifiable is not a problem they're trying to solve. I'm still working on reaching out to other vendors.

@carlosjeurissen
Copy link
Contributor Author

@dotproto thanks for confirming! Not a problem they are trying to solve. Does this mean they are open to it or actively want their browser to go undetected?

@tophf
Copy link

tophf commented Jan 18, 2024

...or they don't see any benefit in solving it.

@regseb
Copy link

regseb commented Sep 6, 2024

For solution 1, there's an open issue in Chromium to add support for runtime.getBrowserInfo.

@xeenon xeenon added the supportive: safari Supportive from Safari label Sep 24, 2024
@carlosjeurissen carlosjeurissen added needs-triage: chrome Chrome needs to assess this issue for the first time needs-triage: firefox Firefox needs to assess this issue for the first time labels Sep 24, 2024
@Rob--W Rob--W added supportive: chrome Supportive from Chrome supportive: firefox Supportive from Firefox and removed needs-triage: chrome Chrome needs to assess this issue for the first time needs-triage: firefox Firefox needs to assess this issue for the first time labels Sep 28, 2024
@Rob--W
Copy link
Member

Rob--W commented Sep 28, 2024

Following a discussion at TPAC 2024 (#659), everyone is supportive of a constant exposing the info. The next step is for someone to author a proposal.

Meeting notes of the discussion will be published soon.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
inconsistency Inconsistent behavior across browsers proposal Proposal for a change or new feature supportive: chrome Supportive from Chrome supportive: firefox Supportive from Firefox supportive: safari Supportive from Safari
Projects
None yet
Development

No branches or pull requests

9 participants