| Index: content/browser/frame_host/render_frame_host_impl.cc
|
| diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc
|
| index e33649f7e9db3c1e7fa85626e2a4bf8dc145298a..b09c451ffb96035529934ac3ebc5bf8d8046d317 100644
|
| --- a/content/browser/frame_host/render_frame_host_impl.cc
|
| +++ b/content/browser/frame_host/render_frame_host_impl.cc
|
| @@ -550,6 +550,7 @@ bool RenderFrameHostImpl::OnMessageReceived(const IPC::Message &msg) {
|
| OnDidChangeSandboxFlags)
|
| IPC_MESSAGE_HANDLER(FrameHostMsg_DidChangeFrameOwnerProperties,
|
| OnDidChangeFrameOwnerProperties)
|
| + IPC_MESSAGE_HANDLER(FrameHostMsg_BlockedLoad, OnBlockedLoad)
|
| IPC_MESSAGE_HANDLER(FrameHostMsg_UpdateTitle, OnUpdateTitle)
|
| IPC_MESSAGE_HANDLER(FrameHostMsg_UpdateEncoding, OnUpdateEncoding)
|
| IPC_MESSAGE_HANDLER(FrameHostMsg_BeginNavigation,
|
| @@ -1516,6 +1517,28 @@ void RenderFrameHostImpl::OnDidChangeFrameOwnerProperties(
|
| }
|
| }
|
|
|
| +void RenderFrameHostImpl::OnBlockedLoad() {
|
| + // When a frame is blocked by X-Frame-Options or CSP frame-ancestors, the
|
| + // blocked frame needs to get a unique origin, which ensures that it
|
| + // appears as a normal cross-origin document, and is the desired behavior
|
| + // according to spec: https://www.w3.org/TR/CSP2/#directive-frame-ancestors
|
| + // This sets the unique origin on both the browser and renderer sides. The
|
| + // IPC to renderer may be required when a cross-process subframe is blocked,
|
| + // since the blocking currently occurs in the pending RenderFrame, but the
|
| + // actual blocked frame will be left in the current RenderFrame in a
|
| + // different process.
|
| + //
|
| + // TODO(mkwst, alexmos): This will probably be called directly rather than
|
| + // from an renderer IPC once X-Frame-Options and CSP enforcement moves to the
|
| + // browser process (https://crbug.com/555418).
|
| + frame_tree_node_->SetCurrentOrigin(url::Origin());
|
| +
|
| + if (this == frame_tree_node_->render_manager()->pending_frame_host()) {
|
| + RenderFrameHost* current_rfh = frame_tree_node_->current_frame_host();
|
| + current_rfh->Send(new FrameMsg_BlockedLoad(current_rfh->GetRoutingID()));
|
| + }
|
| +}
|
| +
|
| void RenderFrameHostImpl::OnUpdateTitle(
|
| const base::string16& title,
|
| blink::WebTextDirection title_direction) {
|
| @@ -1557,11 +1580,22 @@ void RenderFrameHostImpl::OnDispatchLoad() {
|
| RenderFrameProxyHost* proxy =
|
| frame_tree_node()->render_manager()->GetProxyToParent();
|
| if (!proxy) {
|
| + // A valid special case where the proxy won't exist occurs when a frame
|
| + // gets blocked due to X-Frame-Options or CSP while it is still pending.
|
| + // (The proxy in the parent isn't created until commit.) In that case, it
|
| + // is ok to ignore this load event dispatch, since it will be done as part
|
| + // of forwarding the blocked notification (see
|
| + // FrameMsg_CancelLoadAfterXFrameOptionsOrCSPDenied).
|
| + //
|
| + // TODO(mkwst, alexmos): This won't be necessary once X-Frame-Options and
|
| + // CSP enforcement moves to the browser process (https://crbug.com/555418).
|
| + if (this != frame_tree_node_->current_frame_host())
|
| + return;
|
| +
|
| bad_message::ReceivedBadMessage(GetProcess(),
|
| bad_message::RFH_NO_PROXY_TO_PARENT);
|
| return;
|
| }
|
| -
|
| proxy->Send(new FrameMsg_DispatchLoad(proxy->GetRoutingID()));
|
| }
|
|
|
|
|