Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1488)

Issue 1710283003: OOPIF: Handle cross-site frames being blocked by X-Frame-Options or CSP. (Closed)

Created:
4 years, 10 months ago by alexmos
Modified:
4 years, 9 months ago
Reviewers:
Charlie Reis, clamy
CC:
chromium-reviews, mlamouri+watch-content_chromium.org, tyoshino+watch_chromium.org, creis+watch_chromium.org, mlamouri+watch-blink_chromium.org, nasko+codewatch_chromium.org, jam, dcheng, blink-reviews-api_chromium.org, blink-reviews, dglazkov+blink, darin-cc_chromium.org, gavinp+loader_chromium.org, mkwst+moarreviews-renderer_chromium.org, Nate Chapin, loading-reviews_chromium.org, site-isolation-reviews_chromium.org
Base URL:
https://chromium.googlesource.com/chromium/src.git@master
Target Ref:
refs/pending/heads/master
Project:
chromium
Visibility:
Public.

Description

OOPIF: Handle cross-site frames being blocked by X-Frame-Options or CSP. Currently with OOPIFs, when a page from site A embeds a cross-site frame from site B, and the subframe is blocked due to X-Frame-Options or CSP frame-ancestors, the blocking happens in process B, after the frame gets transferred to a new process, but before commit (or rather, DidFailProvisionalLoad, which is what happens because of the block). There are several problems with this: 1. The renderer for frame B gets killed while trying to forward the load event to the parent process, so that it can get fired on the <iframe> element there. (see issue 584845). 2. As a result, the load event for the <iframe> element in process A never fires as it should. (Firing this event is necessary so that the blocking can't be observed.) 3. The blocked subframe is kept in process A, but it still has A's origin, meaning it appears as a same-site frame to its parent, rather than a cross-site frame, as it should after the block. Normal blocking logic handles this by setting a unique origin on the blocked frame, but this happens in process B, and process A never learns about that. In addition, the browser process still thinks the subframe's origin is A. 4. The load that was started for the subframe in process A never gets stopped. In particular, this is problematic for layout tests, which wait for DidStopLoading in process A to end the test. Basically, process A never finds out that the subframe failed to load in a different process due to CSP/XFO blocking, and can't take appropriate action. The proper way to fix this is by enforcing XFO/CSP in the browser process, so that we don't need to create the unnecessary new process in the first place. However, that is a longer-term effort (see https://crbug.com/555418). This CL provides a stop-gap solution of forwarding the notification about the block from process B to process A, so that process A can (1) set the subframe's origin to unique, and (2) fire the load event on its FrameOwner. The browser->renderer part of this notification can be reused once the browser process can do the blocking. This CL also generically fixes the case of stopping the load in the current RenderFrameHost when a pending RenderFrameHost never commits, which solves problem 4 and guards any future such problems. BUG=584845 CQ_INCLUDE_TRYBOTS=tryserver.chromium.linux:linux_site_isolation

Patch Set 1 #

Patch Set 2 : #

Patch Set 3 : #

Patch Set 4 : Rebase #

Total comments: 17

Patch Set 5 : Rename plumbing to use BlockedLoad #

Patch Set 6 : Rebase #

Patch Set 7 : Split off the relaxed DCHECK in OnCrossSiteResponse into separate CL #

Unified diffs Side-by-side diffs Delta from patch set Stats (+211 lines, -13 lines) Patch
M content/browser/frame_host/navigator_impl.cc View 1 2 3 4 5 1 chunk +16 lines, -0 lines 0 comments Download
M content/browser/frame_host/render_frame_host_impl.h View 1 2 3 4 5 1 chunk +1 line, -0 lines 0 comments Download
M content/browser/frame_host/render_frame_host_impl.cc View 1 2 3 4 5 3 chunks +35 lines, -1 line 0 comments Download
M content/browser/site_per_process_browsertest.cc View 1 2 3 4 5 1 chunk +67 lines, -0 lines 0 comments Download
M content/common/frame_messages.h View 1 2 3 4 2 chunks +14 lines, -0 lines 0 comments Download
M content/renderer/render_frame_impl.h View 1 2 3 4 5 2 chunks +2 lines, -0 lines 0 comments Download
M content/renderer/render_frame_impl.cc View 1 2 3 4 5 3 chunks +9 lines, -0 lines 0 comments Download
A content/test/data/frame-ancestors-none.html View 1 chunk +9 lines, -0 lines 0 comments Download
A content/test/data/frame-ancestors-none.html.mock-http-headers View 1 chunk +2 lines, -0 lines 0 comments Download
A content/test/data/x-frame-options-deny.html View 1 1 chunk +9 lines, -0 lines 0 comments Download
A content/test/data/x-frame-options-deny.html.mock-http-headers View 1 2 1 chunk +2 lines, -0 lines 0 comments Download
M third_party/WebKit/LayoutTests/FlagExpectations/site-per-process View 1 2 3 4 5 1 chunk +0 lines, -9 lines 0 comments Download
M third_party/WebKit/Source/core/frame/LocalFrame.h View 1 2 3 4 1 chunk +2 lines, -0 lines 0 comments Download
M third_party/WebKit/Source/core/frame/LocalFrame.cpp View 1 2 3 4 1 chunk +8 lines, -0 lines 0 comments Download
M third_party/WebKit/Source/core/loader/DocumentLoader.cpp View 1 2 3 4 5 1 chunk +10 lines, -3 lines 0 comments Download
M third_party/WebKit/Source/core/loader/FrameLoaderClient.h View 1 2 3 4 1 chunk +2 lines, -0 lines 0 comments Download
M third_party/WebKit/Source/web/FrameLoaderClientImpl.h View 1 2 3 4 1 chunk +1 line, -0 lines 0 comments Download
M third_party/WebKit/Source/web/FrameLoaderClientImpl.cpp View 1 2 3 4 1 chunk +7 lines, -0 lines 0 comments Download
M third_party/WebKit/Source/web/WebFrame.cpp View 1 2 1 chunk +1 line, -0 lines 0 comments Download
M third_party/WebKit/Source/web/WebLocalFrameImpl.h View 1 2 3 4 1 chunk +1 line, -0 lines 0 comments Download
M third_party/WebKit/Source/web/WebLocalFrameImpl.cpp View 1 2 3 4 1 chunk +6 lines, -0 lines 0 comments Download
M third_party/WebKit/public/web/WebFrameClient.h View 1 2 3 4 1 chunk +3 lines, -0 lines 0 comments Download
M third_party/WebKit/public/web/WebLocalFrame.h View 1 2 3 4 1 chunk +4 lines, -0 lines 0 comments Download

Depends on Patchset:

Messages

Total messages: 14 (5 generated)
alexmos
Hey Charlie, can you please take an initial look? This looks long (sorry!), but most ...
4 years, 10 months ago (2016-02-25 21:59:12 UTC) #4
alexmos
+site-isolation-reviews, I thought I did that when I initially sent this, but apparently not.
4 years, 10 months ago (2016-02-25 22:19:33 UTC) #5
Charlie Reis
I'm only a small way in, but I wanted to send a few initial questions. ...
4 years, 10 months ago (2016-02-26 01:13:21 UTC) #7
alexmos
> On 2016/02/25 21:59:12, alexmos wrote: > > Hey Charlie, can you please take an ...
4 years, 10 months ago (2016-02-26 02:38:05 UTC) #8
Charlie Reis
On 2016/02/26 02:38:05, alexmos wrote: > > On 2016/02/25 21:59:12, alexmos wrote: > > > ...
4 years, 10 months ago (2016-02-26 21:10:02 UTC) #9
Charlie Reis
content/ seems good to me once we rename. Thanks! https://codereview.chromium.org/1710283003/diff/60001/content/browser/frame_host/render_frame_host_impl.cc File content/browser/frame_host/render_frame_host_impl.cc (right): https://codereview.chromium.org/1710283003/diff/60001/content/browser/frame_host/render_frame_host_impl.cc#newcode1594 content/browser/frame_host/render_frame_host_impl.cc:1594: ...
4 years, 10 months ago (2016-02-26 21:26:41 UTC) #11
alexmos
Thanks for reviewing, Charlie! I've done the rename and split off the relaxed check into ...
4 years, 10 months ago (2016-02-26 22:37:56 UTC) #12
Charlie Reis
On 2016/02/26 22:37:56, alexmos wrote: > Thanks for reviewing, Charlie! I've done the rename and ...
4 years, 10 months ago (2016-02-27 00:02:15 UTC) #13
alexmos
4 years, 9 months ago (2016-03-04 01:32:08 UTC) #14
On 2016/02/27 00:02:15, Charlie Reis (OOO til Mar 7) wrote:
> On 2016/02/26 22:37:56, alexmos wrote:
> > Thanks for reviewing, Charlie!  I've done the rename and split off the
relaxed
> > check into a separate CL.
> > 
> > > > So today, Chrome doesn't obey the "empty body" part of the spec, and
this
> CL
> > > > doesn't change that.
> > > > 
> > > > Sorry, I was confused when I wrote "blank frame", since I was thinking
> about
> > > the
> > > > case where the blocked URL is the frame's first navigation.  In that
case,
> > the
> > > > blank page that's visible after the block is just the initial
about:blank.
> 
> > > I'll
> > > > go through the comments in this CL and remove any similar language about
> > blank
> > > > frames.
> > > 
> > > Wow, that current behavior sounds bad!  You could basically revoke the
> > effective
> > > origin of a page by navigating it to something that you know will be
> blocked. 
> > > I'm not sure if that can lead to more interesting attacks than DoS, though
> it
> > > probably would be a way to detect if the block happened or not.  (If the
> > > attacker owns the subframe's current page and the navigation is blocked,
the
> > > current page will keep existing and can check in with the server.)
> > > 
> > > Sounds like that will need to be fixed at some point, unless there's
reasons
> > we
> > > took that path.  If it does need to change, how disruptive will that be
for
> > the
> > > changes in this CL?  It's worth thinking about whether that change should
be
> > > made first, or if it's relatively easy to make it later.
> > 
> > Agreed, I didn't realize how bad it is if there's already an existing
document
> > loaded in the frame.  I'll explore what it takes to commit a blank document
> > instead and also run this by mkwst@ to see if there are reasons not to do
it. 
> > If it works out, I think that would be a better approach, and it'll probably
> > make half of this unnecessary (the browser->renderer IPC might still be
needed
> > once the blocking moves to the browser process).  But one potential problem
> with
> > that is that we might need to redo the way we'd commit the blank document
once
> > CSP/XFO moves to browser process, so I'm hesitant on spending much effort
> there
> > unless it's very easy.
> 
> Sounds good.  I'll grant my LGTM for content/ now, in case it turns out the
> behavior change is too disruptive for the moment.  (This CL seems to be a good
> intermediate point that avoids lots of ugly problems we have today.)

Just to give an update here - I'm going to close this CL for now without landing
it.  I ended up going with the alternate approach that changes CSP/XFO blocking
to commit a blank document instead of canceling:
https://codereview.chromium.org/1742923002.  That turned out to be an easier
Blink-only change that makes this behavior more sane, fixes spec compliance, and
fixes all the OOPIF problems for free.  I also extracted out the test I wrote
here and landed that separately in https://codereview.chromium.org/1754383002. 
We can revisit this CL to see if any of this plumbing might be needed once
CSP/XFO moves to the browser process.

Powered by Google App Engine
This is Rietveld 408576698