Closed tcaptan-cr closed 10 months ago
PTAL @emilio @zcorpan @smfr
Thanks @tcaptan-cr... just to make this even easier to review, would you mind splitting out the Makefile into its own PR (and possibly even the xref bikeshed fixes if it's not a huge pain?)
Also, @tcaptan-cr, you are committing to becoming co-Editor? That's ok... but just making sure you are 100% ok with taking on co-ownership. I'll need to announce that to the working group.
Thanks @tcaptan-cr... just to make this even easier to review, would you mind splitting out the Makefile into its own PR (and possibly even the xref bikeshed fixes if it's not a huge pain?)
I split the makefile into this PR, and the bikeshed fixes into this PR
FYI, this change was reviewed in tcaptan's mirror:
Also, @tcaptan-cr, you are committing to becoming co-Editor? That's ok... but just making sure you are 100% ok with taking on co-ownership. I'll need to announce that to the working group.
Yes, I am 100% OK with taking on co-ownership.
Let's fix the link. Pretty sure there's a better way of doing this.
Same for the
margin
property link, which I hadn't noticed.Also, can you rebase to remove the merge commit?
Done.
lgtm
Thanks Stefan!
Looks good to me, with that bit clarified. Thanks for doing this!
Thanks Emilio!
Hi there,
Chromium web platform security reviewer here. I've been looking at the I2P for this change and have a few questions, mostly to clarify my understanding:
Why does this rely on same-origin-domain
-ness of elements? I see the spec mentions that this only matters for implicit intersection observers, but I don't have context on why this matters (or why origin-domain was chosen over origin, the usual security boundary).
I've given this some thought through the lens of xs-leaks, and I believe this makes no material difference to that kind of attack, mostly because scrollMargin
does not apply to iframes. This means that even if the intersection rectangle has been expanded by scrollMargin
, it will be clipped to the iframe's viewport on the way up the tree, so a malicious iframe will not be able to determine more than "am I visible" (modulo rootMargin, but it only applies for same-origin-domain elements). Does this match your understanding?
I guess the iframe could be contained in a scroll container itself, and scrollMargin
would affect that? This seems related to my next question:
In https://github.com/w3c/IntersectionObserver/issues/431#issuecomment-1542502858 it was mentioned that scrollMargin
should stop at cross-origin iframe boundaries. What was meant by that, and is that specified in this PR? I cannot find a reference.
I cannot find in the spec algorithms where it is specified that scrollMargin
only applies to same-origin-domain
elements. Is the plain english paragraph normative here?
This feature is modelled after the existing rootMargin
feature, and it has basically the same set of security/privacy concerns...
"Any target of an explicit root observer is also a same-origin-domain target, since the target must be in the same document as the intersection root."
scrollMargin
does indeed apply to the top-level scrolling viewport of the iframe! No distinction is made between the document-level scrolling viewport and a scrollable element. That is why scrollMargin
is restricted to explicit-root observers and same-origin-domain
implicit-root observers.
The comment in that spec issue is simply stating the requirement that scrollMargin
cannot probe the geometry of the embedding page, in the same way that rootMargin
cannot. This is commensurate with the above explanations.
Beginning at line 291 in index.bs
, this PR adds:
"These offsets are only applied when handling same-origin-domain targets; for cross-origin-domain targets they are ignored."
Thanks for the answers!
This feature is modelled after the existing
rootMargin
feature, and it has basically the same set of security/privacy concerns...
Right, and I don't have context on those concerns, hence my questions :)
- Only implicit-root observers are subject to these restrictions, because only implicit-root observers communicate geometry information that crosses iframe boundaries. Quoting from the spec:
"Any target of an explicit root observer is also a same-origin-domain target, since the target must be in the same document as the intersection root."
I see, and this is actually specified by step 2.2.2 of the Run the Update Intersection Observations Steps algorithm.
I'm still left with my questions:
scrollMargin
does indeed apply to the top-level scrolling viewport of the iframe! No distinction is made between the document-level scrolling viewport and a scrollable element. That is whyscrollMargin
is restricted to explicit-root observers andsame-origin-domain
implicit-root observers.
Oh, I see. I was looking at step 3.1 of the compute the intersection algorithm, but step 3.3 also applies because an iframe is a scroll container?
- The comment in that spec issue is simply stating the requirement that
scrollMargin
cannot probe the geometry of the embedding page, in the same way thatrootMargin
cannot. This is commensurate with the above explanations.
I see, this is what is mentioned in the Privacy and Security section. Can you help me understand the attack here? How would the embeddee learn about its embedder's geometry using rootMargin
or scrollMargin
?
That section mentions that IntersectionObserver
does not allow new methods of detecting intersection, only making existing hacks more usable. Is this "compatibility goal" what led to the choice of same-origin-domain instead of same-origin?
- Beginning at line 291 in
index.bs
, this PR adds:"These offsets are only applied when handling same-origin-domain targets; for cross-origin-domain targets they are ignored."
Right, this was what I referred to as "the plain english paragraph". IIUC this does not correspond to any step in the compute the intersection algorithm? I was expecting to find something there.
- Only implicit-root observers are subject to these restrictions, because only implicit-root observers communicate geometry information that crosses iframe boundaries. Quoting from the spec:
"Any target of an explicit root observer is also a same-origin-domain target, since the target must be in the same document as the intersection root."
I see, and this is actually specified by step 2.2.2 of the Run the Update Intersection Observations Steps algorithm.
I'm still left with my questions:
- Why does this matter (for explicit root observers)?
Sorry, I don't understand your question. Why does what matter for explicit root observers? Explicit root observers can use scrollMargin
without restriction; implicit root observers can use scrollMargin
conditionally.
- Why choose same-origin-domain instead of same-origin? The latter is the web's usual security boundary.
Here's the previous discussion.
scrollMargin
does indeed apply to the top-level scrolling viewport of the iframe! No distinction is made between the document-level scrolling viewport and a scrollable element. That is whyscrollMargin
is restricted to explicit-root observers andsame-origin-domain
implicit-root observers.Oh, I see. I was looking at step 3.1 of the compute the intersection algorithm, but step 3.3 also applies because an iframe is a scroll container?
Yes, that's right.
- The comment in that spec issue is simply stating the requirement that
scrollMargin
cannot probe the geometry of the embedding page, in the same way thatrootMargin
cannot. This is commensurate with the above explanations.I see, this is what is mentioned in the Privacy and Security section. Can you help me understand the attack here? How would the embeddee learn about its embedder's geometry using
rootMargin
orscrollMargin
?
The general idea is that the attacker would create a bunch of IntersectionObservers, each with slightly different rootMargin
and perhaps a range of thresholds
; and that by analyzing the received notifications, it would be possible to deduce the size of the containing viewport. I unfortunately can't find a concrete exploit, but this came up during the early days of developing the API.
- Beginning at line 291 in
index.bs
, this PR adds:"These offsets are only applied when handling same-origin-domain targets; for cross-origin-domain targets they are ignored."
Right, this was what I referred to as "the plain english paragraph". IIUC this does not correspond to any step in the compute the intersection algorithm? I was expecting to find something there.
Ah, that's a good point. There is an explanation of the same-origin-domain restriction on rootMargin
which is reachable from the algorithm description; but the equivalent explanation for scrollMargin
is not directly reachable from the algorithm description. I think this content, which is currently intermingled with the definition of root intersection rect
, should be moved to the definition of scrollMargin
:
When calculating a scrollport intersection rectangle for a same-origin-domain target, the rectangle is expanded according to the offsets in the IntersectionObserver’s [[scrollMargin]] slot in a manner similar to CSS’s margin property, with the four values indicating the amount the top, right, bottom, and left edges, respectively, are offset by, with positive lengths indicating an outward offset. Percentages are resolved relative to the width of the undilated rectangle.
NOTE: scrollMargin affects the clipping of target by all scrollable ancestors up to and including the intersection root. Both the scrollMargin and the rootMargin are applied to a scrollable intersection root’s rectangle.
On same-origin-domain vs same-origin, it only matters when using document.domain
(which is going away). If the pages involved have used document.domain
so they're same-origin-domain, they can access each other's DOM.
Thanks for the answers and pointers, this is super helpful.
Using same-origin-domain makes sense for this, though it would always be better to avoid introducing a new dependency on document.domain
. If y'all would be happy with same-origin, I think it would be a nicer fit for today's web platform.
+1 to amending the spec to extend the same-origin-domain restriction from rootMargin
to scrollMargin
more explicitly.
I have one remaining clarification question: the intent of the same-origin-domain restriction is to prevent scrollMargin
from applying to scroll containers (including iframe documents) that are cross-origin-domain with the observer, right? That is, if A embeds B embeds A, the grandchild A cannot learn about the geometry of B by using scrollMargin
, even though it is same-origin with the top-level document. Is that correct?
I don't think there is any new information being exposed that is not already in rootMargin. Do you think there may be something?
the intent of the same-origin-domain restriction is to prevent scrollMargin from applying to scroll containers (including iframe documents) that are cross-origin-domain with the observer, right?
Yes, this is my understanding.
I don't think there is any new information being exposed that is not already in rootMargin. Do you think there may be something?
I think I'm now convinced there isn't. Since scrollMargin
applies to many more elements than rootMargin
, I was worried there could be.
the intent of the same-origin-domain restriction is to prevent scrollMargin from applying to scroll containers (including iframe documents) that are cross-origin-domain with the observer, right?
Yes, this is my understanding.
Thanks for confirming.
There were no bugs filed for Gecko or WebKit. Please keep that in the issue template in the future.
I've now filed:
Closes #431
The following tasks have been completed:
Implementation commitment:
Preview | Diff