diff options
11 files changed, 91 insertions, 10 deletions
diff --git a/chrome/browser/content_settings/content_settings_browsertest.cc b/chrome/browser/content_settings/content_settings_browsertest.cc index b1e5556..383dc7e 100644 --- a/chrome/browser/content_settings/content_settings_browsertest.cc +++ b/chrome/browser/content_settings/content_settings_browsertest.cc @@ -30,3 +30,18 @@ IN_PROC_BROWSER_TEST_F(InProcessBrowserTest, RedirectLoopCookies) { EXPECT_TRUE(tab_contents->content_settings()->IsContentBlocked( CONTENT_SETTINGS_TYPE_COOKIES)); } + +IN_PROC_BROWSER_TEST_F(InProcessBrowserTest, ContentSettingsBlockDataURLs) { + GURL url("data:text/html,<title>Data URL</title><script>alert(1)</script>"); + + browser()->profile()->GetHostContentSettingsMap()->SetDefaultContentSetting( + CONTENT_SETTINGS_TYPE_JAVASCRIPT, CONTENT_SETTING_BLOCK); + + ui_test_utils::NavigateToURL(browser(), url); + + TabContentsWrapper* tab_contents = browser()->GetSelectedTabContentsWrapper(); + ASSERT_EQ(UTF8ToUTF16("Data URL"), tab_contents->tab_contents()->GetTitle()); + + EXPECT_TRUE(tab_contents->content_settings()->IsContentBlocked( + CONTENT_SETTINGS_TYPE_JAVASCRIPT)); +} diff --git a/chrome/browser/content_settings/host_content_settings_map.cc b/chrome/browser/content_settings/host_content_settings_map.cc index 66853dd..419921c 100644 --- a/chrome/browser/content_settings/host_content_settings_map.cc +++ b/chrome/browser/content_settings/host_content_settings_map.cc @@ -158,6 +158,13 @@ ContentSetting HostContentSettingsMap::GetDefaultContentSetting( return setting; } +ContentSettings HostContentSettingsMap::GetDefaultContentSettings() const { + ContentSettings output(CONTENT_SETTING_DEFAULT); + for (int i = 0; i < CONTENT_SETTINGS_NUM_TYPES; ++i) + output.settings[i] = GetDefaultContentSetting(ContentSettingsType(i)); + return output; +} + ContentSetting HostContentSettingsMap::GetCookieContentSetting( const GURL& url, const GURL& first_party_url, diff --git a/chrome/browser/content_settings/host_content_settings_map.h b/chrome/browser/content_settings/host_content_settings_map.h index 64556f7..dcb48cf 100644 --- a/chrome/browser/content_settings/host_content_settings_map.h +++ b/chrome/browser/content_settings/host_content_settings_map.h @@ -54,6 +54,11 @@ class HostContentSettingsMap ContentSetting GetDefaultContentSetting( ContentSettingsType content_type) const; + // Returns the default settings for all content types. + // + // This may be called on any thread. + ContentSettings GetDefaultContentSettings() const; + // Returns a single ContentSetting which applies to the given URLs. Note that // certain internal schemes are whitelisted. For ContentSettingsTypes that // require an resource identifier to be specified, the |resource_identifier| diff --git a/chrome/browser/content_settings/tab_specific_content_settings.cc b/chrome/browser/content_settings/tab_specific_content_settings.cc index 0a8716a..59303e2 100644 --- a/chrome/browser/content_settings/tab_specific_content_settings.cc +++ b/chrome/browser/content_settings/tab_specific_content_settings.cc @@ -430,6 +430,14 @@ void TabSpecificContentSettings::DidNavigateMainFramePostCommit( } } +void TabSpecificContentSettings::RenderViewCreated( + RenderViewHost* render_view_host) { + HostContentSettingsMap* map = + tab_contents()->profile()->GetHostContentSettingsMap(); + render_view_host->Send(new ViewMsg_SetDefaultContentSettings( + map->GetDefaultContentSettings())); +} + void TabSpecificContentSettings::DidStartProvisionalLoadForFrame( int64 frame_id, bool is_main_frame, @@ -468,9 +476,12 @@ void TabSpecificContentSettings::Observe(NotificationType type, // The active NavigationEntry is the URL in the URL field of a tab. // Currently this should be matched by the |primary_pattern|. settings_details.ptr()->primary_pattern().Matches(entry_url)) { + HostContentSettingsMap* map = + tab_contents()->profile()->GetHostContentSettingsMap(); + Send(new ViewMsg_SetDefaultContentSettings( + map->GetDefaultContentSettings())); Send(new ViewMsg_SetContentSettingsForCurrentURL( - entry_url, tab_contents()->profile()->GetHostContentSettingsMap()-> - GetContentSettings(entry_url, entry_url))); + entry_url, map->GetContentSettings(entry_url, entry_url))); } } diff --git a/chrome/browser/content_settings/tab_specific_content_settings.h b/chrome/browser/content_settings/tab_specific_content_settings.h index d262b92..b862dc5 100644 --- a/chrome/browser/content_settings/tab_specific_content_settings.h +++ b/chrome/browser/content_settings/tab_specific_content_settings.h @@ -159,6 +159,7 @@ class TabSpecificContentSettings : public TabContentsObserver, virtual void DidNavigateMainFramePostCommit( const content::LoadCommittedDetails& details, const ViewHostMsg_FrameNavigate_Params& params) OVERRIDE; + virtual void RenderViewCreated(RenderViewHost* render_view_host) OVERRIDE; virtual void DidStartProvisionalLoadForFrame( int64 frame_id, bool is_main_frame, diff --git a/chrome/common/render_messages.h b/chrome/common/render_messages.h index 65f07433..d33c9fb 100644 --- a/chrome/common/render_messages.h +++ b/chrome/common/render_messages.h @@ -176,6 +176,12 @@ IPC_MESSAGE_CONTROL2(ViewMsg_SetContentSettingsForCurrentURL, GURL /* url */, ContentSettings /* content_settings */) +// Set the content settings for a particular url that the renderer is in the +// process of loading. This will be stored, to be used if the load commits +// and ignored otherwise. +IPC_MESSAGE_CONTROL1(ViewMsg_SetDefaultContentSettings, + ContentSettings /* content_settings */) + // Tells the render view to load all blocked plugins. IPC_MESSAGE_ROUTED0(ViewMsg_LoadBlockedPlugins) diff --git a/chrome/renderer/chrome_render_process_observer.cc b/chrome/renderer/chrome_render_process_observer.cc index 1721723..d50c638 100644 --- a/chrome/renderer/chrome_render_process_observer.cc +++ b/chrome/renderer/chrome_render_process_observer.cc @@ -409,6 +409,8 @@ bool ChromeRenderProcessObserver::OnControlMessageReceived( bool handled = true; IPC_BEGIN_MESSAGE_MAP(ChromeRenderProcessObserver, message) IPC_MESSAGE_HANDLER(ViewMsg_SetIsIncognitoProcess, OnSetIsIncognitoProcess) + IPC_MESSAGE_HANDLER(ViewMsg_SetDefaultContentSettings, + OnSetDefaultContentSettings) IPC_MESSAGE_HANDLER(ViewMsg_SetContentSettingsForCurrentURL, OnSetContentSettingsForCurrentURL) IPC_MESSAGE_HANDLER(ViewMsg_SetCacheCapacities, OnSetCacheCapacities) @@ -446,6 +448,11 @@ void ChromeRenderProcessObserver::OnSetContentSettingsForCurrentURL( RenderView::ForEach(&setter); } +void ChromeRenderProcessObserver::OnSetDefaultContentSettings( + const ContentSettings& content_settings) { + ContentSettingsObserver::SetDefaultContentSettings(content_settings); +} + void ChromeRenderProcessObserver::OnSetCacheCapacities(size_t min_dead_capacity, size_t max_dead_capacity, size_t capacity) { diff --git a/chrome/renderer/chrome_render_process_observer.h b/chrome/renderer/chrome_render_process_observer.h index f447c82..beb2b26 100644 --- a/chrome/renderer/chrome_render_process_observer.h +++ b/chrome/renderer/chrome_render_process_observer.h @@ -35,6 +35,7 @@ class ChromeRenderProcessObserver : public RenderProcessObserver { void OnSetIsIncognitoProcess(bool is_incognito_process); void OnSetContentSettingsForCurrentURL( const GURL& url, const ContentSettings& content_settings); + void OnSetDefaultContentSettings(const ContentSettings& content_settings); void OnSetCacheCapacities(size_t min_dead_capacity, size_t max_dead_capacity, size_t capacity); diff --git a/chrome/renderer/content_settings_observer.cc b/chrome/renderer/content_settings_observer.cc index ef8ebfe..1f9de9e 100644 --- a/chrome/renderer/content_settings_observer.cc +++ b/chrome/renderer/content_settings_observer.cc @@ -13,7 +13,6 @@ #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrameClient.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebSecurityOrigin.h" -#include "third_party/WebKit/Source/WebKit/chromium/public/WebURLRequest.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h" using WebKit::WebDataSource; @@ -21,7 +20,6 @@ using WebKit::WebFrame; using WebKit::WebFrameClient; using WebKit::WebSecurityOrigin; using WebKit::WebString; -using WebKit::WebURLRequest; using WebKit::WebView; namespace { @@ -38,7 +36,7 @@ static bool IsWhitelistedForContentSettings(WebFrame* frame) { // If the scheme is ftp: or file:, an empty file name indicates a directory // listing, which requires JavaScript to function properly. GURL frame_url = frame->url(); - const char* kDirProtocols[] = { "ftp", "file" }; + const char* kDirProtocols[] = { chrome::kFtpScheme, chrome::kFileScheme }; for (size_t i = 0; i < arraysize(kDirProtocols); ++i) { if (EqualsASCII(origin.protocol(), kDirProtocols[i])) { return frame_url.SchemeIs(kDirProtocols[i]) && @@ -51,6 +49,8 @@ static bool IsWhitelistedForContentSettings(WebFrame* frame) { } // namespace +ContentSettings ContentSettingsObserver::default_settings_; + ContentSettingsObserver::ContentSettingsObserver(RenderView* render_view) : RenderViewObserver(render_view), RenderViewObserverTracker<ContentSettingsObserver>(render_view), @@ -61,12 +61,16 @@ ContentSettingsObserver::ContentSettingsObserver(RenderView* render_view) ContentSettingsObserver::~ContentSettingsObserver() { } - void ContentSettingsObserver::SetContentSettings( const ContentSettings& settings) { current_content_settings_ = settings; } +void ContentSettingsObserver::SetDefaultContentSettings( + const ContentSettings& settings) { + default_settings_ = settings; +} + ContentSetting ContentSettingsObserver::GetContentSetting( ContentSettingsType type) { if (type == CONTENT_SETTINGS_TYPE_PLUGINS && @@ -109,19 +113,35 @@ void ContentSettingsObserver::DidCommitProvisionalLoad( if (frame->parent()) return; // Not a top-level navigation. - WebDataSource* ds = frame->dataSource(); - const WebURLRequest& request = ds->request(); - // Clear "block" flags for the new page. This needs to happen before any of // allowScripts(), allowImages(), allowPlugins() is called for the new page // so that these functions can correctly detect that a piece of content // flipped from "not blocked" to "blocked". ClearBlockedContentSettings(); + GURL url = frame->url(); + + if (frame->securityOrigin().toString() == "null" && + !url.SchemeIs(chrome::kFileScheme)) { + // The Frame has a unique security origin. Instead of granting the frame + // privileges based on it's URL, we fall back to the default content + // settings. + + // We exempt file URLs here because we sandbox them by default, but folks + // might reasonably want to supply non-default content settings for various + // file URLs. + SetContentSettings(default_settings_); + return; + } + + // If we start failing this DCHECK, please makes sure we don't regress + // this bug: http://code.google.com/p/chromium/issues/detail?id=79304 + DCHECK(!url.SchemeIs(chrome::kDataScheme)); + // Set content settings. Default them from the parent window if one exists. // This makes sure about:blank windows work as expected. HostContentSettings::iterator host_content_settings = - host_content_settings_.find(GURL(request.url())); + host_content_settings_.find(url); if (host_content_settings != host_content_settings_.end()) { SetContentSettings(host_content_settings->second); diff --git a/chrome/renderer/content_settings_observer.h b/chrome/renderer/content_settings_observer.h index 4929edb..d28deb8 100644 --- a/chrome/renderer/content_settings_observer.h +++ b/chrome/renderer/content_settings_observer.h @@ -30,6 +30,10 @@ class ContentSettingsObserver // allowPlugins(). void SetContentSettings(const ContentSettings& settings); + // Sets the default content settings that back allowScripts(), + // allowImages(), and allowPlugins(). + static void SetDefaultContentSettings(const ContentSettings& settings); + // Returns the setting for the given type. ContentSetting GetContentSetting(ContentSettingsType type); @@ -78,6 +82,9 @@ class ContentSettingsObserver typedef std::map<GURL, ContentSettings> HostContentSettings; HostContentSettings host_content_settings_; + // Stores our most up-to-date view of the default content settings. + static ContentSettings default_settings_; + // Stores if loading of images, scripts, and plugins is allowed. ContentSettings current_content_settings_; diff --git a/chrome/renderer/content_settings_observer_browsertest.cc b/chrome/renderer/content_settings_observer_browsertest.cc index 391bc30..e1b484d 100644 --- a/chrome/renderer/content_settings_observer_browsertest.cc +++ b/chrome/renderer/content_settings_observer_browsertest.cc @@ -107,6 +107,7 @@ TEST_F(RenderViewTest, JSBlockSentAfterPageLoad) { settings.settings[CONTENT_SETTINGS_TYPE_JAVASCRIPT] = CONTENT_SETTING_BLOCK; ContentSettingsObserver* observer = ContentSettingsObserver::Get(view_); observer->SetContentSettings(settings); + ContentSettingsObserver::SetDefaultContentSettings(settings); // Make sure no pending messages are in the queue. ProcessPendingMessages(); |