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

Empty login window on pages that use Cross-Origin-Opener-Policy: same-origin #5769

Open
cdrini opened this issue Aug 28, 2023 · 6 comments
Open

Comments

@cdrini
Copy link
Contributor

cdrini commented Aug 28, 2023

Neither the bookmarklet or the Chrome extension works on https://simonwillison.net/2023/Aug/27/wordcamp-llms/ . Tested both Firefox and Chrome.

The UI appears, but it can't log in. Here are the errors in the console:

Upon clicking loading hypothesis:

image

Upon clicking Log in:

image

and the hypothesis UI displays "Error: Failed to open login window". The login window does open, but it's empty

image

The login window displays the following errors:

image

@cdrini
Copy link
Contributor Author

cdrini commented Aug 28, 2023

Oh it started working now! Must've been a fluke

@cdrini cdrini closed this as not planned Won't fix, can't repro, duplicate, stale Aug 28, 2023
@robertknight
Copy link
Member

robertknight commented Aug 28, 2023

This is actually a valid issue. I can reproduce in Safari. The problem is that the page sets a cross-origin-opener: same-origin header, which prevents the login popup window from interacting with the sidebar via window.opener.

curl -I 'https://simonwillison.net/2023/Aug/27/wordcamp-llms/'
HTTP/2 200 
date: Mon, 28 Aug 2023 16:31:05 GMT
content-type: text/html; charset=utf-8
x-content-type-options: nosniff
referrer-policy: same-origin
cross-origin-opener-policy: same-origin
via: 1.1 vegur
cf-cache-status: HIT
age: 2572
last-modified: Mon, 28 Aug 2023 15:48:13 GMT
accept-ranges: bytes
report-to: {"endpoints":[{"url":"https:\/\/a.nel.cloudflare.com\/report\/v3?s=NtE%2FsXX6eW%2BJYuODgLSAOxAtOqAqac92g8PSWfwXVAdlivrkcyXASodXhrTjhVTr3OmME0wOeRQVF42PvM83%2B42zMKcRBOPa%2BRr5Sfk91s1nZu1vjCivA0gDJ2xRfK7rmq5nPw%3D%3D"}],"group":"cf-nel","max_age":604800}
nel: {"success_fraction":0,"report_to":"cf-nel","max_age":604800}
server: cloudflare
cf-ray: 7fddf14cc9cf71b6-LHR
alt-svc: h3=":443"; ma=86400

There are more details in hypothesis/viahtml#353 (comment) and hypothesis/viahtml#333 (comment). At the time those comments were written we were waiting on new web standards to provide a solution for use cases like ours (sigh). Relevant bit on Hypothesis-specific workarounds:

The a site sets the Cross-Origin-Opener-Policy header this can however prevent logging in to from either the bookmarklet or browser extension. Since Chrome has not yet blocked third-party cookies, a workaround for extension users is to visit some other page first, login there, and then re-visit USA Today (or the other page using COOP). A workaround for bookmarklet users is to use Via.

The particular page you mentioned might change at some future point so that it no longer sets this header, but it is easy enough to create another URL that does set this header for testing.

@robertknight robertknight changed the title Unable to use hypothesis on this page Hypothesis bookmarklet / extension do not work on page that uses Cross-Origin-Opener-Policy: same-origin Aug 28, 2023
@robertknight robertknight changed the title Hypothesis bookmarklet / extension do not work on page that uses Cross-Origin-Opener-Policy: same-origin Client does not work on page that uses Cross-Origin-Opener-Policy: same-origin Aug 28, 2023
@cdrini cdrini reopened this Aug 28, 2023
@robertknight
Copy link
Member

Chrome are currently exploring a solution for this via Cross-Origin-Opener-Policy: restrict-properties. See https://developer.chrome.com/blog/coop-restrict-properties/.

The next step for us here is to explore whether we can leverage restrict-properties in the context of Hypothesis being embedded on a web page which sets Cross-Origin-Opener-Policy: same-origin, or whether the third-party rendering the top-level page needs to make a change on their end.

@acelaya acelaya changed the title Client does not work on page that uses Cross-Origin-Opener-Policy: same-origin Empty login window on pages that use Cross-Origin-Opener-Policy: same-origin Apr 1, 2024
@acelaya acelaya pinned this issue Apr 1, 2024
@robertknight
Copy link
Member

In the case of browser extensions, there is a built-in API for completing OAuth login flows - chrome.identity.launchWebAuthFlow we might be able to use that instead of opening the popup ourselves. If that works, then we've solved this problem in the following cases:

  • Browser extension (uses non-popup mechanism for auth)
  • Via (strips / rewrites Cross-Origin-Opener-Policy headers)

This leaves the bookmarklet and sites that embed Hypothesis. For the bookmarklet, a possible solution would be to have the sidebar iframe request storage access via document.requestStorageAccess, which will give it access to the localStorage and cookies of hypothes.is in a top-level site. The auth popup should then be able to communicate with the sidebar iframe via storage events, cookies or BroadcastChannel.

@robertknight
Copy link
Member

I've been looking closer into using alternative communication channels (eg. BroadcastChannel) to pass the cookie back. What I have found is:

  • The sidebar cannot use BroadcastChannel, localStorage or other non-cookie partitioned storage to read/receive information from a popup window with the same origin as the sidebar. This is because storage is partitioned based on the top-level context, and unlike cookies, the Storage Access API cannot be used to request an un-partitioned view of storage
  • The sidebar can use document.cookie (or cookieStore) to access cookies set from a popup window with the same origin as the sidebar, under certain conditions:
    • The sidebar must acquire storage access via document.requestStorageAccess, or already have been granted it by browser policy. In Safari this will trigger a prompt for each distinct top-level site.
    • The cookie must be set with secure=true, sameSite=none attributes and a path that makes it accessible to the sidebar. For example: document.cookie = 'foo=bar;path=/;secure=true;sameSite=none';

Putting these together, a possible workflow for using document.cookie to pass back the auth token would be:

  1. Client attempts to open the popup window as normal. If the window.open call returns null then Cross-Origin-Opener-Policy: same-origin is in effect, and the client won't be able to communicate directly with the popup.
  2. The client could at this point invoke document.requestStorageAccess (I think, I need to check whether step (1) "consumes" the user gesture) so that it can communicate with the popup via cookies instead
  3. After authorization completes in the popup, the popup must redirect to a domain that matches the sidebar, except for the case where the sidebar domain is the same as the authorization domain
  4. The popup window can then use a Set-Cookie header or document.cookie to pass an auth code back to the sidebar
  5. The sidebar can then read the auth code from document.cookie (via polling) or cookieStore (via events)

In order to make this work, every OAuth client that is not hosted on the h server itself will need to register a functional redirect URL, not merely a "placeholder" URL that provides an origin for use with window.postMessage calls.

For OAuth clients which are hosted on the same site as h, once we have storage access we could skip the whole popup flow if the user is already logged into the h website.

@robertknight
Copy link
Member

Some new web standards proposals that are relevant:

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

No branches or pull requests

2 participants