summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/content_settings/content_settings_browsertest.cc15
-rw-r--r--chrome/browser/content_settings/host_content_settings_map.cc7
-rw-r--r--chrome/browser/content_settings/host_content_settings_map.h5
-rw-r--r--chrome/browser/content_settings/tab_specific_content_settings.cc15
-rw-r--r--chrome/browser/content_settings/tab_specific_content_settings.h1
-rw-r--r--chrome/common/render_messages.h6
-rw-r--r--chrome/renderer/chrome_render_process_observer.cc7
-rw-r--r--chrome/renderer/chrome_render_process_observer.h1
-rw-r--r--chrome/renderer/content_settings_observer.cc36
-rw-r--r--chrome/renderer/content_settings_observer.h7
-rw-r--r--chrome/renderer/content_settings_observer_browsertest.cc1
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();