w3c / webextensions

Charter and administrivia for the WebExtensions Community Group (WECG)
Other
578 stars 50 forks source link

Ability to detect browser variant / fork #503

Open carlosjeurissen opened 6 months ago

carlosjeurissen commented 6 months ago

Issue description

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

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

bershanskiy commented 6 months ago

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 commented 6 months ago

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 commented 6 months ago

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 commented 6 months ago

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 https://github.com/WICG/ua-client-hints/issues/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 commented 6 months ago

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

yankovichv commented 6 months ago

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.

On Thu, Dec 7, 2023 at 12:25 PM carlosjeurissen @.***> wrote:

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 https://vivaldi.com/blog/user-agent-changes/), 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: Orion (tested on MacOS) Kiwi (tested on Android) Vivaldi (tested on MacOS) Arc (tested on MacOS)

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 https://github.com/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?

— Reply to this email directly, view it on GitHub https://github.com/w3c/webextensions/issues/503#issuecomment-1845170764, or unsubscribe https://github.com/notifications/unsubscribe-auth/ASRW3IQWWTU45P2YLTTZW6LYIGRUFAVCNFSM6AAAAABAJS43MWVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTQNBVGE3TANZWGQ . You are receiving this because you are subscribed to this thread.Message ID: @.***>

-- Uladzimir Yankovich, Founder @ Manganum (manganum.app).

carlosjeurissen commented 6 months ago

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 commented 6 months ago

Arc too. Extension support is one thing. But revealing his agents to him is a completely different matter.

On Thu, Dec 7, 2023 at 12:33 PM carlosjeurissen @.***> wrote:

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

@tophf https://github.com/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 https://github.com/yankovichv at least Orion seems supportive of exposing themselves to extensions in some form.

— Reply to this email directly, view it on GitHub https://github.com/w3c/webextensions/issues/503#issuecomment-1845181353, or unsubscribe https://github.com/notifications/unsubscribe-auth/ASRW3IUMBT5VDKPQG37H6WDYIGSQFAVCNFSM6AAAAABAJS43MWVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTQNBVGE4DCMZVGM . You are receiving this because you were mentioned.Message ID: @.***>

-- Uladzimir Yankovich, Founder @ Manganum (manganum.app).

tophf commented 6 months ago

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 commented 6 months ago

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 commented 6 months ago

@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 commented 6 months ago

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 commented 5 months ago

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 commented 5 months ago

@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 commented 5 months ago

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