Charlie, can you please take a look? The trickiest part here was finding a way ...
5 years, 8 months ago
(2015-04-20 17:35:42 UTC)
#2
Charlie, can you please take a look? The trickiest part here was finding a way
to test it - I ended up catching and inspecting a console message for the
cross-domain access error, which needs to reflect the right origin. Currently,
that's also the only use case I know of where this matters.
This will need a couple of CLs to land first: the Blink error message CL
(https://codereview.chromium.org/1085973003/), and also a CL to allow origin
updates in RemoteSecurityContexts (https://codereview.chromium.org/1096873002/).
Charlie Reis
Quick sanity check before I review the code itself: do you know of other places ...
5 years, 8 months ago
(2015-04-20 20:22:48 UTC)
#3
Quick sanity check before I review the code itself: do you know of other places
we'll need this besides the error messages?
Just wanted to make sure we need this (from a least privilege perspective),
since otherwise it would be nice not to tell possibly exploited renderer
processes about everywhere the user visits in that BrowsingInstance. I know we
need the replicated origin on the ancestor chain for a bunch of checks, but as
you mentioned, that can't change without destroying the descendant. In that
sense, I wonder if we only need replicated origins on RemoteFrames when they
have a LocalFrame descendant.
For the error messages case, I could imagine filling in the actual origin in the
browser process, but maybe that's a lot easier said than done. Worth comparing
against this alternative, though.
alexmos
On 2015/04/20 20:22:48, Charlie Reis wrote: > Quick sanity check before I review the code ...
5 years, 8 months ago
(2015-04-20 22:06:12 UTC)
#4
On 2015/04/20 20:22:48, Charlie Reis wrote:
> Quick sanity check before I review the code itself: do you know of other
places
> we'll need this besides the error messages?
>
> Just wanted to make sure we need this (from a least privilege perspective),
> since otherwise it would be nice not to tell possibly exploited renderer
> processes about everywhere the user visits in that BrowsingInstance. I know
we
> need the replicated origin on the ancestor chain for a bunch of checks, but as
> you mentioned, that can't change without destroying the descendant. In that
> sense, I wonder if we only need replicated origins on RemoteFrames when they
> have a LocalFrame descendant.
>
> For the error messages case, I could imagine filling in the actual origin in
the
> browser process, but maybe that's a lot easier said than done. Worth
comparing
> against this alternative, though.
Yes, good point about leaking history. I've thought some more about this, and I
think this may matter if the proxy in question gets a local descendant after an
origin change. For example, suppose you have:
Site A ------------ proxies for B
|--Site B ------- proxies for A
+--Site A ------- proxies for B(replicated_origin=A)
Suppose the second frame navigates to C. Without this CL, you would have:
Site A ------------ proxies for B, C
|--Site B ------- proxies for A, C
+--Site C ------- proxies for A(replicated_origin=C),
B(replicated_origin=A)
Suppose C appends a new frame on site B:
Site A ------------ proxies for B, C
|--Site B ------- proxies for A, C
+--Site C ------- proxies for A(replicated_origin=C),
B(replicated_origin=A)
|--Site B -- proxies for A, C
This will append a local child to the proxy for C in B's process. Now, if that
new child frame evaluates location.ancestorOrigins (or needs ancestors for a
security check), its parent's origin should be "C". Without this CL, it would
be "A".
With this CL, the proxy's replicated_origin would be updated from "A" to "C"
after the navigation to C. To reduce history leaks, maybe we could buffer the
origin updates and only send them to the proxy in question in the last step,
when the proxy gets a local descendant. (The attacker shouldn't be able to
create a child frame under another renderer's frame to exploit this.) That
would break the error messages, though. The frame navigation checks themselves
(like Frame::canNavigate) should still work despite using an incorrect origin,
since they only care about same-origin vs. cross-origin, though this feels a bit
shaky if the checks (or our policy) change in some way in the future. Filling
in the origin for error messages in the browser process seems pretty complex --
we could also just not use a remote frame's origin in the message if we don't
have it for now. Long-term, it seems that checks like Frame::canNavigate should
be enforced in the browser process, which would let us generate correct and
complete error messages there if/when that happens.
If we do go forward with this, I can also write a test for the above scenario,
which would be much better than the hacky test I have currently (though the
current test could still be useful to keep for testing error messages with
OOPIF).
Charlie Reis
On 2015/04/20 22:06:12, alexmos wrote: > On 2015/04/20 20:22:48, Charlie Reis wrote: > > Quick ...
5 years, 8 months ago
(2015-04-20 22:40:36 UTC)
#5
On 2015/04/20 22:06:12, alexmos wrote:
> On 2015/04/20 20:22:48, Charlie Reis wrote:
> > Quick sanity check before I review the code itself: do you know of other
> places
> > we'll need this besides the error messages?
> >
> > Just wanted to make sure we need this (from a least privilege perspective),
> > since otherwise it would be nice not to tell possibly exploited renderer
> > processes about everywhere the user visits in that BrowsingInstance. I know
> we
> > need the replicated origin on the ancestor chain for a bunch of checks, but
as
> > you mentioned, that can't change without destroying the descendant. In that
> > sense, I wonder if we only need replicated origins on RemoteFrames when they
> > have a LocalFrame descendant.
> >
> > For the error messages case, I could imagine filling in the actual origin in
> the
> > browser process, but maybe that's a lot easier said than done. Worth
> comparing
> > against this alternative, though.
>
> Yes, good point about leaking history. I've thought some more about this, and
I
> think this may matter if the proxy in question gets a local descendant after
an
> origin change. For example, suppose you have:
>
> Site A ------------ proxies for B
> |--Site B ------- proxies for A
> +--Site A ------- proxies for B(replicated_origin=A)
>
> Suppose the second frame navigates to C. Without this CL, you would have:
>
> Site A ------------ proxies for B, C
> |--Site B ------- proxies for A, C
> +--Site C ------- proxies for A(replicated_origin=C),
> B(replicated_origin=A)
>
> Suppose C appends a new frame on site B:
> Site A ------------ proxies for B, C
> |--Site B ------- proxies for A, C
> +--Site C ------- proxies for A(replicated_origin=C),
> B(replicated_origin=A)
> |--Site B -- proxies for A, C
>
> This will append a local child to the proxy for C in B's process. Now, if
that
> new child frame evaluates location.ancestorOrigins (or needs ancestors for a
> security check), its parent's origin should be "C". Without this CL, it would
> be "A".
>
> With this CL, the proxy's replicated_origin would be updated from "A" to "C"
> after the navigation to C. To reduce history leaks, maybe we could buffer the
> origin updates and only send them to the proxy in question in the last step,
> when the proxy gets a local descendant. (The attacker shouldn't be able to
> create a child frame under another renderer's frame to exploit this.) That
> would break the error messages, though. The frame navigation checks
themselves
> (like Frame::canNavigate) should still work despite using an incorrect origin,
> since they only care about same-origin vs. cross-origin, though this feels a
bit
> shaky if the checks (or our policy) change in some way in the future. Filling
> in the origin for error messages in the browser process seems pretty complex
--
> we could also just not use a remote frame's origin in the message if we don't
> have it for now. Long-term, it seems that checks like Frame::canNavigate
should
> be enforced in the browser process, which would let us generate correct and
> complete error messages there if/when that happens.
>
> If we do go forward with this, I can also write a test for the above scenario,
> which would be much better than the hacky test I have currently (though the
> current test could still be useful to keep for testing error messages with
> OOPIF).
Yes, when a LocalFrame gets added as a subframe to a RemoteFrame, we would have
to send origin updates for all of its ancestors (maybe only if they've changed,
as you mention).
Also, I agree that Frame::canNavigate is really something that should eventually
be enforced in the browser process, where we have the authoritative info. That
would also let us handle the error messages there, as you mention.
It sounds like your current CL (dynamic origin updates) is a bit more sane and
convenient at the moment, but less in line with where we'd like to end up down
the road. It may be that it's worthwhile landing it for now, with some plans to
undo it when we can move Frame::canNavigate? Let's chat in person a bit
tomorrow about how much work is on each path, and we can decide which way to go.
Thanks!
Charlie Reis
Ok, sounds like we'll need enough of this CL either way that we should proceed. ...
5 years, 8 months ago
(2015-04-21 19:10:30 UTC)
#6
Issue 1098763003: Send origin updates to frame proxies when a frame navigates to new origin.
(Closed)
Created 5 years, 8 months ago by alexmos
Modified 5 years, 8 months ago
Reviewers: Charlie Reis, kenrb
Base URL: https://chromium.googlesource.com/chromium/src.git@master
Comments: 10