Index: media/blink/buffered_data_source.cc |
diff --git a/media/blink/buffered_data_source.cc b/media/blink/buffered_data_source.cc |
index d5f32b1ca298d4c787731c70eb26ead26632bea0..0a86add877f42f3cc20381363d96db359f2e2cfd 100644 |
--- a/media/blink/buffered_data_source.cc |
+++ b/media/blink/buffered_data_source.cc |
@@ -10,6 +10,8 @@ |
#include "base/single_thread_task_runner.h" |
#include "media/base/media_log.h" |
#include "net/base/net_errors.h" |
+#include "third_party/WebKit/public/platform/WebSecurityOrigin.h" |
+#include "third_party/WebKit/public/web/WebFrame.h" |
using blink::WebFrame; |
@@ -356,6 +358,7 @@ void BufferedDataSource::StartCallback( |
loader_->Stop(); |
return; |
} |
+ response_original_url_ = loader_->response_original_url(); |
// All responses must be successful. Resources that are assumed to be fully |
// buffered must have a known content length. |
@@ -403,8 +406,8 @@ void BufferedDataSource::PartialReadStartCallback( |
BufferedResourceLoader::Status status) { |
DCHECK(render_task_runner_->BelongsToCurrentThread()); |
DCHECK(loader_.get()); |
- |
- if (status == BufferedResourceLoader::kOk) { |
+ if (status == BufferedResourceLoader::kOk && |
+ CheckPartialResponseURL(loader_->response_original_url())) { |
// Once the request has started successfully, we can proceed with |
// reading from it. |
ReadInternal(); |
@@ -422,6 +425,30 @@ void BufferedDataSource::PartialReadStartCallback( |
ReadOperation::Run(read_op_.Pass(), kReadError); |
} |
+bool BufferedDataSource::CheckPartialResponseURL( |
+ const GURL& partial_response_original_url) const { |
+ // We check the redirected URL of partial responses in case malicious |
+ // attackers scan the bytes of other origin resources by mixing their |
+ // generated bytes and the target response. See http://crbug.com/489060#c32 |
+ // for details. |
+ |
+ // If the SecurityOrigin of the frame can read content of the new response, we |
+ // accept. |
+ if (frame_->securityOrigin().canRequest(partial_response_original_url)) |
+ return true; |
+ |
+ // If the response is generated in a Service Worker we accept. The Service |
+ // Worker script must be in the same origin as document requesting this URL, |
+ // so the response can be readable by the document. |
+ if (partial_response_original_url.is_empty()) |
+ return true; |
+ |
+ // If the origin of the new response is different from the first response we |
+ // deny the redirected response. |
+ return response_original_url_.GetOrigin() == |
+ partial_response_original_url.GetOrigin(); |
+} |
+ |
void BufferedDataSource::ReadCallback( |
BufferedResourceLoader::Status status, |
int bytes_read) { |