summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authortsepez@chromium.org <tsepez@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-05-08 19:31:34 +0000
committertsepez@chromium.org <tsepez@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-05-08 19:31:34 +0000
commit6136d0622a9bc8cd3e5d339e31708bc31e420847 (patch)
treeabaaa069776336379fa026f90173c98b4163ff5b
parentca71ec7b50d002c0b16e5fea5003c38ce13d9788 (diff)
downloadchromium_src-6136d0622a9bc8cd3e5d339e31708bc31e420847.zip
chromium_src-6136d0622a9bc8cd3e5d339e31708bc31e420847.tar.gz
chromium_src-6136d0622a9bc8cd3e5d339e31708bc31e420847.tar.bz2
Check that the files the renderer wants to preserve as part of a session restore are already available to the renderer.
The fix involves cracking open the WebHistoryItem, extracting its file paths, and checking them against ChildProcessSecurityPolicy for the messages ViewHostMsg_UpdateState and ViewHostMsg_FrameNavigate. BUG=237263 R=darin@chromium.org Review URL: https://codereview.chromium.org/14727006 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@198965 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--content/browser/renderer_host/render_view_host_impl.cc29
-rw-r--r--content/browser/renderer_host/render_view_host_impl.h2
-rw-r--r--content/browser/renderer_host/render_view_host_unittest.cc38
-rw-r--r--content/browser/renderer_host/test_render_view_host.cc46
-rw-r--r--content/browser/renderer_host/test_render_view_host.h18
5 files changed, 122 insertions, 11 deletions
diff --git a/content/browser/renderer_host/render_view_host_impl.cc b/content/browser/renderer_host/render_view_host_impl.cc
index 8424da9..d3363f5 100644
--- a/content/browser/renderer_host/render_view_host_impl.cc
+++ b/content/browser/renderer_host/render_view_host_impl.cc
@@ -67,6 +67,7 @@
#include "ui/shell_dialogs/selected_file_info.h"
#include "ui/snapshot/snapshot.h"
#include "webkit/fileapi/isolated_context.h"
+#include "webkit/glue/glue_serialize.h"
#include "webkit/glue/webdropdata.h"
#include "webkit/glue/webkit_glue.h"
@@ -1224,11 +1225,25 @@ void RenderViewHostImpl::OnNavigate(const IPC::Message& msg) {
FilterURL(policy, process, true, &validated_params.password_form.origin);
FilterURL(policy, process, true, &validated_params.password_form.action);
+ // Without this check, the renderer can trick the browser into using
+ // filenames it can't access in a future session restore.
+ if (!CanAccessFilesOfSerializedState(validated_params.content_state)) {
+ GetProcess()->ReceivedBadMessage();
+ return;
+ }
+
delegate_->DidNavigate(this, validated_params);
}
void RenderViewHostImpl::OnUpdateState(int32 page_id,
const std::string& state) {
+ // Without this check, the renderer can trick the browser into using
+ // filenames it can't access in a future session restore.
+ if (!CanAccessFilesOfSerializedState(state)) {
+ GetProcess()->ReceivedBadMessage();
+ return;
+ }
+
delegate_->UpdateState(this, page_id, state);
}
@@ -2042,4 +2057,18 @@ void RenderViewHostImpl::ClearPowerSaveBlockers() {
STLDeleteValues(&power_save_blockers_);
}
+bool RenderViewHostImpl::CanAccessFilesOfSerializedState(
+ const std::string& state) const {
+ ChildProcessSecurityPolicyImpl* policy =
+ ChildProcessSecurityPolicyImpl::GetInstance();
+ const std::vector<base::FilePath>& file_paths =
+ webkit_glue::FilePathsFromHistoryState(state);
+ for (std::vector<base::FilePath>::const_iterator file = file_paths.begin();
+ file != file_paths.end(); ++file) {
+ if (!policy->CanReadFile(GetProcess()->GetID(), *file))
+ return false;
+ }
+ return true;
+}
+
} // namespace content
diff --git a/content/browser/renderer_host/render_view_host_impl.h b/content/browser/renderer_host/render_view_host_impl.h
index baa4b2e..a03ba43 100644
--- a/content/browser/renderer_host/render_view_host_impl.h
+++ b/content/browser/renderer_host/render_view_host_impl.h
@@ -562,6 +562,8 @@ class CONTENT_EXPORT RenderViewHostImpl
void ClearPowerSaveBlockers();
+ bool CanAccessFilesOfSerializedState(const std::string& state) const;
+
// Our delegate, which wants to know about changes in the RenderView.
RenderViewHostDelegate* delegate_;
diff --git a/content/browser/renderer_host/render_view_host_unittest.cc b/content/browser/renderer_host/render_view_host_unittest.cc
index 7c5898e..38bb777 100644
--- a/content/browser/renderer_host/render_view_host_unittest.cc
+++ b/content/browser/renderer_host/render_view_host_unittest.cc
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "base/path_service.h"
#include "base/utf_string_conversions.h"
#include "content/browser/child_process_security_policy_impl.h"
#include "content/browser/renderer_host/test_render_view_host.h"
@@ -261,4 +262,41 @@ TEST_F(RenderViewHostTest, BadMessageHandlerInputEventAck) {
#endif
+TEST_F(RenderViewHostTest, MessageWithBadHistoryItemFiles) {
+ base::FilePath file_path;
+ EXPECT_TRUE(PathService::Get(base::DIR_TEMP, &file_path));
+ file_path = file_path.AppendASCII("foo");
+ EXPECT_EQ(0, process()->bad_msg_count());
+ test_rvh()->TestOnUpdateStateWithFile(process()->GetID(), file_path);
+ EXPECT_EQ(1, process()->bad_msg_count());
+
+ ChildProcessSecurityPolicyImpl::GetInstance()->GrantPermissionsForFile(
+ process()->GetID(), file_path,
+ base::PLATFORM_FILE_OPEN |
+ base::PLATFORM_FILE_READ |
+ base::PLATFORM_FILE_EXCLUSIVE_READ |
+ base::PLATFORM_FILE_ASYNC);
+ test_rvh()->TestOnUpdateStateWithFile(process()->GetID(), file_path);
+ EXPECT_EQ(1, process()->bad_msg_count());
+}
+
+TEST_F(RenderViewHostTest, NavigationWithBadHistoryItemFiles) {
+ GURL url("http://www.google.com");
+ base::FilePath file_path;
+ EXPECT_TRUE(PathService::Get(base::DIR_TEMP, &file_path));
+ file_path = file_path.AppendASCII("bar");
+ EXPECT_EQ(0, process()->bad_msg_count());
+ test_rvh()->SendNavigateWithFile(1, url, file_path);
+ EXPECT_EQ(1, process()->bad_msg_count());
+
+ ChildProcessSecurityPolicyImpl::GetInstance()->GrantPermissionsForFile(
+ process()->GetID(), file_path,
+ base::PLATFORM_FILE_OPEN |
+ base::PLATFORM_FILE_READ |
+ base::PLATFORM_FILE_EXCLUSIVE_READ |
+ base::PLATFORM_FILE_ASYNC);
+ test_rvh()->SendNavigateWithFile(process()->GetID(), url, file_path);
+ EXPECT_EQ(1, process()->bad_msg_count());
+}
+
} // namespace content
diff --git a/content/browser/renderer_host/test_render_view_host.cc b/content/browser/renderer_host/test_render_view_host.cc
index 0e1792a..6f5310f 100644
--- a/content/browser/renderer_host/test_render_view_host.cc
+++ b/content/browser/renderer_host/test_render_view_host.cc
@@ -289,21 +289,27 @@ void TestRenderViewHost::SendNavigateWithOriginalRequestURL(
int page_id, const GURL& url, const GURL& original_request_url) {
OnDidStartProvisionalLoadForFrame(0, -1, true, url);
SendNavigateWithParameters(page_id, url, PAGE_TRANSITION_LINK,
- original_request_url, 200);
+ original_request_url, 200, 0);
+}
+
+void TestRenderViewHost::SendNavigateWithFile(
+ int page_id, const GURL& url, const base::FilePath& file_path) {
+ SendNavigateWithParameters(page_id, url, PAGE_TRANSITION_LINK,
+ url, 200, &file_path);
}
void TestRenderViewHost::SendNavigateWithTransitionAndResponseCode(
int page_id, const GURL& url, PageTransition transition,
int response_code) {
OnDidStartProvisionalLoadForFrame(0, -1, true, url);
- SendNavigateWithParameters(page_id, url, transition, url, response_code);
+ SendNavigateWithParameters(page_id, url, transition, url, response_code, 0);
}
void TestRenderViewHost::SendNavigateWithParameters(
int page_id, const GURL& url, PageTransition transition,
- const GURL& original_request_url, int response_code) {
+ const GURL& original_request_url, int response_code,
+ const base::FilePath* file_path_for_history_item) {
ViewHostMsg_FrameNavigate_Params params;
-
params.page_id = page_id;
params.frame_id = 0;
params.url = url;
@@ -324,9 +330,23 @@ void TestRenderViewHost::SendNavigateWithParameters(
params.socket_address.set_port(80);
params.was_fetched_via_proxy = simulate_fetch_via_proxy_;
params.history_list_was_cleared = simulate_history_list_was_cleared_;
- params.content_state = webkit_glue::CreateHistoryStateForURL(GURL(url));
params.original_request_url = original_request_url;
+ WebKit::WebHTTPBody http_body;
+ http_body.initialize();
+
+ WebKit::WebHistoryItem history_item;
+ history_item.initialize();
+ history_item.setURLString(WebKit::WebString::fromUTF8(url.spec()));
+ if (file_path_for_history_item) {
+ const char char_data[] = "data";
+ http_body.appendData(WebKit::WebData(char_data, arraysize(char_data)-1));
+ http_body.appendFile(WebKit::WebString::fromUTF8(
+ file_path_for_history_item->MaybeAsASCII()));
+ history_item.setHTTPBody(http_body);
+ }
+ params.content_state = webkit_glue::HistoryItemToString(history_item);
+
ViewHostMsg_FrameNavigate msg(1, params);
OnNavigate(msg);
}
@@ -360,6 +380,22 @@ void TestRenderViewHost::TestOnStartDragging(
event_info);
}
+void TestRenderViewHost::TestOnUpdateStateWithFile(
+ int process_id,
+ const base::FilePath& file_path) {
+ WebKit::WebHTTPBody http_body;
+ http_body.initialize();
+ const char char_data[] = "data";
+ http_body.appendData(WebKit::WebData(char_data, arraysize(char_data)-1));
+ http_body.appendFile(WebKit::WebString::fromUTF8(file_path.MaybeAsASCII()));
+
+ WebKit::WebHistoryItem history_item;
+ history_item.initialize();
+ history_item.setURLString("http://www.google.com");
+ history_item.setHTTPBody(http_body);
+ OnUpdateState(process_id, webkit_glue::HistoryItemToString(history_item));
+}
+
void TestRenderViewHost::set_simulate_fetch_via_proxy(bool proxy) {
simulate_fetch_via_proxy_ = proxy;
}
diff --git a/content/browser/renderer_host/test_render_view_host.h b/content/browser/renderer_host/test_render_view_host.h
index a6ec555..68634d4 100644
--- a/content/browser/renderer_host/test_render_view_host.h
+++ b/content/browser/renderer_host/test_render_view_host.h
@@ -246,6 +246,11 @@ class TestRenderViewHost
void SendNavigateWithOriginalRequestURL(
int page_id, const GURL& url, const GURL& original_request_url);
+ void SendNavigateWithFile(
+ int page_id, const GURL& url, const base::FilePath& file_path);
+
+ void TestOnUpdateStateWithFile(
+ int process_id, const base::FilePath& file_path);
void TestOnStartDragging(const WebDropData& drop_data);
@@ -307,12 +312,13 @@ class TestRenderViewHost
// Calls OnNavigate on the RenderViewHost with the given information.
// Sets the rest of the parameters in the message to the "typical" values.
// This is a helper function for simulating the most common types of loads.
- void SendNavigateWithParameters(int page_id,
- const GURL& url,
- PageTransition transition,
- const GURL& original_request_url,
- int response_code);
-
+ void SendNavigateWithParameters(
+ int page_id,
+ const GURL& url,
+ PageTransition transition,
+ const GURL& original_request_url,
+ int response_code,
+ const base::FilePath* file_path_for_history_item);
// Tracks if the caller thinks if it created the RenderView. This is so we can
// respond to IsRenderViewLive appropriately.