diff options
author | mpcomplete@google.com <mpcomplete@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-06-05 18:23:21 +0000 |
---|---|---|
committer | mpcomplete@google.com <mpcomplete@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-06-05 18:23:21 +0000 |
commit | 9dd9e83865f58d2c886f6be38575bdffc66fb074 (patch) | |
tree | 9ac8ac752f4e3a23a33a7428d23b7077ac947a98 /chrome | |
parent | 0a21bc3b65b20d0fb6e52bdbfdb9d0ff34e43a3c (diff) | |
download | chromium_src-9dd9e83865f58d2c886f6be38575bdffc66fb074.zip chromium_src-9dd9e83865f58d2c886f6be38575bdffc66fb074.tar.gz chromium_src-9dd9e83865f58d2c886f6be38575bdffc66fb074.tar.bz2 |
Refuse to load extension-private plugins for pages that don't belong to that
extension.
BUG=12960
TEST=none
Review URL: http://codereview.chromium.org/118198
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@17743 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r-- | chrome/browser/plugin_service.cc | 37 | ||||
-rw-r--r-- | chrome/browser/plugin_service.h | 30 | ||||
-rw-r--r-- | chrome/browser/renderer_host/resource_message_filter.cc | 3 | ||||
-rw-r--r-- | chrome/browser/renderer_host/resource_message_filter.h | 1 | ||||
-rw-r--r-- | chrome/common/render_messages_internal.h | 3 | ||||
-rw-r--r-- | chrome/renderer/render_view.cc | 6 |
6 files changed, 59 insertions, 21 deletions
diff --git a/chrome/browser/plugin_service.cc b/chrome/browser/plugin_service.cc index 10a56f5..773698a 100644 --- a/chrome/browser/plugin_service.cc +++ b/chrome/browser/plugin_service.cc @@ -158,7 +158,10 @@ void PluginService::OpenChannelToPlugin( const std::wstring& locale, IPC::Message* reply_msg) { DCHECK(MessageLoop::current() == ChromeThread::GetMessageLoop(ChromeThread::IO)); - FilePath plugin_path = GetPluginPath(url, mime_type, clsid, NULL); + // We don't need a policy URL here because that was already checked by a + // previous call to GetPluginPath. + GURL policy_url; + FilePath plugin_path = GetPluginPath(url, policy_url, mime_type, clsid, NULL); PluginProcessHost* plugin_host = FindOrStartPluginProcess(plugin_path, clsid); if (plugin_host) { plugin_host->OpenChannelToPlugin(renderer_msg_filter, mime_type, reply_msg); @@ -171,16 +174,21 @@ void PluginService::OpenChannelToPlugin( } FilePath PluginService::GetPluginPath(const GURL& url, + const GURL& policy_url, const std::string& mime_type, const std::string& clsid, std::string* actual_mime_type) { AutoLock lock(lock_); bool allow_wildcard = true; WebPluginInfo info; - NPAPI::PluginList::Singleton()->GetPluginInfo(url, mime_type, clsid, - allow_wildcard, &info, - actual_mime_type); - return info.path; + if (NPAPI::PluginList::Singleton()->GetPluginInfo(url, mime_type, clsid, + allow_wildcard, &info, + actual_mime_type) && + PluginAllowedForURL(info.path, policy_url)) { + return info.path; + } + + return FilePath(); } bool PluginService::GetPluginInfoByPath(const FilePath& plugin_path, @@ -233,10 +241,11 @@ void PluginService::Observe(NotificationType type, extension != extensions->end(); ++extension) { for (size_t i = 0; i < (*extension)->plugins().size(); ++i ) { const Extension::PluginInfo& plugin = (*extension)->plugins()[i]; - // TODO(mpcomplete): pass through plugin.is_public AutoLock lock(lock_); NPAPI::PluginList::ResetPluginsLoaded(); NPAPI::PluginList::AddExtraPluginPath(plugin.path); + if (!plugin.is_public) + private_plugins_[plugin.path] = (*extension)->url(); } } break; @@ -253,3 +262,19 @@ void PluginService::Observe(NotificationType type, DCHECK(false); } } + +bool PluginService::PluginAllowedForURL(const FilePath& plugin_path, + const GURL& url) { + if (url.is_empty()) + return true; // Caller wants all plugins. + + PrivatePluginMap::iterator it = private_plugins_.find(plugin_path); + if (it == private_plugins_.end()) + return true; // This plugin is not private, so it's allowed everywhere. + + // We do a dumb compare of scheme and host, rather than using the domain + // service, since we only care about this for extensions. + const GURL& required_url = it->second; + return (url.scheme() == required_url.scheme() && + url.host() == required_url.host()); +} diff --git a/chrome/browser/plugin_service.h b/chrome/browser/plugin_service.h index b77d731..8bcbf7c 100644 --- a/chrome/browser/plugin_service.h +++ b/chrome/browser/plugin_service.h @@ -19,6 +19,7 @@ #include "chrome/browser/browser_process.h" #include "chrome/common/notification_observer.h" #include "chrome/common/notification_registrar.h" +#include "googleurl/src/gurl.h" #include "webkit/glue/webplugininfo.h" #if defined(OS_WIN) @@ -29,7 +30,6 @@ namespace IPC { class Message; } -class GURL; class MessageLoop; class PluginProcessHost; class URLRequestContext; @@ -84,21 +84,15 @@ class PluginService bool HavePluginFor(const std::string& mime_type, bool allow_wildcard); + // Get the path to the plugin specified. policy_url is the URL of the page + // requesting the plugin, so we can verify whether the plugin is allowed + // on that page. FilePath GetPluginPath(const GURL& url, + const GURL& policy_url, const std::string& mime_type, const std::string& clsid, std::string* actual_mime_type); - // Get plugin info by matching full path. - bool GetPluginInfoByPath(const FilePath& plugin_path, - WebPluginInfo* info); - - // Returns true if the plugin's mime-type supports a given mime-type. - // Checks for absolute matching and wildcards. mime-types should be in - // lower case. - bool SupportsMimeType(const std::wstring& plugin_mime_type, - const std::wstring& mime_type); - // The UI thread's message loop MessageLoop* main_message_loop() { return main_message_loop_; } @@ -121,6 +115,13 @@ class PluginService virtual void Observe(NotificationType type, const NotificationSource& source, const NotificationDetails& details); + // Get plugin info by matching full path. + bool GetPluginInfoByPath(const FilePath& plugin_path, WebPluginInfo* info); + + // Returns true if the given plugin is allowed to be used by a page with + // the given URL. + bool PluginAllowedForURL(const FilePath& plugin_path, const GURL& url); + // mapping between plugin path and PluginProcessHost typedef base::hash_map<FilePath, PluginProcessHost*> PluginMap; PluginMap plugin_hosts_; @@ -137,10 +138,15 @@ class PluginService // The browser's UI locale. const std::wstring ui_locale_; + // Map of plugin paths to the origin they are restricted to. Used for + // extension-only plugins. + typedef base::hash_map<FilePath, GURL> PrivatePluginMap; + PrivatePluginMap private_plugins_; + // Need synchronization whenever we access the plugin_list singelton through // webkit_glue since this class is called on the main and IO thread. Lock lock_; - + NotificationRegistrar registrar_; #if defined(OS_WIN) diff --git a/chrome/browser/renderer_host/resource_message_filter.cc b/chrome/browser/renderer_host/resource_message_filter.cc index a37f683..c9d6a04 100644 --- a/chrome/browser/renderer_host/resource_message_filter.cc +++ b/chrome/browser/renderer_host/resource_message_filter.cc @@ -510,11 +510,12 @@ void ResourceMessageFilter::OnGetPlugins(bool refresh, } void ResourceMessageFilter::OnGetPluginPath(const GURL& url, + const GURL& policy_url, const std::string& mime_type, const std::string& clsid, FilePath* filename, std::string* url_mime_type) { - *filename = plugin_service_->GetPluginPath(url, mime_type, clsid, + *filename = plugin_service_->GetPluginPath(url, policy_url, mime_type, clsid, url_mime_type); } diff --git a/chrome/browser/renderer_host/resource_message_filter.h b/chrome/browser/renderer_host/resource_message_filter.h index 784cc44..e5c7f96 100644 --- a/chrome/browser/renderer_host/resource_message_filter.h +++ b/chrome/browser/renderer_host/resource_message_filter.h @@ -131,6 +131,7 @@ class ResourceMessageFilter : public IPC::ChannelProxy::MessageFilter, void OnGetScreenInfo(gfx::NativeViewId window, IPC::Message* reply); void OnGetPlugins(bool refresh, std::vector<WebPluginInfo>* plugins); void OnGetPluginPath(const GURL& url, + const GURL& policy_url, const std::string& mime_type, const std::string& clsid, FilePath* filename, diff --git a/chrome/common/render_messages_internal.h b/chrome/common/render_messages_internal.h index b5a28d2..5677f16 100644 --- a/chrome/common/render_messages_internal.h +++ b/chrome/common/render_messages_internal.h @@ -802,8 +802,9 @@ IPC_BEGIN_MESSAGES(ViewHost) // Returns a path to a plugin for the given url and mime type. If there's // no plugin, an empty string is returned. - IPC_SYNC_MESSAGE_CONTROL3_2(ViewHostMsg_GetPluginPath, + IPC_SYNC_MESSAGE_CONTROL4_2(ViewHostMsg_GetPluginPath, GURL /* url */, + GURL /* policy_url */, std::string /* mime_type */, std::string /* clsid */, FilePath /* filename */, diff --git a/chrome/renderer/render_view.cc b/chrome/renderer/render_view.cc index 6ad30d6..4e0ec16 100644 --- a/chrome/renderer/render_view.cc +++ b/chrome/renderer/render_view.cc @@ -1720,9 +1720,13 @@ WebPluginDelegate* RenderView::CreatePluginDelegate( if (!PluginChannelHost::IsListening()) return NULL; + GURL policy_url; + if (webview->GetMainFrame()) + policy_url = webview->GetMainFrame()->GetURL(); + FilePath path; render_thread_->Send( - new ViewHostMsg_GetPluginPath(url, mime_type, clsid, &path, + new ViewHostMsg_GetPluginPath(url, policy_url, mime_type, clsid, &path, actual_mime_type)); if (path.value().empty()) return NULL; |