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

CORS eats custom board backgrounds #675

Closed
Archenoth opened this issue May 15, 2023 · 5 comments
Closed

CORS eats custom board backgrounds #675

Archenoth opened this issue May 15, 2023 · 5 comments
Labels
bug Something isn't working

Comments

@Archenoth
Copy link

So! When you set a custom board image, it loads nicely on most pages!
board with the background loaded sucessfully
(Image source, plus a direct url link here if you wanted to test it)

However, on Puzzles, User Analysis, the normal Analyze page, Practice, Relay, and Studies, the board instead looks like this
board without the background loaded, also my embarrassingly low puzzle score is visible here (it's 1164)

And on these pages, this message shows up in the console:
the CORS error in the console

I've narrowed it down to the server replying with "Cross-Origin-Opener-Policy: same-origin" when looking at a lot of pages (the broken ones)
response headers for a request to the /training/daily page, with the Cross-Origin-Opener-Policy being set to "same-origin" highlighted for emphasis

...but not all! (the working ones)
response headers for a request to a page where i'm playing an ai, which doesn't have Cross-Origin-Opener-Policy set

These headers are added in this method!

protected def EnableSharedArrayBuffer(res: Result)(implicit req: RequestHeader): Result =
res.withHeaders(
"Cross-Origin-Opener-Policy" -> "same-origin",
"Cross-Origin-Embedder-Policy" -> (if (HTTPRequest isChrome96OrMore req) "credentialless"
else "require-corp")
)

Which is called when loading all of the pages that break custom board URLs:
a reference search for the LilaController#EnableSharedArrayBuffer method, which shows it is called in all of the pages previously mentioned that were broken

It looks like the original reason this header was added was to enable multi-threaded WASM in firefox, though I'm not 100% sure how this is related, or if there is a workaround

Is there a way that custom board URLs could be used on all pages across the interface..? (And is there anything I could do to help if there is?)

@Archenoth Archenoth added the bug Something isn't working label May 15, 2023
@WandererXII
Copy link
Owner

Hey! Thanks for submitting the issues.

To get WASM engines to work we need to have:
Cross-Origin-Embedder-Policy "require-corp".
This unfortunately means that all loaded resources need to have: Cross-Origin-Resource-Policy: cross-origin.

Chrome supports credentialless instead of require-corp header (more about that here https://developer.chrome.com/blog/coep-credentialless-origin-trial/), which eliminates that need, so with chrome it should work.

It seems firefox supports it as an origin trial - mozilla/standards-positions#539 (comment). But lishogi wouldn't recognize that anyway, since we only check for chrome and there were/are some issues with it? Might need to look into it.

I might set up a proxy on heroku later tomorrow as a dirty solution. Another option would be to host all the images on lishogi...

In short, the image needs to have this header: Cross-Origin-Resource-Policy: cross-origin.

@WandererXII
Copy link
Owner

Deployed this: https://github.com/WandererXII/cors-anywhere to render.com.

Simply append the URL with your picture to https://lishogi-proxy.onrender.com/

For your image replace the link you use with this: https://lishogi-proxy.onrender.com/https://pbs.twimg.com/media/Ft0PzuiakAAcXiF?format=jpg&name=orig and it should work.

I can't guarantee that render.com will keep hosting the proxy, but for now it should work.

@Archenoth
Copy link
Author

Oh dang! Thank you! I can confirm this works!

Though, if changing CORS stuff is hard, another thing that I sometimes do to get around things like this is to copy the base64 URI of an image so that it doesn't need to be hosted from a third party
the right click context menu of an image in the firefox web inspector copy section with the option to copy the "Image Data-Url" highlighted

The benefit of that is that images can't be hotlinked by third party sites, since the img src is just the image data itself, and it works without any additional setup

However, the downside of that is that those URIs can also be really long, so you'd want to enforce a reasonable length per user. Also, the TS rejects any URIs that start with anything besides https:// or //:

export function validateUrl(url: string): boolean {
// modules/pref/src/main/PrefForm.scala
return url === '' || ((url.startsWith('https://') || url.startsWith('//')) && url.length >= 10 && url.length <= 400);
}

I'm not saying you should do this or anything, but I wanted to bring it up in case you didn't want to maintain a separate proxy altogether~ (Also, thanks again for setting that up! I really do appreciate it!)

@WandererXII
Copy link
Owner

Oh dang! Thank you! I can confirm this works!

Though, if changing CORS stuff is hard, another thing that I sometimes do to get around things like this is to copy the base64 URI of an image so that it doesn't need to be hosted from a third party

The benefit of that is that images can't be hotlinked by third party sites, since the img src is just the image data itself, and it works without any additional setup

However, the downside of that is that those URIs can also be really long, so you'd want to enforce a reasonable length per user. Also, the TS rejects any URIs that start with anything besides https:// or //:

Glad it works!

Allowing the data-url could work, but the data-url would have to be sent from the server with every html doc, which would be rather inefficient. Also storing big data-urls in the pref collection in db could deteriorate performance/memory usage.

I considered to host the images myself on a separate server, providing upload an image button to users, rather than paste a link. But for now I don't wanna get into that.
The current implementation works for chrome based browsers (https://caniuse.com/mdn-http_headers_cross-origin-embedder-policy_credentialless), the issue is firefox and safari. Hopefully firefox will soon start suporting credentialless.

@Archenoth
Copy link
Author

This makes sense! And thanks again for the help..!

Since there really isn't anything else that can be done, I think I'll close this issue for now~

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants