summaryrefslogtreecommitdiffstats
path: root/webkit/glue/site_isolation_metrics.cc
diff options
context:
space:
mode:
authorcreis@chromium.org <creis@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-05-23 17:37:54 +0000
committercreis@chromium.org <creis@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-05-23 17:37:54 +0000
commitf4b8f31dde49067a092303025d4baaf47e93f491 (patch)
treeb2e88b62dfad97470c2c97e5fd32c6b68b7186d8 /webkit/glue/site_isolation_metrics.cc
parent865f37920b4b2b600832017c9f3c1741a38b416a (diff)
downloadchromium_src-f4b8f31dde49067a092303025d4baaf47e93f491.zip
chromium_src-f4b8f31dde49067a092303025d4baaf47e93f491.tar.gz
chromium_src-f4b8f31dde49067a092303025d4baaf47e93f491.tar.bz2
Update the Site Isolation UMA metrics.
Fixes a bug with tracking CORS headers and starts tracking all requests and all cross-site requests, for calculating the fraction we would block. Also explicitly counts the requests we would block in new UMA histograms. Currently has a problem with "304 Not Modified" responses, since no MIME type is provided... BUG=none TEST=none Review URL: http://codereview.chromium.org/2132002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@48003 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit/glue/site_isolation_metrics.cc')
-rw-r--r--webkit/glue/site_isolation_metrics.cc123
1 files changed, 89 insertions, 34 deletions
diff --git a/webkit/glue/site_isolation_metrics.cc b/webkit/glue/site_isolation_metrics.cc
index a97bb96..912263f 100644
--- a/webkit/glue/site_isolation_metrics.cc
+++ b/webkit/glue/site_isolation_metrics.cc
@@ -51,7 +51,8 @@ static const char* const kCrossOriginMimeTypesToLog[] = {
"application/atom+xml",
"application/json",
"application/x-x509-user-cert",
- "multipart/x-mixed-replace"
+ "multipart/x-mixed-replace",
+ "(NONE)" // Keep track of missing MIME types as well
};
static MimeTypeMap* GetMimeTypeMap() {
@@ -72,7 +73,7 @@ static CrossOriginTextHtmlResponseSet* GetCrossOriginTextHtmlResponseSet() {
static void LogVerifiedTextHtmlResponse() {
UMA_HISTOGRAM_COUNTS(
- "SiteIsolation.CrossSiteNonFrameResponse_verified_texthtml", 1);
+ "SiteIsolation.CrossSiteNonFrameResponse_verified_texthtml_BLOCK", 1);
}
static void LogMislabeledTextHtmlResponse() {
@@ -86,50 +87,102 @@ void SiteIsolationMetrics::AddRequest(unsigned identifier,
target_type_map[identifier] = target_type;
}
+// Check whether the given response is allowed due to access control headers.
+// This is basically a copy of the logic of passesAccessControlCheck() in
+// WebCore/loader/CrossOriginAccessControl.cpp.
+bool SiteIsolationMetrics::AllowedByAccessControlHeader(
+ WebFrame* frame, const WebURLResponse& response) {
+ WebString access_control_origin = response.httpHeaderField(
+ WebString::fromUTF8("Access-Control-Allow-Origin"));
+ WebSecurityOrigin security_origin =
+ WebSecurityOrigin::createFromString(access_control_origin);
+ return access_control_origin == WebString::fromUTF8("*") ||
+ frame->securityOrigin().canAccess(security_origin);
+}
+
+// We want to log any cross-site request that we don't think a renderer should
+// be allowed to make. We can safely ignore frame requests (since we'd like
+// those to be in a separate renderer) and plugin requests, even if they are
+// cross-origin.
+//
+// For comparison, we keep counts of:
+// - All requests made by a renderer
+// - All cross-site requests
+//
+// Then, for cross-site non-frame/plugin requests, we keep track of:
+// - Counts for MIME types of interest
+// - Counts of those MIME types that carry CORS headers
+// - Counts of mislabeled text/html responses (without CORS)
+// As well as those we would block:
+// - Counts of verified text/html responses (without CORS)
+// - Counts of XML/JSON responses (without CORS)
+//
+// This will let us say what percentage of requests we would end up blocking.
void SiteIsolationMetrics::LogMimeTypeForCrossOriginRequest(
WebFrame* frame, unsigned identifier, const WebURLResponse& response) {
+ UMA_HISTOGRAM_COUNTS("SiteIsolation.Requests", 1);
+
TargetTypeMap& target_type_map = *GetTargetTypeMap();
TargetTypeMap::iterator iter = target_type_map.find(identifier);
if (iter != target_type_map.end()) {
WebURLRequest::TargetType target_type = iter->second;
target_type_map.erase(iter);
- // We want to log any cross-site request that we don't think a renderer
- // should be allowed to make. We can safely ignore frame requests (since
- // we'd like those to be in a separate renderer) and plugin requests, even
- // if they are cross-origin.
- if (target_type != WebURLRequest::TargetIsMainFrame &&
- target_type != WebURLRequest::TargetIsSubFrame &&
- target_type != WebURLRequest::TargetIsObject &&
- !frame->securityOrigin().canAccess(
+
+ // Focus on cross-site requests.
+ if (!frame->securityOrigin().canAccess(
WebSecurityOrigin::create(response.url()))) {
- std::string mime_type = response.mimeType().utf8();
- MimeTypeMap mime_type_map = *GetMimeTypeMap();
- MimeTypeMap::iterator mime_type_iter = mime_type_map.find(mime_type);
- if (mime_type_iter != mime_type_map.end()) {
- UMA_HISTOGRAM_ENUMERATION(
- "SiteIsolation.CrossSiteNonFrameResponse_MIME_Type",
- mime_type_iter->second,
- arraysize(kCrossOriginMimeTypesToLog));
-
- // We also should check access control headers, in case this
- // cross-origin request has been explicitly permitted.
- // This is basically a copy of the logic of passesAccessControlCheck()
- // in WebCore/loader/CrossOriginAccessControl.cpp.
- WebString access_control_origin = response.httpHeaderField(
- WebString::fromUTF8("Access-Control-Allow-Origin"));
- if (access_control_origin != WebString::fromUTF8("*")
- && !frame->securityOrigin().canAccess(
- WebSecurityOrigin::createFromString(access_control_origin))) {
+ UMA_HISTOGRAM_COUNTS("SiteIsolation.CrossSiteRequests", 1);
+
+ // Now focus on non-frame, non-plugin requests.
+ if (target_type != WebURLRequest::TargetIsMainFrame &&
+ target_type != WebURLRequest::TargetIsSubFrame &&
+ target_type != WebURLRequest::TargetIsObject) {
+ // If it is part of a MIME type we might block, log the MIME type.
+ std::string mime_type = response.mimeType().utf8();
+ MimeTypeMap mime_type_map = *GetMimeTypeMap();
+ // Also track it if it lacks a MIME type.
+ // TODO(creis): 304 responses have no MIME type, so we don't handle
+ // them correctly. Can we look up their MIME type from the cache?
+ if (mime_type == "")
+ mime_type = "(NONE)";
+ MimeTypeMap::iterator mime_type_iter = mime_type_map.find(mime_type);
+ if (mime_type_iter != mime_type_map.end()) {
UMA_HISTOGRAM_ENUMERATION(
- "SiteIsolation.CrossSiteNonFrameResponse_With_CORS_MIME_Type",
+ "SiteIsolation.CrossSiteNonFrameResponse_MIME_Type",
mime_type_iter->second,
arraysize(kCrossOriginMimeTypesToLog));
- }
- // Sometimes resources are mislabeled as text/html. Once we have some
- // of the payload, we want to determine if this was actually text/html.
- if (mime_type == "text/html")
- GetCrossOriginTextHtmlResponseSet()->insert(response.url().spec());
+ // We also check access control headers, in case this
+ // cross-origin request has been explicitly permitted.
+ if (AllowedByAccessControlHeader(frame, response)) {
+ UMA_HISTOGRAM_ENUMERATION(
+ "SiteIsolation.CrossSiteNonFrameResponse_With_CORS_MIME_Type",
+ mime_type_iter->second,
+ arraysize(kCrossOriginMimeTypesToLog));
+ } else {
+ // Without access control headers, we might block this request.
+ // Sometimes resources are mislabled as text/html, though, and we
+ // should only block them if we can verify that. To do so, we sniff
+ // the content once we have some of the payload.
+ if (mime_type == "text/html") {
+ // Remember the response until we can sniff its contents.
+ GetCrossOriginTextHtmlResponseSet()->insert(
+ response.url().spec());
+ } else if (mime_type == "text/xml" ||
+ mime_type == "text/xsl" ||
+ mime_type == "application/xml" ||
+ mime_type == "application/xhtml+xml" ||
+ mime_type == "application/rss+xml" ||
+ mime_type == "application/atom+xml" ||
+ mime_type == "application/json") {
+ // We will also block XML and JSON MIME types for cross-site
+ // non-frame requests without CORS headers.
+ UMA_HISTOGRAM_COUNTS(
+ "SiteIsolation.CrossSiteNonFrameResponse_xml_or_json_BLOCK",
+ 1);
+ }
+ }
+ }
}
}
}
@@ -141,11 +194,13 @@ void SiteIsolationMetrics::SniffCrossOriginHTML(const WebURL& response_url,
if (!response_url.isValid())
return;
+ // Look up the URL to see if it is a text/html request we are tracking.
CrossOriginTextHtmlResponseSet& cross_origin_text_html_response_set =
*GetCrossOriginTextHtmlResponseSet();
CrossOriginTextHtmlResponseSet::iterator request_iter =
cross_origin_text_html_response_set.find(response_url.spec());
if (request_iter != cross_origin_text_html_response_set.end()) {
+ // Log whether it actually looks like HTML.
std::string sniffed_mime_type;
bool successful = net::SniffMimeType(data, len, response_url,
"", &sniffed_mime_type);