| Index: content/browser/renderer_host/render_view_host_impl.cc
|
| diff --git a/content/browser/renderer_host/render_view_host_impl.cc b/content/browser/renderer_host/render_view_host_impl.cc
|
| index e6cdcc9631e1560aee662b8e7fc96c97bbb26283..75de0517a94ee3fe93a34d67c7dfea60702b83c1 100644
|
| --- a/content/browser/renderer_host/render_view_host_impl.cc
|
| +++ b/content/browser/renderer_host/render_view_host_impl.cc
|
| @@ -131,11 +131,11 @@ RenderViewHost* RenderViewHost::From(RenderWidgetHost* rwh) {
|
| }
|
|
|
| // static
|
| -void RenderViewHost::FilterURL(int renderer_id,
|
| +void RenderViewHost::FilterURL(const RenderProcessHost* process,
|
| bool empty_allowed,
|
| GURL* url) {
|
| RenderViewHostImpl::FilterURL(ChildProcessSecurityPolicyImpl::GetInstance(),
|
| - renderer_id, empty_allowed, url);
|
| + process, empty_allowed, url);
|
| }
|
|
|
| ///////////////////////////////////////////////////////////////////////////////
|
| @@ -268,6 +268,8 @@ bool RenderViewHostImpl::CreateRenderView(
|
|
|
| // If it's enabled, tell the renderer to set up the Javascript bindings for
|
| // sending messages back to the browser.
|
| + if (GetProcess()->IsGuest())
|
| + DCHECK_EQ(0, enabled_bindings_);
|
| Send(new ViewMsg_AllowBindings(GetRoutingID(), enabled_bindings_));
|
| // Let our delegate know that we created a RenderView.
|
| delegate_->RenderViewCreated(this);
|
| @@ -289,14 +291,18 @@ void RenderViewHostImpl::SyncRendererPrefs() {
|
| }
|
|
|
| void RenderViewHostImpl::Navigate(const ViewMsg_Navigate_Params& params) {
|
| - ChildProcessSecurityPolicyImpl::GetInstance()->GrantRequestURL(
|
| - GetProcess()->GetID(), params.url);
|
| - if (params.url.SchemeIs(chrome::kDataScheme) &&
|
| - params.base_url_for_data_url.SchemeIs(chrome::kFileScheme)) {
|
| - // If 'data:' is used, and we have a 'file:' base url, grant access to
|
| - // local files.
|
| + // Browser plugin guests are not allowed to navigate outside web-safe schemes,
|
| + // so do not grant them the ability to request additional URLs.
|
| + if (!GetProcess()->IsGuest()) {
|
| ChildProcessSecurityPolicyImpl::GetInstance()->GrantRequestURL(
|
| - GetProcess()->GetID(), params.base_url_for_data_url);
|
| + GetProcess()->GetID(), params.url);
|
| + if (params.url.SchemeIs(chrome::kDataScheme) &&
|
| + params.base_url_for_data_url.SchemeIs(chrome::kFileScheme)) {
|
| + // If 'data:' is used, and we have a 'file:' base url, grant access to
|
| + // local files.
|
| + ChildProcessSecurityPolicyImpl::GetInstance()->GrantRequestURL(
|
| + GetProcess()->GetID(), params.base_url_for_data_url);
|
| + }
|
| }
|
|
|
| ViewMsg_Navigate* nav_message = new ViewMsg_Navigate(GetRoutingID(), params);
|
| @@ -591,7 +597,7 @@ void RenderViewHostImpl::DragTargetDragEnter(
|
| // The URL could have been cobbled together from any highlighted text string,
|
| // and can't be interpreted as a capability.
|
| WebDropData filtered_data(drop_data);
|
| - FilterURL(policy, renderer_id, true, &filtered_data.url);
|
| + FilterURL(policy, GetProcess(), true, &filtered_data.url);
|
|
|
| // The filenames vector, on the other hand, does represent a capability to
|
| // access the given files.
|
| @@ -817,6 +823,12 @@ void RenderViewHostImpl::AllowBindings(int bindings_flags) {
|
| return;
|
| }
|
|
|
| + // Never grant any bindings to browser plugin guests.
|
| + if (GetProcess()->IsGuest()) {
|
| + NOTREACHED() << "Never grant bindings to a guest process.";
|
| + return;
|
| + }
|
| +
|
| if (bindings_flags & BINDINGS_POLICY_WEB_UI) {
|
| ChildProcessSecurityPolicyImpl::GetInstance()->GrantWebUIBindings(
|
| GetProcess()->GetID());
|
| @@ -1221,7 +1233,7 @@ void RenderViewHostImpl::OnMsgNavigate(const IPC::Message& msg) {
|
| if (is_waiting_for_unload_ack_)
|
| return;
|
|
|
| - const int renderer_id = GetProcess()->GetID();
|
| + RenderProcessHost* process = GetProcess();
|
| ChildProcessSecurityPolicyImpl* policy =
|
| ChildProcessSecurityPolicyImpl::GetInstance();
|
| // Without this check, an evil renderer can trick the browser into creating
|
| @@ -1231,15 +1243,15 @@ void RenderViewHostImpl::OnMsgNavigate(const IPC::Message& msg) {
|
| // renderer to load the URL and grant the renderer the privileges to request
|
| // the URL. To prevent this attack, we block the renderer from inserting
|
| // banned URLs into the navigation controller in the first place.
|
| - FilterURL(policy, renderer_id, false, &validated_params.url);
|
| - FilterURL(policy, renderer_id, true, &validated_params.referrer.url);
|
| + FilterURL(policy, process, false, &validated_params.url);
|
| + FilterURL(policy, process, true, &validated_params.referrer.url);
|
| for (std::vector<GURL>::iterator it(validated_params.redirects.begin());
|
| it != validated_params.redirects.end(); ++it) {
|
| - FilterURL(policy, renderer_id, false, &(*it));
|
| + FilterURL(policy, process, false, &(*it));
|
| }
|
| - FilterURL(policy, renderer_id, true, &validated_params.searchable_form_url);
|
| - FilterURL(policy, renderer_id, true, &validated_params.password_form.origin);
|
| - FilterURL(policy, renderer_id, true, &validated_params.password_form.action);
|
| + FilterURL(policy, process, true, &validated_params.searchable_form_url);
|
| + FilterURL(policy, process, true, &validated_params.password_form.origin);
|
| + FilterURL(policy, process, true, &validated_params.password_form.action);
|
|
|
| delegate_->DidNavigate(this, validated_params);
|
|
|
| @@ -1323,16 +1335,16 @@ void RenderViewHostImpl::OnMsgContextMenu(const ContextMenuParams& params) {
|
| // Validate the URLs in |params|. If the renderer can't request the URLs
|
| // directly, don't show them in the context menu.
|
| ContextMenuParams validated_params(params);
|
| - int renderer_id = GetProcess()->GetID();
|
| + RenderProcessHost* process = GetProcess();
|
| ChildProcessSecurityPolicyImpl* policy =
|
| ChildProcessSecurityPolicyImpl::GetInstance();
|
|
|
| // We don't validate |unfiltered_link_url| so that this field can be used
|
| // when users want to copy the original link URL.
|
| - FilterURL(policy, renderer_id, true, &validated_params.link_url);
|
| - FilterURL(policy, renderer_id, true, &validated_params.src_url);
|
| - FilterURL(policy, renderer_id, false, &validated_params.page_url);
|
| - FilterURL(policy, renderer_id, true, &validated_params.frame_url);
|
| + FilterURL(policy, process, true, &validated_params.link_url);
|
| + FilterURL(policy, process, true, &validated_params.src_url);
|
| + FilterURL(policy, process, false, &validated_params.page_url);
|
| + FilterURL(policy, process, true, &validated_params.frame_url);
|
|
|
| ContextMenuSourceType type = CONTEXT_MENU_SOURCE_MOUSE;
|
| if (!in_process_event_types_.empty()) {
|
| @@ -1357,7 +1369,7 @@ void RenderViewHostImpl::OnMsgOpenURL(const GURL& url,
|
| int64 source_frame_id) {
|
| GURL validated_url(url);
|
| FilterURL(ChildProcessSecurityPolicyImpl::GetInstance(),
|
| - GetProcess()->GetID(), false, &validated_url);
|
| + GetProcess(), false, &validated_url);
|
|
|
| delegate_->RequestOpenURL(
|
| this, validated_url, referrer, disposition, source_frame_id);
|
| @@ -1452,13 +1464,14 @@ void RenderViewHostImpl::OnMsgStartDragging(
|
| return;
|
|
|
| WebDropData filtered_data(drop_data);
|
| + RenderProcessHost* process = GetProcess();
|
| ChildProcessSecurityPolicyImpl* policy =
|
| ChildProcessSecurityPolicyImpl::GetInstance();
|
|
|
| // Allow drag of Javascript URLs to enable bookmarklet drag to bookmark bar.
|
| if (!filtered_data.url.SchemeIs(chrome::kJavaScriptScheme))
|
| - FilterURL(policy, GetProcess()->GetID(), true, &filtered_data.url);
|
| - FilterURL(policy, GetProcess()->GetID(), false, &filtered_data.html_base_url);
|
| + FilterURL(policy, process, true, &filtered_data.url);
|
| + FilterURL(policy, process, false, &filtered_data.html_base_url);
|
| // Filter out any paths that the renderer didn't have access to. This prevents
|
| // the following attack on a malicious renderer:
|
| // 1. StartDragging IPC sent with renderer-specified filesystem paths that it
|
| @@ -1699,7 +1712,7 @@ void RenderViewHostImpl::ToggleSpeechInput() {
|
| }
|
|
|
| void RenderViewHostImpl::FilterURL(ChildProcessSecurityPolicyImpl* policy,
|
| - int renderer_id,
|
| + const RenderProcessHost* process,
|
| bool empty_allowed,
|
| GURL* url) {
|
| if (empty_allowed && url->is_empty())
|
| @@ -1720,7 +1733,12 @@ void RenderViewHostImpl::FilterURL(ChildProcessSecurityPolicyImpl* policy,
|
| *url = GURL(chrome::kAboutBlankURL);
|
| }
|
|
|
| - if (!policy->CanRequestURL(renderer_id, *url)) {
|
| + // Do not allow browser plugin guests to navigate to non-web URLs, since they
|
| + // cannot swap processes or grant bindings.
|
| + bool non_web_url_in_guest = process->IsGuest() &&
|
| + !(url->is_valid() && policy->IsWebSafeScheme(url->scheme()));
|
| +
|
| + if (non_web_url_in_guest || !policy->CanRequestURL(process->GetID(), *url)) {
|
| // If this renderer is not permitted to request this URL, we invalidate the
|
| // URL. This prevents us from storing the blocked URL and becoming confused
|
| // later.
|
|
|