Reland of Downgrade lock icon for broken-HTTPS subresources (patchset #2 id:300001 of https://codereview.chromium.org/1497423002/ )
Reason for revert:
Relanding since the speculative revert didn't seem to help with crbug.com/565540
Original issue's description:
> Revert of Downgrade lock icon for broken-HTTPS subresources (patchset #11 id:200001 of https://codereview.chromium.org/1415923015/ )
>
> Reason for revert:
> Speculatively reverting to see if it makes https://code.google.com/p/chromium/issues/detail?id=565540 go away
>
> Note that this revert preserves the histogrammed
> bad_message.h value that was added in CL 1415923015
>
> Original issue's description:
> > Downgrade lock icon for broken-HTTPS subresources
> >
> > This CL attaches a boolean to resource responses to indicate if they
> > have certificate errors. If Blink sees a resource with a cert error, it
> > notifies the renderer via FrameLoaderClient, who then notifies the
> > browser, who treats the situation like mixed content.
> >
> > The browser (//content) ignores subresources with cert errors on HTTP
> > pages, and subresources with the same cert errors as the main
> > resource. This allows embedders to distinguish broken-HTTPS foo.com with
> > a subresource from broken-HTTPS bar.com and broken-HTTPS foo.com with a
> > subresource from broken-HTTPS foo.com.
> >
> > BUG=477868
> >
> > Committed: https://crrev.com/8bfb78c859ab5993eada6db30e4de50aa7403f1c
> > Cr-Commit-Position: refs/heads/master@{#362246}
>
> [email protected],[email protected],[email protected]
> NOPRESUBMIT=true
> NOTREECHECKS=true
> NOTRY=true
> BUG=477868
>
> Committed: https://crrev.com/51ea371ad45bb5887dacf7fca6fe0feef8941262
> Cr-Commit-Position: refs/heads/master@{#363388}
[email protected],[email protected],[email protected]
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
BUG=477868
Review URL: https://codereview.chromium.org/1506203004
Cr-Commit-Position: refs/heads/master@{#364152}
diff --git a/content/browser/loader/resource_loader.cc b/content/browser/loader/resource_loader.cc
index 6238b25..e8a404f 100644
--- a/content/browser/loader/resource_loader.cc
+++ b/content/browser/loader/resource_loader.cc
@@ -115,6 +115,9 @@
GetSSLStatusForRequest(request->url(), request->ssl_info(),
info->GetChildID(), &ssl_status);
response->head.security_info = SerializeSecurityInfo(ssl_status);
+ response->head.has_major_certificate_errors =
+ net::IsCertStatusError(ssl_status.cert_status) &&
+ !net::IsCertStatusMinorError(ssl_status.cert_status);
} else {
// We should not have any SSL state.
DCHECK(!request->ssl_info().cert_status);
diff --git a/content/browser/ssl/ssl_manager.cc b/content/browser/ssl/ssl_manager.cc
index cd6c2bea..c1b42f0 100644
--- a/content/browser/ssl/ssl_manager.cc
+++ b/content/browser/ssl/ssl_manager.cc
@@ -134,11 +134,7 @@
NotifyDidChangeVisibleSSLState();
}
-void SSLManager::DidDisplayInsecureContent() {
- UpdateEntry(controller_->GetLastCommittedEntry());
-}
-
-void SSLManager::DidRunInsecureContent(const std::string& security_origin) {
+void SSLManager::DidRunInsecureContent(const GURL& security_origin) {
NavigationEntryImpl* navigation_entry = controller_->GetLastCommittedEntry();
policy()->DidRunInsecureContent(navigation_entry, security_origin);
UpdateEntry(navigation_entry);
diff --git a/content/browser/ssl/ssl_manager.h b/content/browser/ssl/ssl_manager.h
index 6e46705..fb31a25 100644
--- a/content/browser/ssl/ssl_manager.h
+++ b/content/browser/ssl/ssl_manager.h
@@ -31,6 +31,7 @@
struct LoadFromMemoryCacheDetails;
struct ResourceRedirectDetails;
struct ResourceRequestDetails;
+struct SSLStatus;
// The SSLManager SSLManager controls the SSL UI elements in a WebContents. It
// listens for various events that influence when these elements should or
@@ -88,8 +89,7 @@
void DidReceiveResourceRedirect(const ResourceRedirectDetails& details);
// Insecure content entry point.
- void DidDisplayInsecureContent();
- void DidRunInsecureContent(const std::string& security_origin);
+ void DidRunInsecureContent(const GURL& security_origin);
private:
// Updates the NavigationEntry with our current state. This will
diff --git a/content/browser/ssl/ssl_policy.cc b/content/browser/ssl/ssl_policy.cc
index ed8d80b3..06677dc 100644
--- a/content/browser/ssl/ssl_policy.cc
+++ b/content/browser/ssl/ssl_policy.cc
@@ -105,7 +105,7 @@
}
void SSLPolicy::DidRunInsecureContent(NavigationEntryImpl* entry,
- const std::string& security_origin) {
+ const GURL& security_origin) {
if (!entry)
return;
@@ -113,20 +113,16 @@
if (!site_instance)
return;
- backend_->HostRanInsecureContent(GURL(security_origin).host(),
+ backend_->HostRanInsecureContent(security_origin.host(),
site_instance->GetProcess()->GetID());
}
void SSLPolicy::OnRequestStarted(SSLRequestInfo* info) {
- // TODO(abarth): This mechanism is wrong. What we should be doing is sending
- // this information back through WebKit and out some FrameLoaderClient
- // methods.
-
- if (net::IsCertStatusError(info->ssl_cert_status())) {
- backend_->HostRanInsecureContent(info->url().host(), info->child_id());
- } else if (info->ssl_cert_id() && info->url().SchemeIsCryptographic()) {
- // If the scheme is https: or wss: *and* the security info for the cert has
- // been set (i.e. the cert id is not 0), revoke any previous decisions that
+ if (info->ssl_cert_id() && info->url().SchemeIsCryptographic() &&
+ !net::IsCertStatusError(info->ssl_cert_status())) {
+ // If the scheme is https: or wss: *and* the security info for the
+ // cert has been set (i.e. the cert id is not 0) and the cert did
+ // not have any errors, revoke any previous decisions that
// have occurred. If the cert info has not been set, do nothing since it
// isn't known if the connection was actually a valid connection or if it
// had a cert error.
diff --git a/content/browser/ssl/ssl_policy.h b/content/browser/ssl/ssl_policy.h
index 2855a1b..c002bfc 100644
--- a/content/browser/ssl/ssl_policy.h
+++ b/content/browser/ssl/ssl_policy.h
@@ -36,7 +36,7 @@
void OnCertError(SSLCertErrorHandler* handler);
void DidRunInsecureContent(NavigationEntryImpl* entry,
- const std::string& security_origin);
+ const GURL& security_origin);
// We have started a resource request with the given info.
void OnRequestStarted(SSLRequestInfo* info);
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
index 327617d..1ca34e2 100644
--- a/content/browser/web_contents/web_contents_impl.cc
+++ b/content/browser/web_contents/web_contents_impl.cc
@@ -632,6 +632,10 @@
OnDidDisplayInsecureContent)
IPC_MESSAGE_HANDLER(FrameHostMsg_DidRunInsecureContent,
OnDidRunInsecureContent)
+ IPC_MESSAGE_HANDLER(FrameHostMsg_DidDisplayContentWithCertificateErrors,
+ OnDidDisplayContentWithCertificateErrors)
+ IPC_MESSAGE_HANDLER(FrameHostMsg_DidRunContentWithCertificateErrors,
+ OnDidRunContentWithCertificateErrors)
IPC_MESSAGE_HANDLER(ViewHostMsg_GoToEntryAtOffset, OnGoToEntryAtOffset)
IPC_MESSAGE_HANDLER(ViewHostMsg_UpdateZoomLimits, OnUpdateZoomLimits)
IPC_MESSAGE_HANDLER(ViewHostMsg_PageScaleFactorChanged,
@@ -3170,12 +3174,12 @@
GetController().GetBrowserContext());
}
-void WebContentsImpl::OnDidRunInsecureContent(
- const std::string& security_origin, const GURL& target_url) {
+void WebContentsImpl::OnDidRunInsecureContent(const GURL& security_origin,
+ const GURL& target_url) {
LOG(WARNING) << security_origin << " ran insecure content from "
<< target_url.possibly_invalid_spec();
RecordAction(base::UserMetricsAction("SSL.RanInsecureContent"));
- if (base::EndsWith(security_origin, kDotGoogleDotCom,
+ if (base::EndsWith(security_origin.spec(), kDotGoogleDotCom,
base::CompareCase::INSENSITIVE_ASCII))
RecordAction(base::UserMetricsAction("SSL.RanInsecureContentGoogle"));
controller_.ssl_manager()->DidRunInsecureContent(security_origin);
@@ -3183,6 +3187,39 @@
GetController().GetBrowserContext());
}
+void WebContentsImpl::OnDidDisplayContentWithCertificateErrors(
+ const GURL& url,
+ const std::string& security_info) {
+ SSLStatus ssl;
+ if (!DeserializeSecurityInfo(security_info, &ssl)) {
+ bad_message::ReceivedBadMessage(
+ GetRenderProcessHost(),
+ bad_message::WC_CONTENT_WITH_CERT_ERRORS_BAD_SECURITY_INFO);
+ return;
+ }
+
+ displayed_insecure_content_ = true;
+ SSLManager::NotifySSLInternalStateChanged(
+ GetController().GetBrowserContext());
+}
+
+void WebContentsImpl::OnDidRunContentWithCertificateErrors(
+ const GURL& security_origin,
+ const GURL& url,
+ const std::string& security_info) {
+ SSLStatus ssl;
+ if (!DeserializeSecurityInfo(security_info, &ssl)) {
+ bad_message::ReceivedBadMessage(
+ GetRenderProcessHost(),
+ bad_message::WC_CONTENT_WITH_CERT_ERRORS_BAD_SECURITY_INFO);
+ return;
+ }
+
+ controller_.ssl_manager()->DidRunInsecureContent(security_origin);
+ SSLManager::NotifySSLInternalStateChanged(
+ GetController().GetBrowserContext());
+}
+
void WebContentsImpl::OnDocumentLoadedInFrame() {
if (!HasValidFrameSource())
return;
diff --git a/content/browser/web_contents/web_contents_impl.h b/content/browser/web_contents/web_contents_impl.h
index 5ef8108..a46f717 100644
--- a/content/browser/web_contents/web_contents_impl.h
+++ b/content/browser/web_contents/web_contents_impl.h
@@ -837,8 +837,14 @@
const std::string& mime_type,
ResourceType resource_type);
void OnDidDisplayInsecureContent();
- void OnDidRunInsecureContent(const std::string& security_origin,
+ void OnDidRunInsecureContent(const GURL& security_origin,
const GURL& target_url);
+ void OnDidDisplayContentWithCertificateErrors(
+ const GURL& url,
+ const std::string& security_info);
+ void OnDidRunContentWithCertificateErrors(const GURL& security_origin,
+ const GURL& url,
+ const std::string& security_info);
void OnDocumentLoadedInFrame();
void OnDidFinishLoad(const GURL& url);
void OnGoToEntryAtOffset(int offset);
diff --git a/content/child/web_url_loader_impl.cc b/content/child/web_url_loader_impl.cc
index bea6020..dbcff212 100644
--- a/content/child/web_url_loader_impl.cc
+++ b/content/child/web_url_loader_impl.cc
@@ -887,6 +887,7 @@
response->setTextEncodingName(WebString::fromUTF8(info.charset));
response->setExpectedContentLength(info.content_length);
response->setSecurityInfo(info.security_info);
+ response->setHasMajorCertificateErrors(info.has_major_certificate_errors);
response->setAppCacheID(info.appcache_id);
response->setAppCacheManifestURL(info.appcache_manifest_url);
response->setWasCached(!info.load_timing.request_start_time.is_null() &&
diff --git a/content/common/frame_messages.h b/content/common/frame_messages.h
index 72d6751..f9604de 100644
--- a/content/common/frame_messages.h
+++ b/content/common/frame_messages.h
@@ -1225,9 +1225,22 @@
// Sent when the renderer runs insecure content in a secure origin.
IPC_MESSAGE_ROUTED2(FrameHostMsg_DidRunInsecureContent,
- std::string /* security_origin */,
+ GURL /* security_origin */,
GURL /* target URL */)
+// Sent when the renderer displays content that was loaded with
+// certificate errors.
+IPC_MESSAGE_ROUTED2(FrameHostMsg_DidDisplayContentWithCertificateErrors,
+ GURL /* resource url */,
+ std::string /* serialized security info */)
+
+// Sent when the renderer runs content that was loaded with certificate
+// errors.
+IPC_MESSAGE_ROUTED3(FrameHostMsg_DidRunContentWithCertificateErrors,
+ GURL /* security_origin */,
+ GURL /* resource url */,
+ std::string /* serialized security info */)
+
// Response to FrameMsg_GetSavableResourceLinks.
IPC_MESSAGE_ROUTED3(FrameHostMsg_SavableResourceLinksResponse,
std::vector<GURL> /* savable resource links */,
diff --git a/content/common/resource_messages.h b/content/common/resource_messages.h
index 0c970ae..65e7f00 100644
--- a/content/common/resource_messages.h
+++ b/content/common/resource_messages.h
@@ -119,6 +119,7 @@
IPC_STRUCT_TRAITS_MEMBER(mime_type)
IPC_STRUCT_TRAITS_MEMBER(charset)
IPC_STRUCT_TRAITS_MEMBER(security_info)
+ IPC_STRUCT_TRAITS_MEMBER(has_major_certificate_errors)
IPC_STRUCT_TRAITS_MEMBER(content_length)
IPC_STRUCT_TRAITS_MEMBER(encoded_data_length)
IPC_STRUCT_TRAITS_MEMBER(appcache_id)
diff --git a/content/public/common/resource_response.cc b/content/public/common/resource_response.cc
index 12f1dd7..1277355 100644
--- a/content/public/common/resource_response.cc
+++ b/content/public/common/resource_response.cc
@@ -19,6 +19,8 @@
new_response->head.mime_type = head.mime_type;
new_response->head.charset = head.charset;
new_response->head.security_info = head.security_info;
+ new_response->head.has_major_certificate_errors =
+ head.has_major_certificate_errors;
new_response->head.content_length = head.content_length;
new_response->head.encoded_data_length = head.encoded_data_length;
new_response->head.appcache_id = head.appcache_id;
diff --git a/content/public/common/resource_response_info.cc b/content/public/common/resource_response_info.cc
index 1d4e304..f05ee19 100644
--- a/content/public/common/resource_response_info.cc
+++ b/content/public/common/resource_response_info.cc
@@ -10,7 +10,8 @@
namespace content {
ResourceResponseInfo::ResourceResponseInfo()
- : content_length(-1),
+ : has_major_certificate_errors(false),
+ content_length(-1),
encoded_data_length(-1),
appcache_id(kAppCacheNoCacheId),
was_fetched_via_spdy(false),
@@ -22,8 +23,7 @@
was_fallback_required_by_service_worker(false),
response_type_via_service_worker(
blink::WebServiceWorkerResponseTypeDefault),
- is_using_lofi(false) {
-}
+ is_using_lofi(false) {}
ResourceResponseInfo::~ResourceResponseInfo() {
}
diff --git a/content/public/common/resource_response_info.h b/content/public/common/resource_response_info.h
index 1a0f126..8b81f6d 100644
--- a/content/public/common/resource_response_info.h
+++ b/content/public/common/resource_response_info.h
@@ -50,6 +50,9 @@
// response. This may include information about the SSL connection used.
std::string security_info;
+ // True if the resource was loaded in spite of certificate errors.
+ bool has_major_certificate_errors;
+
// Content length if available. -1 if not available
int64 content_length;
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc
index 271720e..9e432ba9 100644
--- a/content/renderer/render_frame_impl.cc
+++ b/content/renderer/render_frame_impl.cc
@@ -48,6 +48,7 @@
#include "content/common/savable_subframe.h"
#include "content/common/service_worker/service_worker_types.h"
#include "content/common/site_isolation_policy.h"
+#include "content/common/ssl_status_serialization.h"
#include "content/common/swapped_out_messages.h"
#include "content/common/view_messages.h"
#include "content/public/common/bindings_policy.h"
@@ -575,6 +576,38 @@
path.NormalizePathSeparatorsTo(FILE_PATH_LITERAL('/')).AsUTF8Unsafe());
}
+bool IsContentWithCertificateErrorsRelevantToUI(
+ const blink::WebURL& url,
+ const blink::WebCString& security_info,
+ const blink::WebURL& main_resource_url,
+ const blink::WebCString& main_resource_security_info) {
+ content::SSLStatus ssl_status;
+ content::SSLStatus main_resource_ssl_status;
+ CHECK(DeserializeSecurityInfo(security_info, &ssl_status));
+ CHECK(DeserializeSecurityInfo(main_resource_security_info,
+ &main_resource_ssl_status));
+
+ if (!GURL(main_resource_url).SchemeIsCryptographic())
+ return false;
+
+ // Do not handle subresource certificate errors if they are the same
+ // as errors that occured during the main page load. This compares
+ // most, but not all, fields of SSLStatus. For example, this check
+ // does not compare |content_status| because the navigation entry
+ // might have mixed content but also have the exact same SSL
+ // connection properties as the subresource, thereby making the
+ // subresource errors duplicative.
+ return (!url::Origin(GURL(url))
+ .IsSameOriginWith(url::Origin(GURL(main_resource_url))) ||
+ main_resource_ssl_status.security_style !=
+ ssl_status.security_style ||
+ main_resource_ssl_status.cert_id != ssl_status.cert_id ||
+ main_resource_ssl_status.cert_status != ssl_status.cert_status ||
+ main_resource_ssl_status.security_bits != ssl_status.security_bits ||
+ main_resource_ssl_status.connection_status !=
+ ssl_status.connection_status);
+}
+
} // namespace
// static
@@ -3680,12 +3713,38 @@
const blink::WebSecurityOrigin& origin,
const blink::WebURL& target) {
Send(new FrameHostMsg_DidRunInsecureContent(
- routing_id_, origin.toString().utf8(), target));
+ routing_id_, GURL(origin.toString().utf8()), target));
GetContentClient()->renderer()->RecordRapporURL(
"ContentSettings.MixedScript.RanMixedScript",
GURL(origin.toString().utf8()));
}
+void RenderFrameImpl::didDisplayContentWithCertificateErrors(
+ const blink::WebURL& url,
+ const blink::WebCString& security_info,
+ const blink::WebURL& main_resource_url,
+ const blink::WebCString& main_resource_security_info) {
+ if (!IsContentWithCertificateErrorsRelevantToUI(
+ url, security_info, main_resource_url, main_resource_security_info)) {
+ return;
+ }
+ Send(new FrameHostMsg_DidDisplayContentWithCertificateErrors(routing_id_, url,
+ security_info));
+}
+
+void RenderFrameImpl::didRunContentWithCertificateErrors(
+ const blink::WebURL& url,
+ const blink::WebCString& security_info,
+ const blink::WebURL& main_resource_url,
+ const blink::WebCString& main_resource_security_info) {
+ if (!IsContentWithCertificateErrorsRelevantToUI(
+ url, security_info, main_resource_url, main_resource_security_info)) {
+ return;
+ }
+ Send(new FrameHostMsg_DidRunContentWithCertificateErrors(
+ routing_id_, GURL(main_resource_url).GetOrigin(), url, security_info));
+}
+
void RenderFrameImpl::didChangePerformanceTiming() {
FOR_EACH_OBSERVER(RenderFrameObserver,
observers_,
diff --git a/content/renderer/render_frame_impl.h b/content/renderer/render_frame_impl.h
index 8d3c4f39..9da61e04 100644
--- a/content/renderer/render_frame_impl.h
+++ b/content/renderer/render_frame_impl.h
@@ -522,6 +522,16 @@
void didDisplayInsecureContent() override;
void didRunInsecureContent(const blink::WebSecurityOrigin& origin,
const blink::WebURL& target) override;
+ void didDisplayContentWithCertificateErrors(
+ const blink::WebURL& url,
+ const blink::WebCString& security_info,
+ const blink::WebURL& main_resource_url,
+ const blink::WebCString& main_resource_security_info) override;
+ void didRunContentWithCertificateErrors(
+ const blink::WebURL& url,
+ const blink::WebCString& security_info,
+ const blink::WebURL& main_resource_url,
+ const blink::WebCString& main_resource_security_info) override;
void didChangePerformanceTiming() override;
void didCreateScriptContext(blink::WebLocalFrame* frame,
v8::Local<v8::Context> context,