| Index: content/browser/frame_host/render_frame_proxy_host.cc
|
| diff --git a/content/browser/frame_host/render_frame_proxy_host.cc b/content/browser/frame_host/render_frame_proxy_host.cc
|
| index 7d79501b10298b3e1037d26cfd1962540fb94178..2e09d76202cfe7a2de8436df19bd465d45f83566 100644
|
| --- a/content/browser/frame_host/render_frame_proxy_host.cc
|
| +++ b/content/browser/frame_host/render_frame_proxy_host.cc
|
| @@ -135,6 +135,8 @@ bool RenderFrameProxyHost::OnMessageReceived(const IPC::Message& msg) {
|
| IPC_BEGIN_MESSAGE_MAP(RenderFrameProxyHost, msg)
|
| IPC_MESSAGE_HANDLER(FrameHostMsg_Detach, OnDetach)
|
| IPC_MESSAGE_HANDLER(FrameHostMsg_OpenURL, OnOpenURL)
|
| + IPC_MESSAGE_HANDLER(FrameHostMsg_ForwardContentSecurityPolicyViolation,
|
| + OnForwardContentSecurityPolicyViolation)
|
| IPC_MESSAGE_HANDLER(FrameHostMsg_RouteMessageEvent, OnRouteMessageEvent)
|
| IPC_MESSAGE_HANDLER(FrameHostMsg_DidChangeOpener, OnDidChangeOpener)
|
| IPC_MESSAGE_HANDLER(FrameHostMsg_AdvanceFocus, OnAdvanceFocus)
|
| @@ -268,6 +270,64 @@ void RenderFrameProxyHost::OnOpenURL(
|
| params.resource_request_body);
|
| }
|
|
|
| +bool RenderFrameProxyHost::CanForwardViolationToCurrentDocument(
|
| + const url::Origin& origin_declaring_violated_csp,
|
| + const std::string& violated_csp_header) {
|
| + RenderFrameHostImpl* current_rfh = frame_tree_node_->current_frame_host();
|
| + if (!origin_declaring_violated_csp.IsSameOriginWith(
|
| + current_rfh->GetLastCommittedOrigin())) {
|
| + return false;
|
| + }
|
| +
|
| + if (!current_rfh->frame_tree_node()->ContainsContentSecurityPolicyHeader(
|
| + violated_csp_header)) {
|
| + return false;
|
| + }
|
| +
|
| + return true;
|
| +}
|
| +
|
| +// TODO(lukasza): http://crbug.com/376522: Forwarding should not be needed once
|
| +// processing of frame-src, plugin-types and similar CSP directives is done in
|
| +// the browser process.
|
| +void RenderFrameProxyHost::OnForwardContentSecurityPolicyViolation(
|
| + const url::Origin& origin_declaring_violated_csp,
|
| + const ContentSecurityPolicyViolation& violation) {
|
| + // Try to verify that the CSP violation will be reported in the same document
|
| + // as the one that declared the violated CSP (i.e. that navigation of
|
| + // |current_rfh| didn't win a race with ForwardContentSecurityPolicyViolation
|
| + // IPC message).
|
| + //
|
| + // The checks made by CanForwardViolationToCurrentDocument are not 100%
|
| + // accurate, but a mistake should be safe to make until we can get rid of
|
| + // forwarding as part of moving CSP processing to the browser process
|
| + // (http://crbug.com/376522). The mistake should be safe, because:
|
| + // 1. We check that we don't disclose information cross-origin.
|
| + // 2. |violation.report_endpoints| works from any document of the right origin
|
| + // 3. It should be fine to write a console message as long as it reaches the
|
| + // console associated with the frame that used to host the document
|
| + // declaring the violated CSP.
|
| + // 4. In case of a race, an incorrect "securitypolicyviolation" event can be
|
| + // raised but this should be mitigated by:
|
| + // - low likelyhood of this happening (repro requires 1) different document
|
| + // from the same origin, 2) with the same csp header present, 3)
|
| + // navigated in a racey way with the csp check [e.g. navigating parent
|
| + // frame while checking child frame doesn't have the race - the child
|
| + // RFPH will be torn down before the violation-forwarding-ipc reaches
|
| + // it]).
|
| + // - low likelyhood of adverse effects (a page is unlikely to change its
|
| + // core behavior in response to a csp violation event)
|
| + if (!CanForwardViolationToCurrentDocument(origin_declaring_violated_csp,
|
| + violation.header)) {
|
| + return;
|
| + }
|
| +
|
| + // Forward CSP violation report to the frame that declared the CSP.
|
| + RenderFrameHostImpl* current_rfh = frame_tree_node_->current_frame_host();
|
| + current_rfh->Send(new FrameMsg_ReportContentSecurityPolicyViolation(
|
| + current_rfh->GetRoutingID(), violation));
|
| +}
|
| +
|
| void RenderFrameProxyHost::OnRouteMessageEvent(
|
| const FrameMsg_PostMessage_Params& params) {
|
| RenderFrameHostImpl* target_rfh = frame_tree_node()->current_frame_host();
|
|
|