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

Detection of "credentialless" vs "require-corp" backwards #20

Closed
mgc8 opened this issue Aug 1, 2023 · 6 comments · Fixed by #21 or #25
Closed

Detection of "credentialless" vs "require-corp" backwards #20

mgc8 opened this issue Aug 1, 2023 · 6 comments · Fixed by #21 or #25

Comments

@mgc8
Copy link
Contributor

mgc8 commented Aug 1, 2023

The current code contains the following lines in coi-serviceworker.js:

67    coepCredentialless: () => !(window.chrome || window.netscape),

and

44    coepCredentialless ? "credentialless" : "require-corp"

According to this logic, it says "if the browser it NOT (Chrome or Firefox), then add 'credentialless', otherwise add 'require-corp'"

However, the state of support is exactly backwards -- those are the only browsers that actually can use 'credentialless', and others (such as Safari) break when using it.

Testing with a Godot 4 app in Safari 16.5 reveals this exact behaviour -- with the current file the app is broken and we see this in the headers:
Screenshot 2023-08-01 at 01 51 36

The simple change of removing the "!" from line 67 results in the app loading (after clearing caches) and this in the headers:
Screenshot 2023-08-01 at 01 52 03

Testing the same in Chrome results in it also switching to "require-corp" but working nonetheless, since it supports both versions, however it appears the actual check at line 67 is not working as intended (the result when "true" is not a boolean but the actual "window.chrome" object!). Maybe this would work better?

coepCredentialless: () => (window.chrome !== undefined || window.netscape !== undefined),

Perhaps a more thorough review of the logic here should be conducted since the variable is used in other parts of the code as well.

@gzuidhof
Copy link
Owner

gzuidhof commented Aug 1, 2023

Ah.. thank you for sharing your findings - this looks like a bug introduced in #13

I have not tested this in various browsers, so I didn't run into this myself. Could you perhaps make a PR with the required changes?

I'm happy to then test them in a few relevant browsers in BrowserStack.

@tamo
Copy link
Contributor

tamo commented Aug 10, 2023

As far as I can see, Firefox doesn't support credentialless.
https://caniuse.com/mdn-http_headers_cross-origin-embedder-policy_credentialless
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cross-Origin-Embedder-Policy#browser_compatibility
So we should not enable coepCredentialless on Firefox.
It seems to break my web app when using Firefox (on Windows, I don't know of Mac).

Moreover, nobody should rely on window.netscape.
https://bugzilla.mozilla.org/show_bug.cgi?id=791526
https://bugzilla.mozilla.org/show_bug.cgi?id=794923
(Same for window.chrome? https://bugs.chromium.org/p/chromium/issues/detail?id=768489 )

We should not detect browsers by ourselves.
There are a number of projects like bowser.
There is also an experimental feature called userAgentData.
https://developer.mozilla.org/en-US/docs/Web/API/Navigator/userAgentData
https://caniuse.com/mdn-api_navigator_useragentdata

Therefore, false by default is not so bad in my opinion.
If it is not enough, we could consider reading navigator.userAgentData.brands and only turn on coepCredentialless for a limited range of browsers.

That said, it can be configured anyway.
In fact I don't use credentialless at all.
tamo/extsub@3422ee1

@mgc8
Copy link
Contributor Author

mgc8 commented Aug 10, 2023

As far as I can see, Firefox doesn't support credentialless

Firefox does have support for credentialless, ever since about version 104, but it's not complete to the same level as Chrome; if anything, the caniuse.com website is misleading in this case, as they should either add an asterisk to the evaluation or more accurately portray it as "amber" for "partial support".

Here is the patch from about a year ago:
https://bugzilla.mozilla.org/show_bug.cgi?id=1731778

... and the note on support from version 104:
mozilla/standards-positions#539 (comment)

At the moment, this does require enrolling in an origin trial, which is done easily just as it was for Chrome -- it is what itch.io already did, and you can apply it for your own app as well; here it is in action (check the Response headers, note that the page may take a long time to initialise due to other bugs in Firefox):
https://arturitoproductions.itch.io/coco-and-frogy

Check with:
Screenshot 2023-08-10 at 20 15 01

I am not sure there is a universal solution to this, given the current state of browsers :-/ It could be that manual configuration remains the best, as you well pointed out. Having credentialless as an option is quite important to a lot of people, since require-corp is extremely restrictive, and tends to break a lot more pages because it expects changes on remote (often third-party, inaccessible) resources.

That being said, fully agreed on the window.chrome / window.netscape manner of detecting browsers, that's a pretty fragile implementation, and anything better based on user-agent would be an improvement!

@tamo
Copy link
Contributor

tamo commented Aug 12, 2023

Thanks for the information! I'll try registering for the origin trial if I need credentialless.

So the lowest-hanging fruit at the moment may look like

// You can enable credentialless on Firefox if you use "origin-trial" (https://wiki.mozilla.org/Origin_Trials)
// but non-Chromium browsers are basically unable to handle credentialless.
coepCredentialless: () => navigator.userAgentData?.brands?.some((b) => b.brand == "Chromium")

@gzuidhof gzuidhof reopened this Aug 15, 2023
@gzuidhof
Copy link
Owner

Re-opening this issue, as I think there is space to improve the detection of user agents that support or don't support credentialless

@tamo tamo mentioned this issue Aug 29, 2023
@tamo
Copy link
Contributor

tamo commented Sep 10, 2023

So the lowest-hanging fruit at the moment may look like

// You can enable credentialless on Firefox if you use "origin-trial" (https://wiki.mozilla.org/Origin_Trials)
// but non-Chromium browsers are basically unable to handle credentialless.
coepCredentialless: () => navigator.userAgentData?.brands?.some((b) => b.brand == "Chromium")

If you want to try a diff, see master...tamo:coi-serviceworker:coep-ua-brand
though I haven't tested it (so it's not a PR)

Update: Firefox 119 seems to support credentialless now. But it doesn't have userAgentData.

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