Index: content/child/resource_dispatcher.cc |
diff --git a/content/child/resource_dispatcher.cc b/content/child/resource_dispatcher.cc |
index 424902fb0411288794a78d12f8710e7034edd9d5..e0fff23b47c68ace66252d5c67661a15cc10d068 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 |
Charlie Reis
2013/08/22 18:23:30
nit: End with period.
dsjang
2013/08/22 19:05:55
Done.
|
+ 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); |
- 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 ok_response = SiteIsolationPolicy::OnReceivedData( |
Charlie Reis
2013/08/22 18:23:30
This name doesn't describe what the function is do
dsjang
2013/08/22 19:05:55
Done.
|
+ 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 (!ok_response && |
+ command_line.HasSwitch(switches::kCrossSiteDocumentBlocking)) { |
+ // if data_offset is not-zero, this is not the first data packet for |
Charlie Reis
2013/08/22 18:23:30
Nit: capitalize sentence.
dsjang
2013/08/22 19:05:55
Done.
|
+ // 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 |
Charlie Reis
2013/08/22 18:23:30
nit: Remove the colon and just have two sentences.
dsjang
2013/08/22 19:05:55
Done.
|
+ // 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 sent it to |
Charlie Reis
2013/08/22 18:23:30
nit: sent -> send
dsjang
2013/08/22 19:05:55
Done.
|
+ // 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,11 @@ void ResourceDispatcher::OnRequestComplete( |
bool was_ignored_by_handler, |
const std::string& security_info, |
const base::TimeTicks& browser_completion_time) { |
+ // TODO(dsjang): This logging code is just temporary. There has to |
+ // be a better way to connect the received data to the response_url |
Charlie Reis
2013/08/22 18:23:30
I don't understand this comment.
1) Are you planni
dsjang
2013/08/22 19:05:55
With the blocking logic, everything about SiteIsol
|
+ // than this. |
+ SiteIsolationPolicy::OnRequestComplete(request_id); |
+ |
PendingRequestInfo* request_info = GetPendingRequestInfo(request_id); |
if (!request_info) |
return; |
@@ -507,6 +550,7 @@ void ResourceDispatcher::OnRequestComplete( |
base::TimeTicks renderer_completion_time = ToRendererCompletionTime( |
*request_info, browser_completion_time); |
+ |
Charlie Reis
2013/08/22 18:23:30
nit: Don't add extra line.
dsjang
2013/08/22 19:05:55
Done.
|
// The request ID will be removed from our pending list in the destructor. |
// Normally, dispatching this message causes the reference-counted request to |
// die immediately. |
@@ -517,11 +561,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 +575,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 +591,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 +639,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()) { |
} |