-
Notifications
You must be signed in to change notification settings - Fork 2.6k
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
Add a noopener-allow-popups
value to COOP
#10394
base: main
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would like to hear what @camillelamy thinks as well, but I think one change I'd like to see is that we drop "cross-origin" from the internal naming scheme now that we make it apply to same-origin scenarios.
(We probably don't want to change any of the IDs though.)
It also seems to me some other algorithms need updating here:
- obtain a cross-origin opener policy
- check if COOP values require a browsing context group switch
Would it make sense to spin off this editorial only change to a separate PR? (happy to work on it, just wondering RE editorial vs. functional split)
Oops, added!
I think this is covered by the change to matching COOP, but I could be I'm missing something.. |
@yoavweiss I think once we have agreement for this PR, that could be a separate PR as well (to be landed first). It would be a bit of extra work, but I agree that it would be nicer. |
9aa933f
to
a743f59
Compare
https://bugs.webkit.org/show_bug.cgi?id=275147 Reviewed by NOBODY (OOPS!). The `noopener-allow-popups` COOP value would enable a document to ensure it can't be scripted by other same-origin documents that have opened it. Some origins can contain different applications with different levels of security requirements. In those cases, it can be beneficial to prevent scripts running in one application from being able to open and script pages of another same-origin application. The noopener-allow-popups Cross-Origin-Opener-Policy value severs the opener relationship between the document loaded with this policy and its opener. At the same time, this document can open further documents (as the "allow-popups" in the name suggests) and maintain its opener relationship with them, assuming that their COOP policy allows it. This implements whatwg/html#10394 * LayoutTests/imported/w3c/web-platform-tests/html/cross-origin-opener-policy/reporting/resources/reporting-common.js: (const.coopHeaders): A helper to create headers in a more succinct way. * LayoutTests/imported/w3c/web-platform-tests/html/cross-origin-opener-policy/reporting/tentative/access-to-noopener-page-from-no-coop-ro.https-expected.txt: Added. * LayoutTests/imported/w3c/web-platform-tests/html/cross-origin-opener-policy/reporting/tentative/access-to-noopener-page-from-no-coop-ro.https.html: Added. * LayoutTests/imported/w3c/web-platform-tests/html/cross-origin-opener-policy/resources/noopener-helper.js: Added. (getExecutorPath): (const.test_noopener_opening_popup): The logic for the noopener tests. (async const): * LayoutTests/imported/w3c/web-platform-tests/html/cross-origin-opener-policy/tentative/noopener/coop-noopener-allow-popups.https-expected.txt: Added. * LayoutTests/imported/w3c/web-platform-tests/html/cross-origin-opener-policy/tentative/noopener/coop-noopener-allow-popups.https.html: Added. * Source/WebCore/loader/CrossOriginOpenerPolicy.cpp: (WebCore::crossOriginOpenerPolicyToString): Add the "noopener-allow-popups" string. (WebCore::crossOriginOpenerPolicyValueToEffectivePolicyString): Add the "noopener-allow-popups" string. (WebCore::matchingCOOP): Implement the related HTML algorithm. (WebCore::coopValuesRequireBrowsingContextGroupSwitch): Implement the switching logic related to noopener-allow-popups. (WebCore::obtainCrossOriginOpenerPolicy): Parse the "noopener-allow-popups" value. * Source/WebCore/loader/CrossOriginOpenerPolicy.h: Add the noopener-allow-popups enum value. * Source/WebKit/Shared/WebCoreArgumentCoders.serialization.in: Add the noopener-allow-popups enum value.
I added @ddworken's commented risks as a note. |
Yes, I think it could be helpful to at least add a note somewhere saying that browser should aim to put documents with this COOP value in a separate renderer process (or something along these lines) -- otherwise, same-origin documents would still be able to read arbitrary from memory even if they can't directly access it using web-level APIs. |
f345df4
to
35c581a
Compare
@yoavweiss did you open a PR already to drop "cross origin" from the internal concepts? |
Was out, will do that now.. |
35c581a
to
28caad5
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is looking good, I have nothing but nits.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for reviewing!
It'd be nice to also document the vector in this comment. |
I believe it's covered in the note under https://whatpr.org/html/10394/browsers.html#coop-noopener-allow-popups |
@shhnjk - or did you mean that the note should cover Cache API usage as well? |
The note talks about i.e.:
|
Added a separate line for "Cache API manipulation or access to sensitive data". Thanks!! |
data-x="">httponly</code>.</p></li> | ||
<li><p>localStorage access to sensitive data.</p></li> | ||
<li><p>Service worker installation.</p></li> | ||
<li><p>Cache API manipulation or access to sensitive data.</p></li> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
https://w3c.github.io/ServiceWorker/#cache right? Maybe link to it manually here, and then add a [SW]
ref like in https://html.spec.whatwg.org/multipage/webappapis.html#fetching-scripts-perform-fetch:~:text=Service%20Workers%20is%20an%20example%20of%20a%20specification%20that%20runs%20these%20algorithms%20with%20its%20own%20options%20for%20the%20hook
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done! Let me know if this matches what you had in mind
<var>responseCOOPValue</var>, and <var>responseOrigin</var> is true, return false.</p></li> | ||
<var>responseCOOPValue</var>, and <var>responseOrigin</var> is true, then return false.</p></li> | ||
|
||
<li><p>If <var>activeDocumentCOOPValue</var> is "<code |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm curious about this condition and how it relates to what I'm seeing in https://chromium-review.googlesource.com/c/chromium/src/+/5581251/25/content/browser/security/coop/cross_origin_opener_policy_status.cc. I'm not super familiar with COOP impl specifics, so I'm probably missing something but it seems in Chromium when an initiator has noopener-allow-popups
and the destination/response has same-origin-allow-popups
we only conditionally "no swap" (based on origin), but the spec here unconditionally returns false?
Is this a real difference or am I incorrectly comparing two different things?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes this seems like it would prevent the popup from being opened at all. When you open a popup, you create an about:blank document that inherits COOP from its creator, so in this case noopener-allow-popups
. With this clause, then the navigation from noopener-allow-popups
about:blank to the actual popup would always trigger a BCG swap. Which is not what you want. This is why same-origin-allow-popups has the conditions below about not swapping when you're the initial about:blank document. You should do something similar.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@domfarolino - I think you're right and for same-origin-allow-popups
we should check for an origin here.
@camillelamy - I'm not sure the scenario you're describing matches my read of the spec, so I'd love to better understand it. For a navigation from noopener-allow-popups
about:blank to the actual popup, I think this line returns "false", which means no BCG swap will take place. Am I reading it wrong?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the about:blank popup case, the line will not return false because activeDocumentCOOP value is noopener-allow-popups
and the value of responseCOOP is unsafe-none
. So they don't match, per line 86864 in this PR.
The step 2 of this algorithm (if all of the following are true...) deals specifically with the popup case. You should modify the following in this step:
- activeDocumentCOOPValue's value is "same-origin-allow-popups"; and
so that it also applies if activeDocumentCOOPValue is noopener-allow-popups
.
However, this line will return false when navigating an about:blank noopener-allow-popups
to another noopener-allow-popups
page, meaning that the noopener-allow-popups
popup will keep its opener (which is itself noopener-allow-popups
). I think this would be unexpected.
<var>responseCOOPValue</var>, and <var>responseOrigin</var> is true, return false.</p></li> | ||
<var>responseCOOPValue</var>, and <var>responseOrigin</var> is true, then return false.</p></li> | ||
|
||
<li><p>If <var>activeDocumentCOOPValue</var> is "<code |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the about:blank popup case, the line will not return false because activeDocumentCOOP value is noopener-allow-popups
and the value of responseCOOP is unsafe-none
. So they don't match, per line 86864 in this PR.
The step 2 of this algorithm (if all of the following are true...) deals specifically with the popup case. You should modify the following in this step:
- activeDocumentCOOPValue's value is "same-origin-allow-popups"; and
so that it also applies if activeDocumentCOOPValue is noopener-allow-popups
.
However, this line will return false when navigating an about:blank noopener-allow-popups
to another noopener-allow-popups
page, meaning that the noopener-allow-popups
popup will keep its opener (which is itself noopener-allow-popups
). I think this would be unexpected.
|
||
<ol> | ||
<li><p>If <var>responseCOOPValue</var> is "<code | ||
data-x="coop-unsafe-none">unsafe-none</code>", then return false.</p></li> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This means that we will not trigger a BCG switch when navigating from noopener-allow-popups to unsafe-none. This is different from the same-origin-allow-popups behavior, where this is only true for the intial navigation in a popup. I would recommend removing this and aligning on same-origin-allow-popups here.
<li><p>If <var>responseCOOPValue</var> is "<code | ||
data-x="coop-unsafe-none">unsafe-none</code>", then return false.</p></li> | ||
|
||
<li><p>If <var>responseCOOPValue</var> is "<code |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So navigating from noopener-allow-popups to same-origin-allow-popups doesn't trigger a BCG switch, but the reverse does? I think this is likely to be confusing, especially when you factor in back navigations.
For example, consider the following scenario:
- You're on page A with noopener-allow-popups. Page A opens popup B. Communication with the popup works.
- Page A navigates to a same -origin same-origin-allow-popups page. Communication with the popup works.
- The user goes back to the noopener-allow-popups page. Communication with the popup stops working. This might be unexpected to the original noopener-allow-popups page.
Fixes #10373
Some origins can contain different applications with different levels of security requirements. In those cases, it can be beneficial to prevent scripts running in one application from being able to open and script pages of another same-origin application.
In such cases, it can be beneficial for a document to ensure its opener cannot script it, even if the opener document is a same-origin one.
This PR adds a
noopener-allow-popups
Cross-Origin-Opener-Policy value that severs the opener relationship between the document loaded with this policy and its opener. At the same time, this document can open further documents (as the "allow-popups" in the name suggests) and maintain its opener relationship with them, assuming that their COOP policy allows it.Explainer
noopener-allow-popups
COOP value mdn/mdn#579(See WHATWG Working Mode: Changes for more details.)
💥 Error: read ECONNRESET 💥
PR Preview failed to build. (Last tried on Sep 30, 2024, 8:56 AM UTC).
More
PR Preview relies on a number of web services to run. There seems to be an issue with the following one:
🚨 Wattsi Server - Wattsi Server is the web service used to build the WHATWG HTML spec.
🔗 Related URL
If you don't have enough information above to solve the error by yourself (or to understand to which web service the error is related to, if any), please file an issue.