diff options
author | tsepez@chromium.org <tsepez@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-11-02 20:09:43 +0000 |
---|---|---|
committer | tsepez@chromium.org <tsepez@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-11-02 20:09:43 +0000 |
commit | 92d213847a203e5135aa1d746e97ff11925f77cc (patch) | |
tree | 9346952134a3f0b84ad8ea9d00c05b125a4fb9f7 /chrome | |
parent | 386818c554263d063213308310daf606191c2dab (diff) | |
download | chromium_src-92d213847a203e5135aa1d746e97ff11925f77cc.zip chromium_src-92d213847a203e5135aa1d746e97ff11925f77cc.tar.gz chromium_src-92d213847a203e5135aa1d746e97ff11925f77cc.tar.bz2 |
Hosts opting in to strict-transport-security get mixed content blocking.
BUG=100136
Review URL: http://codereview.chromium.org/8341031
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@108337 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r-- | chrome/browser/renderer_host/chrome_resource_dispatcher_host_delegate.cc | 24 | ||||
-rw-r--r-- | chrome/common/render_messages.h | 4 | ||||
-rw-r--r-- | chrome/renderer/chrome_render_view_observer.cc | 127 | ||||
-rw-r--r-- | chrome/renderer/chrome_render_view_observer.h | 6 |
4 files changed, 101 insertions, 60 deletions
diff --git a/chrome/browser/renderer_host/chrome_resource_dispatcher_host_delegate.cc b/chrome/browser/renderer_host/chrome_resource_dispatcher_host_delegate.cc index 9a6b9f7c..35231bb 100644 --- a/chrome/browser/renderer_host/chrome_resource_dispatcher_host_delegate.cc +++ b/chrome/browser/renderer_host/chrome_resource_dispatcher_host_delegate.cc @@ -34,6 +34,7 @@ #include "content/public/browser/browser_thread.h" #include "content/public/browser/notification_service.h" #include "net/base/load_flags.h" +#include "net/base/ssl_config_service.h" // TODO(oshima): Enable this for other platforms. #if defined(OS_CHROMEOS) @@ -312,15 +313,32 @@ void ChromeResourceDispatcherHostDelegate::OnResponseStarted( ResourceMessageFilter* filter) { LoadTimingObserver::PopulateTimingInfo(request, response); + ResourceDispatcherHostRequestInfo* info = + resource_dispatcher_host_->InfoForRequest(request); + + if (request->url().SchemeIsSecure()) { + const net::URLRequestContext* context = request->context(); + net::TransportSecurityState* state = context->transport_security_state(); + if (state) { + net::TransportSecurityState::DomainState domain_state; + bool has_sni = net::SSLConfigService::IsSNIAvailable( + context->ssl_config_service()); + if (state->IsEnabledForHost( + &domain_state, request->url().host(), has_sni) || + state->HasPinsForHost( + &domain_state, request->url().host(), has_sni)) { + filter->Send(new ChromeViewMsg_AddStrictSecurityHost( + info->route_id(), request->url().host())); + } + } + } + // We must send the content settings for the URL before sending response // headers to the renderer. const content::ResourceContext& resource_context = filter->resource_context(); ProfileIOData* io_data = reinterpret_cast<ProfileIOData*>(resource_context.GetUserData(NULL)); HostContentSettingsMap* map = io_data->GetHostContentSettingsMap(); - - ResourceDispatcherHostRequestInfo* info = - resource_dispatcher_host_->InfoForRequest(request); filter->Send(new ChromeViewMsg_SetContentSettingsForLoadingURL( info->route_id(), request->url(), map->GetContentSettings(request->url()))); diff --git a/chrome/common/render_messages.h b/chrome/common/render_messages.h index 847ed36..905e531 100644 --- a/chrome/common/render_messages.h +++ b/chrome/common/render_messages.h @@ -338,6 +338,10 @@ IPC_MESSAGE_ROUTED1(ChromeViewMsg_SetAllowDisplayingInsecureContent, IPC_MESSAGE_ROUTED1(ChromeViewMsg_SetAllowRunningInsecureContent, bool /* allowed */) +// Tells renderer to always enforce mixed content blocking for this host. +IPC_MESSAGE_ROUTED1(ChromeViewMsg_AddStrictSecurityHost, + std::string /* host */) + // Sent when the profile changes the kSafeBrowsingEnabled preference. IPC_MESSAGE_ROUTED1(ChromeViewMsg_SetClientSidePhishingDetection, bool /* enable_phishing_detection */) diff --git a/chrome/renderer/chrome_render_view_observer.cc b/chrome/renderer/chrome_render_view_observer.cc index 36fe553..c031cec 100644 --- a/chrome/renderer/chrome_render_view_observer.cc +++ b/chrome/renderer/chrome_render_view_observer.cc @@ -261,6 +261,8 @@ bool ChromeRenderViewObserver::OnMessageReceived(const IPC::Message& message) { IPC_MESSAGE_HANDLER(ChromeViewMsg_StartFrameSniffer, OnStartFrameSniffer) #endif IPC_MESSAGE_HANDLER(ChromeViewMsg_GetFPS, OnGetFPS) + IPC_MESSAGE_HANDLER(ChromeViewMsg_AddStrictSecurityHost, + OnAddStrictSecurityHost) IPC_MESSAGE_UNHANDLED(handled = false) IPC_END_MESSAGE_MAP() @@ -353,6 +355,11 @@ void ChromeRenderViewObserver::OnSetAllowRunningInsecureContent(bool allow) { OnSetAllowDisplayingInsecureContent(allow); } +void ChromeRenderViewObserver::OnAddStrictSecurityHost( + const std::string& host) { + strict_security_hosts_.insert(host); +} + void ChromeRenderViewObserver::Navigate(const GURL& url) { // Execute cache clear operations that were postponed until a navigation // event (including tab reload). @@ -451,48 +458,48 @@ bool ChromeRenderViewObserver::allowDisplayingInsecureContent( WebKit::WebFrame* frame, bool allowed_per_settings, const WebKit::WebSecurityOrigin& origin, - const WebKit::WebURL& url) { + const WebKit::WebURL& resource_url) { SendInsecureContentSignal(INSECURE_CONTENT_DISPLAY); - std::string host(origin.host().utf8()); - GURL frame_url(frame->document().url()); - if (isHostInDomain(host, kGoogleDotCom)) { + std::string origin_host(origin.host().utf8()); + GURL frame_gurl(frame->document().url()); + if (isHostInDomain(origin_host, kGoogleDotCom)) { SendInsecureContentSignal(INSECURE_CONTENT_DISPLAY_HOST_GOOGLE); - if (StartsWithASCII(frame_url.path(), kGoogleSupportPathPrefix, false)) { + if (StartsWithASCII(frame_gurl.path(), kGoogleSupportPathPrefix, false)) { SendInsecureContentSignal(INSECURE_CONTENT_DISPLAY_HOST_GOOGLE_SUPPORT); - } else if (StartsWithASCII(frame_url.path(), + } else if (StartsWithASCII(frame_gurl.path(), kGoogleIntlPathPrefix, false)) { SendInsecureContentSignal(INSECURE_CONTENT_DISPLAY_HOST_GOOGLE_INTL); } } - if (host == kWWWDotGoogleDotCom) { + if (origin_host == kWWWDotGoogleDotCom) { SendInsecureContentSignal(INSECURE_CONTENT_DISPLAY_HOST_WWW_GOOGLE); - if (StartsWithASCII(frame_url.path(), kGoogleReaderPathPrefix, false)) + if (StartsWithASCII(frame_gurl.path(), kGoogleReaderPathPrefix, false)) SendInsecureContentSignal(INSECURE_CONTENT_DISPLAY_HOST_GOOGLE_READER); - } else if (host == kMailDotGoogleDotCom) { + } else if (origin_host == kMailDotGoogleDotCom) { SendInsecureContentSignal(INSECURE_CONTENT_DISPLAY_HOST_MAIL_GOOGLE); - } else if (host == kPlusDotGoogleDotCom) { + } else if (origin_host == kPlusDotGoogleDotCom) { SendInsecureContentSignal(INSECURE_CONTENT_DISPLAY_HOST_PLUS_GOOGLE); - } else if (host == kDocsDotGoogleDotCom) { + } else if (origin_host == kDocsDotGoogleDotCom) { SendInsecureContentSignal(INSECURE_CONTENT_DISPLAY_HOST_DOCS_GOOGLE); - } else if (host == kSitesDotGoogleDotCom) { + } else if (origin_host == kSitesDotGoogleDotCom) { SendInsecureContentSignal(INSECURE_CONTENT_DISPLAY_HOST_SITES_GOOGLE); - } else if (host == kPicasawebDotGoogleDotCom) { + } else if (origin_host == kPicasawebDotGoogleDotCom) { SendInsecureContentSignal(INSECURE_CONTENT_DISPLAY_HOST_PICASAWEB_GOOGLE); - } else if (host == kCodeDotGoogleDotCom) { + } else if (origin_host == kCodeDotGoogleDotCom) { SendInsecureContentSignal(INSECURE_CONTENT_DISPLAY_HOST_CODE_GOOGLE); - } else if (host == kGroupsDotGoogleDotCom) { + } else if (origin_host == kGroupsDotGoogleDotCom) { SendInsecureContentSignal(INSECURE_CONTENT_DISPLAY_HOST_GROUPS_GOOGLE); - } else if (host == kMapsDotGoogleDotCom) { + } else if (origin_host == kMapsDotGoogleDotCom) { SendInsecureContentSignal(INSECURE_CONTENT_DISPLAY_HOST_MAPS_GOOGLE); - } else if (host == kWWWDotYoutubeDotCom) { + } else if (origin_host == kWWWDotYoutubeDotCom) { SendInsecureContentSignal(INSECURE_CONTENT_DISPLAY_HOST_YOUTUBE); } - GURL gurl(url); - if (EndsWith(gurl.path(), kDotHTML, false)) + GURL resource_gurl(resource_url); + if (EndsWith(resource_gurl.path(), kDotHTML, false)) SendInsecureContentSignal(INSECURE_CONTENT_DISPLAY_HTML); if (allowed_per_settings || allow_displaying_insecure_content_) @@ -506,76 +513,78 @@ bool ChromeRenderViewObserver::allowRunningInsecureContent( WebKit::WebFrame* frame, bool allowed_per_settings, const WebKit::WebSecurityOrigin& origin, - const WebKit::WebURL& url) { - // Single value to control permissive mixed content behaviour. - const bool enforce_insecure_content_on_all_domains = true; + const WebKit::WebURL& resource_url) { + // Single value to control permissive mixed content behaviour. We flip + // this at the present between beta / stable releases. + const bool block_insecure_content_on_all_domains = false; + + std::string origin_host(origin.host().utf8()); + GURL frame_gurl(frame->document().url()); + DCHECK_EQ(frame_gurl.host(), origin_host); - std::string host(origin.host().utf8()); - GURL frame_url(frame->document().url()); - bool is_google = isHostInDomain(host, kGoogleDotCom); + bool is_google = isHostInDomain(origin_host, kGoogleDotCom); if (is_google) { SendInsecureContentSignal(INSECURE_CONTENT_RUN_HOST_GOOGLE); - if (StartsWithASCII(frame_url.path(), kGoogleSupportPathPrefix, false)) { + if (StartsWithASCII(frame_gurl.path(), kGoogleSupportPathPrefix, false)) { SendInsecureContentSignal(INSECURE_CONTENT_RUN_HOST_GOOGLE_SUPPORT); - } else if (StartsWithASCII(frame_url.path(), + } else if (StartsWithASCII(frame_gurl.path(), kGoogleIntlPathPrefix, false)) { SendInsecureContentSignal(INSECURE_CONTENT_RUN_HOST_GOOGLE_INTL); } } - if (host == kWWWDotGoogleDotCom) { + if (origin_host == kWWWDotGoogleDotCom) { SendInsecureContentSignal(INSECURE_CONTENT_RUN_HOST_WWW_GOOGLE); - if (StartsWithASCII(frame_url.path(), kGoogleReaderPathPrefix, false)) + if (StartsWithASCII(frame_gurl.path(), kGoogleReaderPathPrefix, false)) SendInsecureContentSignal(INSECURE_CONTENT_RUN_HOST_GOOGLE_READER); - } else if (host == kMailDotGoogleDotCom) { + } else if (origin_host == kMailDotGoogleDotCom) { SendInsecureContentSignal(INSECURE_CONTENT_RUN_HOST_MAIL_GOOGLE); - } else if (host == kPlusDotGoogleDotCom) { + } else if (origin_host == kPlusDotGoogleDotCom) { SendInsecureContentSignal(INSECURE_CONTENT_RUN_HOST_PLUS_GOOGLE); - } else if (host == kDocsDotGoogleDotCom) { + } else if (origin_host == kDocsDotGoogleDotCom) { SendInsecureContentSignal(INSECURE_CONTENT_RUN_HOST_DOCS_GOOGLE); - } else if (host == kSitesDotGoogleDotCom) { + } else if (origin_host == kSitesDotGoogleDotCom) { SendInsecureContentSignal(INSECURE_CONTENT_RUN_HOST_SITES_GOOGLE); - } else if (host == kPicasawebDotGoogleDotCom) { + } else if (origin_host == kPicasawebDotGoogleDotCom) { SendInsecureContentSignal(INSECURE_CONTENT_RUN_HOST_PICASAWEB_GOOGLE); - } else if (host == kCodeDotGoogleDotCom) { + } else if (origin_host == kCodeDotGoogleDotCom) { SendInsecureContentSignal(INSECURE_CONTENT_RUN_HOST_CODE_GOOGLE); - } else if (host == kGroupsDotGoogleDotCom) { + } else if (origin_host == kGroupsDotGoogleDotCom) { SendInsecureContentSignal(INSECURE_CONTENT_RUN_HOST_GROUPS_GOOGLE); - } else if (host == kMapsDotGoogleDotCom) { + } else if (origin_host == kMapsDotGoogleDotCom) { SendInsecureContentSignal(INSECURE_CONTENT_RUN_HOST_MAPS_GOOGLE); - } else if (host == kWWWDotYoutubeDotCom) { + } else if (origin_host == kWWWDotYoutubeDotCom) { SendInsecureContentSignal(INSECURE_CONTENT_RUN_HOST_YOUTUBE); - } else if (EndsWith(host, kDotGoogleUserContentDotCom, false)) { + } else if (EndsWith(origin_host, kDotGoogleUserContentDotCom, false)) { SendInsecureContentSignal(INSECURE_CONTENT_RUN_HOST_GOOGLEUSERCONTENT); } - GURL gurl(url); - if (gurl.host() == kWWWDotYoutubeDotCom) + GURL resource_gurl(resource_url); + if (resource_gurl.host() == kWWWDotYoutubeDotCom) SendInsecureContentSignal(INSECURE_CONTENT_RUN_TARGET_YOUTUBE); - if (EndsWith(gurl.path(), kDotJS, false)) + if (EndsWith(resource_gurl.path(), kDotJS, false)) SendInsecureContentSignal(INSECURE_CONTENT_RUN_JS); - else if (EndsWith(gurl.path(), kDotCSS, false)) + else if (EndsWith(resource_gurl.path(), kDotCSS, false)) SendInsecureContentSignal(INSECURE_CONTENT_RUN_CSS); - else if (EndsWith(gurl.path(), kDotSWF, false)) + else if (EndsWith(resource_gurl.path(), kDotSWF, false)) SendInsecureContentSignal(INSECURE_CONTENT_RUN_SWF); - if (allow_running_insecure_content_ || allowed_per_settings) - return true; - - if (!(enforce_insecure_content_on_all_domains || - CommandLine::ForCurrentProcess()->HasSwitch( - switches::kNoRunningInsecureContent))) { - bool mandatory_enforcement = (is_google || - isHostInDomain(host, kFacebookDotCom) || - isHostInDomain(host, kTwitterDotCom)); - if (!mandatory_enforcement) - return true; + if (!allow_running_insecure_content_ && + !allowed_per_settings && + (block_insecure_content_on_all_domains || + CommandLine::ForCurrentProcess()->HasSwitch( + switches::kNoRunningInsecureContent) || + is_google || + isHostInDomain(origin_host, kFacebookDotCom) || + isHostInDomain(origin_host, kTwitterDotCom) || + IsStrictSecurityHost(origin_host))) { + Send(new ChromeViewHostMsg_DidBlockRunningInsecureContent(routing_id())); + return false; } - Send(new ChromeViewHostMsg_DidBlockRunningInsecureContent(routing_id())); - return false; + return true; } void ChromeRenderViewObserver::didNotAllowPlugins(WebFrame* frame) { @@ -1025,3 +1034,7 @@ SkBitmap ChromeRenderViewObserver::ImageFromDataUrl(const GURL& url) const { } return SkBitmap(); } + +bool ChromeRenderViewObserver::IsStrictSecurityHost(const std::string& host) { + return (strict_security_hosts_.find(host) != strict_security_hosts_.end()); +} diff --git a/chrome/renderer/chrome_render_view_observer.h b/chrome/renderer/chrome_render_view_observer.h index a8d08f9..f0d8e82 100644 --- a/chrome/renderer/chrome_render_view_observer.h +++ b/chrome/renderer/chrome_render_view_observer.h @@ -6,6 +6,7 @@ #define CHROME_RENDERER_CHROME_RENDER_VIEW_OBSERVER_H_ #pragma once +#include <set> #include <string> #include <vector> @@ -127,6 +128,7 @@ class ChromeRenderViewObserver : public content::RenderViewObserver, void OnSetClientSidePhishingDetection(bool enable_phishing_detection); void OnStartFrameSniffer(const string16& frame_name); void OnGetFPS(); + void OnAddStrictSecurityHost(const std::string& host); // Captures the thumbnail and text contents for indexing for the given load // ID. If the view's load ID is different than the parameter, this call is @@ -174,6 +176,9 @@ class ChromeRenderViewObserver : public content::RenderViewObserver, // Decodes a data: URL image or returns an empty image in case of failure. SkBitmap ImageFromDataUrl(const GURL&) const; + // Determines if a host is in the strict security host set. + bool IsStrictSecurityHost(const std::string& host); + // Save the JavaScript to preload if a ViewMsg_WebUIJavaScript is received. scoped_ptr<WebUIJavaScript> webui_javascript_; @@ -197,6 +202,7 @@ class ChromeRenderViewObserver : public content::RenderViewObserver, // Insecure content may be permitted for the duration of this render view. bool allow_displaying_insecure_content_; bool allow_running_insecure_content_; + std::set<std::string> strict_security_hosts_; // Allows JS to access DOM automation. The JS object is only exposed when the // DOM automation bindings are enabled. |