Index: content/renderer/render_frame_impl.cc |
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc |
index 0587fde7f7bb2663563ebe61643f315c339c0c5a..9c3d27cd842d5c8bf4f34ed516c1da89439a629a 100644 |
--- a/content/renderer/render_frame_impl.cc |
+++ b/content/renderer/render_frame_impl.cc |
@@ -61,6 +61,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" |
@@ -783,6 +784,51 @@ |
DISALLOW_COPY_AND_ASSIGN(MHTMLPartsGenerationDelegate); |
}; |
+// Returns true if a subresource certificate error (described by |url| |
+// and |security_info|) is "interesting" to the browser process. The |
+// browser process is interested in certificate errors that differ from |
+// certificate errors encountered while loading the main frame's main |
+// resource. In other words, it would be confusing to mark a page as |
+// having displayed/run insecure content when the whole page has already |
+// been marked as insecure for the same reason, so subresources with the |
+// same certificate errors as the main resource are not sent to the |
+// browser process. |
+bool IsContentWithCertificateErrorsRelevantToUI( |
+ blink::WebFrame* frame, |
+ const blink::WebURL& url, |
+ const blink::WebCString& security_info) { |
+ blink::WebFrame* main_frame = frame->top(); |
+ |
+ // If the main frame is remote, then it must be cross-site and |
+ // therefore this subresource's certificate errors are potentially |
+ // interesting to the browser (not redundant with the main frame's |
+ // main resource). |
+ if (main_frame->isWebRemoteFrame()) |
+ return true; |
+ |
+ WebDataSource* main_ds = main_frame->toWebLocalFrame()->dataSource(); |
+ content::SSLStatus ssl_status; |
+ content::SSLStatus main_resource_ssl_status; |
+ CHECK(DeserializeSecurityInfo(security_info, &ssl_status)); |
+ CHECK(DeserializeSecurityInfo(main_ds->response().securityInfo(), |
+ &main_resource_ssl_status)); |
+ |
+ // Do not send 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_ds->request().url()))) || |
+ 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); |
+} |
+ |
bool IsHttpPost(const blink::WebURLRequest& request) { |
return request.httpMethod().utf8() == "POST"; |
} |
@@ -4171,14 +4217,17 @@ |
void RenderFrameImpl::didDisplayContentWithCertificateErrors( |
const blink::WebURL& url, |
const blink::WebCString& security_info) { |
- Send(new FrameHostMsg_DidDisplayContentWithCertificateErrors( |
- routing_id_, url)); |
+ if (IsContentWithCertificateErrorsRelevantToUI(frame_, url, security_info)) { |
+ Send(new FrameHostMsg_DidDisplayContentWithCertificateErrors( |
+ routing_id_, url)); |
+ } |
} |
void RenderFrameImpl::didRunContentWithCertificateErrors( |
const blink::WebURL& url, |
const blink::WebCString& security_info) { |
- Send(new FrameHostMsg_DidRunContentWithCertificateErrors(routing_id_, url)); |
+ if (IsContentWithCertificateErrorsRelevantToUI(frame_, url, security_info)) |
+ Send(new FrameHostMsg_DidRunContentWithCertificateErrors(routing_id_, url)); |
} |
void RenderFrameImpl::didChangePerformanceTiming() { |