Chromium Code Reviews| Index: content/child/resource_dispatcher.cc |
| diff --git a/content/child/resource_dispatcher.cc b/content/child/resource_dispatcher.cc |
| index 424902fb0411288794a78d12f8710e7034edd9d5..ec68171d796fa967abc640558ebba9434eea9071 100644 |
| --- a/content/child/resource_dispatcher.cc |
| +++ b/content/child/resource_dispatcher.cc |
| @@ -8,6 +8,7 @@ |
| #include "base/basictypes.h" |
| #include "base/bind.h" |
| +#include "base/command_line.h" |
| #include "base/compiler_specific.h" |
| #include "base/debug/alias.h" |
| #include "base/files/file_path.h" |
| @@ -16,9 +17,11 @@ |
| #include "base/metrics/histogram.h" |
| #include "base/strings/string_util.h" |
| #include "content/child/request_extra_data.h" |
| +#include "content/child/site_isolation_policy.h" |
| #include "content/common/inter_process_time_ticks_converter.h" |
| #include "content/common/resource_messages.h" |
| #include "content/public/child/resource_dispatcher_delegate.h" |
| +#include "content/public/common/content_switches.h" |
| #include "content/public/common/resource_response.h" |
| #include "net/base/net_errors.h" |
| #include "net/base/net_util.h" |
| @@ -96,6 +99,9 @@ class IPCResourceLoaderBridge : public ResourceLoaderBridge { |
| // The routing id used when sending IPC messages. |
| int routing_id_; |
| + // The security origin of the frame that initiates this request. |
| + GURL frame_origin_; |
| + |
| bool is_synchronous_request_; |
| }; |
| @@ -135,6 +141,7 @@ IPCResourceLoaderBridge::IPCResourceLoaderBridge( |
| extra_data->transferred_request_child_id(); |
| request_.transferred_request_request_id = |
| extra_data->transferred_request_request_id(); |
| + frame_origin_ = extra_data->frame_origin(); |
| } else { |
| request_.is_main_frame = false; |
| request_.frame_id = -1; |
| @@ -179,7 +186,7 @@ bool IPCResourceLoaderBridge::Start(Peer* peer) { |
| // generate the request ID, and append it to the message |
| request_id_ = dispatcher_->AddPendingRequest( |
| - peer_, request_.resource_type, request_.url); |
| + peer_, request_.resource_type, frame_origin_, request_.url); |
| return dispatcher_->message_sender()->Send( |
| new ResourceHostMsg_RequestResource(routing_id_, request_id_, request_)); |
| @@ -346,6 +353,11 @@ void ResourceDispatcher::OnReceivedResponse( |
| ResourceResponseInfo renderer_response_info; |
| ToResourceResponseInfo(*request_info, response_head, &renderer_response_info); |
| + SiteIsolationPolicy::OnReceivedResponse(request_id, |
| + request_info->frame_origin, |
| + request_info->response_url, |
| + request_info->resource_type, |
| + renderer_response_info); |
| request_info->peer->OnReceivedResponse(renderer_response_info); |
| } |
| @@ -411,10 +423,33 @@ void ResourceDispatcher::OnReceivedData(const IPC::Message& message, |
| CHECK(data_ptr); |
| CHECK(data_ptr + data_offset); |
|
darin (slow to review)
2013/08/22 21:50:42
perhaps another option here is to call a method on
dsjang
2013/08/22 22:30:19
Done.
|
| - request_info->peer->OnReceivedData( |
| - data_ptr + data_offset, |
| - data_length, |
| - encoded_data_length); |
| + // Check whether this response data is compliant with our cross-site |
| + // document blocking policy. |
| + bool blocked_response = SiteIsolationPolicy::ShouldBlockResponse( |
| + request_id, data_ptr + data_offset, data_length); |
| + |
| + // We block a response when the command line switch is on. |
| + const CommandLine& command_line = *CommandLine::ForCurrentProcess(); |
| + if (blocked_response && |
| + command_line.HasSwitch(switches::kBlockCrossSiteDocuments)) { |
| + // If data_offset is not-zero, this is not the first data packet for |
| + // this request. We just ignore it. |
| + if (data_offset == 0) { |
| + // If we decide to block the response data, we just return an empty |
| + // one-character string as response data. This is needed to trigger |
| + // parsing errors in image decoders, etc. |
| + LOG(ERROR) << request_info->response_url |
| + << " is blocked as an illegal cross-site document from " |
| + << request_info->frame_origin; |
| + const char* empty_data_ptr = " "; |
| + request_info->peer->OnReceivedData(empty_data_ptr, 1, 1); |
| + } |
| + } else { |
| + request_info->peer->OnReceivedData( |
| + data_ptr + data_offset, |
| + data_length, |
| + encoded_data_length); |
| + } |
| UMA_HISTOGRAM_TIMES("ResourceDispatcher.OnReceivedDataTime", |
| base::TimeTicks::Now() - time_start); |
| @@ -462,6 +497,9 @@ void ResourceDispatcher::OnReceivedRedirect( |
| request_info = GetPendingRequestInfo(request_id); |
| if (!request_info) |
| return; |
| + // We update the response_url here so that we can send it to |
| + // SiteIsolationPolicy later when OnReceivedResponse is called. |
| + request_info->response_url = new_url; |
| request_info->pending_redirect_message.reset( |
| new ResourceHostMsg_FollowRedirect(routing_id, request_id, |
| has_new_first_party_for_cookies, |
| @@ -488,6 +526,8 @@ void ResourceDispatcher::OnRequestComplete( |
| bool was_ignored_by_handler, |
| const std::string& security_info, |
| const base::TimeTicks& browser_completion_time) { |
| + SiteIsolationPolicy::OnRequestComplete(request_id); |
| + |
| PendingRequestInfo* request_info = GetPendingRequestInfo(request_id); |
| if (!request_info) |
| return; |
| @@ -517,11 +557,12 @@ void ResourceDispatcher::OnRequestComplete( |
| int ResourceDispatcher::AddPendingRequest( |
| ResourceLoaderBridge::Peer* callback, |
| ResourceType::Type resource_type, |
| + const GURL& frame_origin, |
| const GURL& request_url) { |
| // Compute a unique request_id for this renderer process. |
| int id = MakeRequestID(); |
| pending_requests_[id] = |
| - PendingRequestInfo(callback, resource_type, request_url); |
| + PendingRequestInfo(callback, resource_type, frame_origin, request_url); |
| return id; |
| } |
| @@ -530,6 +571,7 @@ bool ResourceDispatcher::RemovePendingRequest(int request_id) { |
| if (it == pending_requests_.end()) |
| return false; |
| + SiteIsolationPolicy::OnRequestComplete(request_id); |
| PendingRequestInfo& request_info = it->second; |
| ReleaseResourcesInMessageQueue(&request_info.deferred_message_queue); |
| pending_requests_.erase(it); |
| @@ -545,6 +587,7 @@ void ResourceDispatcher::CancelPendingRequest(int routing_id, |
| return; |
| } |
| + SiteIsolationPolicy::OnRequestComplete(request_id); |
| PendingRequestInfo& request_info = it->second; |
| ReleaseResourcesInMessageQueue(&request_info.deferred_message_queue); |
| pending_requests_.erase(it); |
| @@ -592,11 +635,14 @@ ResourceDispatcher::PendingRequestInfo::PendingRequestInfo() |
| ResourceDispatcher::PendingRequestInfo::PendingRequestInfo( |
| webkit_glue::ResourceLoaderBridge::Peer* peer, |
| ResourceType::Type resource_type, |
| + const GURL& frame_origin, |
| const GURL& request_url) |
| : peer(peer), |
| resource_type(resource_type), |
| is_deferred(false), |
| url(request_url), |
| + frame_origin(frame_origin), |
| + response_url(request_url), |
| request_start(base::TimeTicks::Now()) { |
| } |