site_isolation_policy.cc revision 58537e28ecd584eab876aee8be7156509866d23a
1424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 2424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// found in the LICENSE file. 4424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 5424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "content/child/site_isolation_policy.h" 6424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 7424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "base/basictypes.h" 8424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "base/command_line.h" 9424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "base/logging.h" 10424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "base/metrics/histogram.h" 11424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "base/strings/string_piece.h" 12424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "base/strings/string_util.h" 13424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "content/public/common/content_switches.h" 14424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "net/base/registry_controlled_domains/registry_controlled_domain.h" 15424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "net/http/http_response_headers.h" 16424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "third_party/WebKit/public/platform/WebHTTPHeaderVisitor.h" 17424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "third_party/WebKit/public/platform/WebString.h" 18424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "third_party/WebKit/public/platform/WebURL.h" 19424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "third_party/WebKit/public/platform/WebURLRequest.h" 20424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "third_party/WebKit/public/platform/WebURLResponse.h" 21424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "third_party/WebKit/public/web/WebDocument.h" 22424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "third_party/WebKit/public/web/WebFrame.h" 23424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "third_party/WebKit/public/web/WebFrameClient.h" 24424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "third_party/WebKit/public/web/WebSecurityOrigin.h" 25424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 26424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)using WebKit::WebDocument; 27424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)using WebKit::WebString; 28424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)using WebKit::WebURL; 29424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)using WebKit::WebURLResponse; 30424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)using WebKit::WebURLRequest; 31424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 32424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)namespace content { 33424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 34424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)namespace { 35424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 36424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// MIME types 37424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)const char kTextHtml[] = "text/html"; 38424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)const char kTextXml[] = "text/xml"; 39424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)const char xAppRssXml[] = "application/rss+xml"; 40424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)const char kAppXml[] = "application/xml"; 41424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)const char kAppJson[] = "application/json"; 42424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)const char kTextJson[] = "text/json"; 43424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)const char kTextXjson[] = "text/x-json"; 44424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)const char kTextPlain[] = "text/plain"; 45424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 46424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} // anonymous namespace 47424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 48424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)SiteIsolationPolicy::ResponseMetaData::ResponseMetaData() {} 49424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 5058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// The cross-site document blocking/UMA data collection is deactivated by 5158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// default, and only activated in renderer processes. 5258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)bool SiteIsolationPolicy::g_policy_enabled = false; 5358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 5458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void SiteIsolationPolicy::SetPolicyEnabled(bool enabled) { 5558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) g_policy_enabled = enabled; 5658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 5758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 58424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void SiteIsolationPolicy::OnReceivedResponse( 59424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) int request_id, 60424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) GURL& frame_origin, 61424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) GURL& response_url, 62424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ResourceType::Type resource_type, 6358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) int origin_pid, 64424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const webkit_glue::ResourceResponseInfo& info) { 6558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (!g_policy_enabled) 6658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return; 6758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 6858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // if |origin_pid| is non-zero, it means that this response is for a plugin 6958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // spawned from this renderer process. We exclude responses for plugins for 7058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // now, but eventually, we're going to make plugin processes directly talk to 7158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // the browser process so that we don't apply cross-site document blocking to 7258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // them. 7358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (origin_pid) 7458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return; 7558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 76424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) UMA_HISTOGRAM_COUNTS("SiteIsolation.AllResponses", 1); 77424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 78424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // See if this is for navigation. If it is, don't block it, under the 79424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // assumption that we will put it in an appropriate process. 80424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (ResourceType::IsFrame(resource_type)) 81424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return; 82424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 83424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (!IsBlockableScheme(response_url)) 84424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return; 85424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 86424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (IsSameSite(frame_origin, response_url)) 87424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return; 88424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 89424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) SiteIsolationPolicy::ResponseMetaData::CanonicalMimeType canonical_mime_type = 90424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) GetCanonicalMimeType(info.mime_type); 91424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 92424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (canonical_mime_type == SiteIsolationPolicy::ResponseMetaData::Others) 93424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return; 94424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 95424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Every CORS request should have the Access-Control-Allow-Origin header even 96424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // if it is preceded by a pre-flight request. Therefore, if this is a CORS 97424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // request, it has this header. response.httpHeaderField() internally uses 98424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // case-insensitive matching for the header name. 99424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) std::string access_control_origin; 100424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 101424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // We can use a case-insensitive header name for EnumerateHeader(). 102424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) info.headers->EnumerateHeader( 103424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) NULL, "access-control-allow-origin", &access_control_origin); 104424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (IsValidCorsHeaderSet(frame_origin, response_url, access_control_origin)) 105424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return; 106424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 107424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Real XSD data collection starts from here. 108424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) std::string no_sniff; 109424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) info.headers->EnumerateHeader(NULL, "x-content-type-options", &no_sniff); 110424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 111424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ResponseMetaData resp_data; 112424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) resp_data.frame_origin = frame_origin.spec(); 113424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) resp_data.response_url = response_url; 114424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) resp_data.resource_type = resource_type; 115424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) resp_data.canonical_mime_type = canonical_mime_type; 116424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) resp_data.http_status_code = info.headers->response_code(); 117424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) resp_data.no_sniff = LowerCaseEqualsASCII(no_sniff, "nosniff"); 118424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 119424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) RequestIdToMetaDataMap* metadata_map = GetRequestIdToMetaDataMap(); 120424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) (*metadata_map)[request_id] = resp_data; 121424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 122424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 123424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// These macros are defined here so that we prevent code size bloat-up due to 124424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// the UMA_HISTOGRAM_* macros. Similar logic is used for recording UMA stats for 125424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// different MIME types, but we cannot create a helper function for this since 126424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// UMA_HISTOGRAM_* macros do not accept variables as their bucket names. As a 127424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// solution, macros are used instead to capture the repeated pattern for 128424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// recording UMA stats. TODO(dsjang): this is only needed for collecting UMA 129424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// stat. Will be deleted when this class is used for actual blocking. 130424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 131424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#define SITE_ISOLATION_POLICY_COUNT_BLOCK(BUCKET_PREFIX) \ 132424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) UMA_HISTOGRAM_COUNTS( BUCKET_PREFIX ".Blocked", 1); \ 133424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) result = true; \ 134424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (renderable_status_code) { \ 135424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) UMA_HISTOGRAM_ENUMERATION( \ 136424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) BUCKET_PREFIX ".Blocked.RenderableStatusCode", \ 137424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) resp_data.resource_type, \ 138424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) WebURLRequest::TargetIsUnspecified + 1); \ 139424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } else { \ 140424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) UMA_HISTOGRAM_COUNTS(BUCKET_PREFIX ".Blocked.NonRenderableStatusCode",1);\ 141424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 142424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 143424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#define SITE_ISOLATION_POLICY_COUNT_NO_SNIFF_BLOCK(BUCKET_PREFIX) \ 144424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) UMA_HISTOGRAM_COUNTS( BUCKET_PREFIX ".NoSniffBlocked", 1); \ 145424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) result = true; \ 146424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (renderable_status_code) { \ 147424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) UMA_HISTOGRAM_ENUMERATION( \ 148424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) BUCKET_PREFIX ".NoSniffBlocked.RenderableStatusCode", \ 149424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) resp_data.resource_type, \ 150424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) WebURLRequest::TargetIsUnspecified + 1); \ 151424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } else { \ 152424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) UMA_HISTOGRAM_ENUMERATION( \ 153424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) BUCKET_PREFIX ".NoSniffBlocked.NonRenderableStatusCode", \ 154424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) resp_data.resource_type, \ 155424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) WebURLRequest::TargetIsUnspecified + 1); \ 156424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 157424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 158424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#define SITE_ISOLATION_POLICY_COUNT_NOTBLOCK(BUCKET_PREFIX) \ 159424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) UMA_HISTOGRAM_COUNTS(BUCKET_PREFIX ".NotBlocked", 1); \ 160424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (is_sniffed_for_js) \ 161424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) UMA_HISTOGRAM_COUNTS(BUCKET_PREFIX ".NotBlocked.MaybeJS", 1); \ 162424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 163424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#define SITE_ISOLATION_POLICY_SNIFF_AND_COUNT(SNIFF_EXPR,BUCKET_PREFIX) \ 164424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (SNIFF_EXPR) { \ 165424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) SITE_ISOLATION_POLICY_COUNT_BLOCK(BUCKET_PREFIX) \ 166424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } else { \ 167424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (resp_data.no_sniff) { \ 168424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) SITE_ISOLATION_POLICY_COUNT_NO_SNIFF_BLOCK(BUCKET_PREFIX) \ 169424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } else { \ 170424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) SITE_ISOLATION_POLICY_COUNT_NOTBLOCK(BUCKET_PREFIX) \ 171424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } \ 172424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 173424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 174424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)bool SiteIsolationPolicy::ShouldBlockResponse( 175424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) int request_id, 176424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const char* data, 177424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) int length, 178424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) std::string* alternative_data) { 17958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (!g_policy_enabled) 18058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return false; 18158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 182424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) RequestIdToMetaDataMap* metadata_map = GetRequestIdToMetaDataMap(); 183424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) RequestIdToResultMap* result_map = GetRequestIdToResultMap(); 184424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 185424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // If there's an entry for |request_id| in blocked_map, this request's first 186424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // data packet has already been examined. We can return the result here. 187424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (result_map->count(request_id) != 0) { 188424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if ((*result_map)[request_id]) { 189424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Here, the blocking result has been set for the previous run of 190424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // ShouldBlockResponse(), so we set alternative data to an empty string so 191424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // that ResourceDispatcher doesn't call its peer's onReceivedData() with 192424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // the alternative data. 193424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) alternative_data->erase(); 194424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return true; 195424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 196424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return false; 197424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 198424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 199424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // If result_map doesn't have an entry for |request_id|, we're receiving the 200424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // first data packet for request_id. If request_id is not registered, this 201424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // request is identified as a non-target of our policy. So we return true. 202424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (metadata_map->count(request_id) == 0) { 203424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // We set request_id to true so that we always return true for this request. 204424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) (*result_map)[request_id] = false; 205424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return false; 206424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 207424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 208424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // We now look at the first data packet received for request_id. 209424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ResponseMetaData resp_data = (*metadata_map)[request_id]; 210424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) metadata_map->erase(request_id); 211424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 212424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Record the length of the first received network packet to see if it's 213424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // enough for sniffing. 214424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) UMA_HISTOGRAM_COUNTS("SiteIsolation.XSD.DataLength", length); 215424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 216424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Record the number of cross-site document responses with a specific mime 217424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // type (text/html, text/xml, etc). 218424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) UMA_HISTOGRAM_ENUMERATION( 219424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) "SiteIsolation.XSD.MimeType", 220424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) resp_data.canonical_mime_type, 221424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) SiteIsolationPolicy::ResponseMetaData::MaxCanonicalMimeType); 222424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 223424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Store the result of cross-site document blocking analysis. True means we 224424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // can return this document to the renderer, false means that we have to block 225424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // the response data. 226424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) bool result = false; 227424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 228424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // The content is blocked if it is sniffed for HTML/JSON/XML. When the blocked 229424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // response is with an error status code, it is not disruptive by the 230424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // following reasons : 1) the blocked content is not a binary object (such as 231424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // an image) since it is sniffed for text; 2) then, this blocking only breaks 232424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // the renderer behavior only if it is either JavaScript or CSS. However, the 233424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // renderer doesn't use the contents of JS/CSS with unaffected status code 234424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // (e.g, 404). 3) the renderer is expected not to use the cross-site document 235424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // content for purposes other than JS/CSS (e.g, XHR). 236424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) bool renderable_status_code = IsRenderableStatusCodeForDocument( 237424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) resp_data.http_status_code); 238424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 239424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // This is only used for false-negative analysis for non-blocked resources. 240424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) bool is_sniffed_for_js = SniffForJS(data, length); 241424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 242424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Record the number of responses whose content is sniffed for what its mime 243424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // type claims it to be. For example, we apply a HTML sniffer for a document 244424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // tagged with text/html here. Whenever this check becomes true, we'll block 245424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // the response. 246424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) switch (resp_data.canonical_mime_type) { 247424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) case SiteIsolationPolicy::ResponseMetaData::HTML: 248424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) SITE_ISOLATION_POLICY_SNIFF_AND_COUNT(SniffForHTML(data, length), 249424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) "SiteIsolation.XSD.HTML"); 250424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) break; 251424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) case SiteIsolationPolicy::ResponseMetaData::XML: 252424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) SITE_ISOLATION_POLICY_SNIFF_AND_COUNT(SniffForXML(data, length), 253424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) "SiteIsolation.XSD.XML"); 254424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) break; 255424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) case SiteIsolationPolicy::ResponseMetaData::JSON: 256424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) SITE_ISOLATION_POLICY_SNIFF_AND_COUNT(SniffForJSON(data, length), 257424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) "SiteIsolation.XSD.JSON"); 258424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) break; 259424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) case SiteIsolationPolicy::ResponseMetaData::Plain: 260424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (SniffForHTML(data, length)) { 261424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) SITE_ISOLATION_POLICY_COUNT_BLOCK( 262424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) "SiteIsolation.XSD.Plain.HTML"); 263424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } else if (SniffForXML(data, length)) { 264424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) SITE_ISOLATION_POLICY_COUNT_BLOCK( 265424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) "SiteIsolation.XSD.Plain.XML"); 266424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } else if (SniffForJSON(data, length)) { 267424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) SITE_ISOLATION_POLICY_COUNT_BLOCK( 268424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) "SiteIsolation.XSD.Plain.JSON"); 269424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } else if (is_sniffed_for_js) { 270424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (resp_data.no_sniff) { 271424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) SITE_ISOLATION_POLICY_COUNT_NO_SNIFF_BLOCK( 272424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) "SiteIsolation.XSD.Plain"); 273424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } else { 274424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) SITE_ISOLATION_POLICY_COUNT_NOTBLOCK( 275424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) "SiteIsolation.XSD.Plain"); 276424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 277424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 278424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) break; 279424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) default : 280424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) NOTREACHED() << 281424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) "Not a blockable mime type. This mime type shouldn't reach here."; 282424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) break; 283424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 284424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 285424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const CommandLine& command_line = *CommandLine::ForCurrentProcess(); 286424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (!command_line.HasSwitch(switches::kBlockCrossSiteDocuments)) 287424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) result = false; 288424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) (*result_map)[request_id] = result; 289424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 290424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (result) { 291424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) alternative_data->erase(); 292424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) alternative_data->insert(0, " "); 293424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) LOG(ERROR) << resp_data.response_url 294424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) << " is blocked as an illegal cross-site document from " 295424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) << resp_data.frame_origin; 296424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 297424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return result; 298424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 299424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 300424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#undef SITE_ISOLATION_POLICY_COUNT_NOTBLOCK 301424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#undef SITE_ISOLATION_POLICY_SNIFF_AND_COUNT 302424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#undef SITE_ISOLATION_POLICY_COUNT_BLOCK 303424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 304424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void SiteIsolationPolicy::OnRequestComplete(int request_id) { 30558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (!g_policy_enabled) 30658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return; 307424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) RequestIdToMetaDataMap* metadata_map = GetRequestIdToMetaDataMap(); 308424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) RequestIdToResultMap* result_map = GetRequestIdToResultMap(); 309424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) metadata_map->erase(request_id); 310424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) result_map->erase(request_id); 311424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 312424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 313424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)SiteIsolationPolicy::ResponseMetaData::CanonicalMimeType 314424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)SiteIsolationPolicy::GetCanonicalMimeType(const std::string& mime_type) { 315424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (LowerCaseEqualsASCII(mime_type, kTextHtml)) { 316424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return SiteIsolationPolicy::ResponseMetaData::HTML; 317424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 318424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 319424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (LowerCaseEqualsASCII(mime_type, kTextPlain)) { 320424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return SiteIsolationPolicy::ResponseMetaData::Plain; 321424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 322424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 323424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (LowerCaseEqualsASCII(mime_type, kAppJson) || 324424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) LowerCaseEqualsASCII(mime_type, kTextJson) || 325424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) LowerCaseEqualsASCII(mime_type, kTextXjson)) { 326424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return SiteIsolationPolicy::ResponseMetaData::JSON; 327424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 328424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 329424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (LowerCaseEqualsASCII(mime_type, kTextXml) || 330424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) LowerCaseEqualsASCII(mime_type, xAppRssXml) || 331424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) LowerCaseEqualsASCII(mime_type, kAppXml)) { 332424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return SiteIsolationPolicy::ResponseMetaData::XML; 333424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 334424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 335424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return SiteIsolationPolicy::ResponseMetaData::Others; 336424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 337424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 338424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 339424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)bool SiteIsolationPolicy::IsBlockableScheme(const GURL& url) { 340424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // We exclude ftp:// from here. FTP doesn't provide a Content-Type 341424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // header which our policy depends on, so we cannot protect any 342424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // document from FTP servers. 343424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return url.SchemeIs("http") || url.SchemeIs("https"); 344424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 345424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 346424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)bool SiteIsolationPolicy::IsSameSite(const GURL& frame_origin, 347424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const GURL& response_url) { 348424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 349424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (!frame_origin.is_valid() || !response_url.is_valid()) 350424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return false; 351424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 352424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (frame_origin.scheme() != response_url.scheme()) 353424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return false; 354424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 355424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // SameDomainOrHost() extracts the effective domains (public suffix plus one) 356424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // from the two URLs and compare them. 357424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // TODO(dsjang): use INCLUDE_PRIVATE_REGISTRIES when http://crbug.com/7988 is 358424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // fixed. 359424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return net::registry_controlled_domains::SameDomainOrHost( 360424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) frame_origin, 361424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) response_url, 362424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) net::registry_controlled_domains::EXCLUDE_PRIVATE_REGISTRIES); 363424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 364424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 365424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)bool SiteIsolationPolicy::IsFrameNavigating(WebKit::WebFrame* frame) { 366424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // When a navigation starts, frame->provisionalDataSource() is set 367424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // to a not-null value which stands for the request made for the 368424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // navigation. As soon as the network request is committed to the 369424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // frame, frame->provisionalDataSource() is converted to null, and 370424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // the committed data source is moved to frame->dataSource(). This 371424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // is the most reliable way to detect whether the frame is in 372424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // navigation or not. 373424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return frame->provisionalDataSource() != NULL; 374424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 375424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 376424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// We don't use Webkit's existing CORS policy implementation since 377424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// their policy works in terms of origins, not sites. For example, 378424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// when frame is sub.a.com and it is not allowed to access a document 379424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// with sub1.a.com. But under Site Isolation, it's allowed. 380424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)bool SiteIsolationPolicy::IsValidCorsHeaderSet( 381424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) GURL& frame_origin, 382424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) GURL& website_origin, 383424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) std::string access_control_origin) { 384424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Many websites are sending back "\"*\"" instead of "*". This is 385424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // non-standard practice, and not supported by Chrome. Refer to 386424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // CrossOriginAccessControl::passesAccessControlCheck(). 387424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 388424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // TODO(dsjang): * is not allowed for the response from a request 389424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // with cookies. This allows for more than what the renderer will 390424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // eventually be able to receive, so we won't see illegal cross-site 391424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // documents allowed by this. We have to find a way to see if this 392424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // response is from a cookie-tagged request or not in the future. 393424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (access_control_origin == "*") 394424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return true; 395424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 396424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // TODO(dsjang): The CORS spec only treats a fully specified URL, except for 397424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // "*", but many websites are using just a domain for access_control_origin, 398424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // and this is blocked by Webkit's CORS logic here : 399424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // CrossOriginAccessControl::passesAccessControlCheck(). GURL is set 400424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // is_valid() to false when it is created from a URL containing * in the 401424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // domain part. 402424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 403424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) GURL cors_origin(access_control_origin); 404424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return IsSameSite(frame_origin, cors_origin); 405424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 406424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 407424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// This function is a slight modification of |net::SniffForHTML|. 408424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)bool SiteIsolationPolicy::SniffForHTML(const char* data, size_t length) { 409424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // The content sniffer used by Chrome and Firefox are using "<!--" 410424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // as one of the HTML signatures, but it also appears in valid 411424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // JavaScript, considered as well-formed JS by the browser. Since 412424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // we do not want to block any JS, we exclude it from our HTML 413424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // signatures. This can weaken our document block policy, but we can 414424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // break less websites. 415424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // TODO(dsjang): parameterize |net::SniffForHTML| with an option 416424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // that decides whether to include <!-- or not, so that we can 417424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // remove this function. 418424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const char* html_signatures[] = {"<!DOCTYPE html", // HTML5 spec 419424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) "<script", // HTML5 spec, Mozilla 420424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) "<html", // HTML5 spec, Mozilla 421424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) "<head", // HTML5 spec, Mozilla 422424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) "<iframe", // Mozilla 423424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) "<h1", // Mozilla 424424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) "<div", // Mozilla 425424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) "<font", // Mozilla 426424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) "<table", // Mozilla 427424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) "<a", // Mozilla 428424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) "<style", // Mozilla 429424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) "<title", // Mozilla 430424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) "<b", // Mozilla 431424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) "<body", // Mozilla 432424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) "<br", "<p", // Mozilla 433424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) "<?xml" // Mozilla 434424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) }; 435424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 436424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (MatchesSignature( 437424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) data, length, html_signatures, arraysize(html_signatures))) 438424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return true; 439424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 440424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // "<!--" is specially treated since web JS can use "<!--" "-->" pair for 441424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // comments. 442424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) static const char* comment_begins[] = {"<!--"}; 443424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 444424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (MatchesSignature( 445424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) data, length, comment_begins, arraysize(comment_begins))) { 446424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Search for --> and do SniffForHTML after that. If we can find the 447424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // comment's end, we start HTML sniffing from there again. 448424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) static const char end_comment[] = "-->"; 449424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) base::StringPiece data_as_stringpiece(data, length); 450424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 451424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) size_t offset = data_as_stringpiece.find(end_comment); 452424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (offset != base::StringPiece::npos) { 453424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) size_t new_start_offset = offset + strlen(end_comment); 454424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (new_start_offset < length) { 455424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return SniffForHTML(data + new_start_offset, 456424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) length - new_start_offset); 457424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 458424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 459424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 460424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 461424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return false; 462424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 463424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 464424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)bool SiteIsolationPolicy::SniffForXML(const char* data, size_t length) { 465424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // TODO(dsjang): Chrome's mime_sniffer is using strncasecmp() for 466424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // this signature. However, XML is case-sensitive. Don't we have to 467424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // be more lenient only to block documents starting with the exact 468424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // string <?xml rather than <?XML ? 469424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const char* xml_signatures[] = {"<?xml" // Mozilla 470424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) }; 471424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return MatchesSignature( 472424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) data, length, xml_signatures, arraysize(xml_signatures)); 473424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 474424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 475424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)bool SiteIsolationPolicy::SniffForJSON(const char* data, size_t length) { 476424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // TODO(dsjang): We have to come up with a better way to sniff 477424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // JSON. However, even RE cannot help us that much due to the fact 478424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // that we don't do full parsing. This DFA starts with state 0, and 479424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // finds {, "/' and : in that order. We're avoiding adding a 480424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // dependency on a regular expression library. 481424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const int kInitState = 0; 482424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const int kLeftBraceState = 1; 483424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const int kLeftQuoteState = 2; 484424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const int kColonState = 3; 485424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const int kDeadState = 4; 486424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 487424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) int state = kInitState; 488424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) for (size_t i = 0; i < length && state < kColonState; ++i) { 489424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const char c = data[i]; 490424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (c == ' ' || c == '\t' || c == '\r' || c == '\n') 491424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) continue; 492424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 493424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) switch (state) { 494424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) case kInitState: 495424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (c == '{') 496424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) state = kLeftBraceState; 497424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) else 498424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) state = kDeadState; 499424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) break; 500424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) case kLeftBraceState: 501424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (c == '\"' || c == '\'') 502424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) state = kLeftQuoteState; 503424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) else 504424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) state = kDeadState; 505424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) break; 506424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) case kLeftQuoteState: 507424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (c == ':') 508424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) state = kColonState; 509424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) break; 510424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) default: 511424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) NOTREACHED(); 512424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) break; 513424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 514424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 515424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return state == kColonState; 516424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 517424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 518424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)bool SiteIsolationPolicy::MatchesSignature(const char* raw_data, 519424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) size_t raw_length, 520424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const char* signatures[], 521424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) size_t arr_size) { 522424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) size_t start = 0; 523424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Skip white characters at the beginning of the document. 524424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) for (start = 0; start < raw_length; ++start) { 525424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) char c = raw_data[start]; 526424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (!(c == ' ' || c == '\t' || c == '\r' || c == '\n')) 527424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) break; 528424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 529424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 530424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // There is no not-whitespace character in this document. 531424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (!(start < raw_length)) 532424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return false; 533424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 534424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const char* data = raw_data + start; 535424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) size_t length = raw_length - start; 536424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 537424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) for (size_t sig_index = 0; sig_index < arr_size; ++sig_index) { 538424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const char* signature = signatures[sig_index]; 539424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) size_t signature_length = strlen(signature); 540424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 541424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (length < signature_length) 542424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) continue; 543424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 544424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (!base::strncasecmp(signature, data, signature_length)) 545424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return true; 546424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 547424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return false; 548424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 549424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 550424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)bool SiteIsolationPolicy::IsRenderableStatusCodeForDocument(int status_code) { 551424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Chrome only uses the content of a response with one of these status codes 552424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // for CSS/JavaScript. For images, Chrome just ignores status code. 553424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const int renderable_status_code[] = {200, 201, 202, 203, 206, 300, 301, 302, 554424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 303, 305, 306, 307}; 555424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) for (size_t i = 0; i < arraysize(renderable_status_code); ++i) { 556424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (renderable_status_code[i] == status_code) 557424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return true; 558424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 559424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return false; 560424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 561424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 562424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)bool SiteIsolationPolicy::SniffForJS(const char* data, size_t length) { 563424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // TODO(dsjang): This is a real hack. The only purpose of this function is to 564424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // try to see if there's any possibility that this data can be JavaScript 565424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // (superset of JS). This function will be removed once UMA stats are 566424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // gathered. 567424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 568424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Search for "var " for JS detection. 569424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return base::StringPiece(data, length).find("var ") != 570424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) base::StringPiece::npos; 571424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 572424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 573424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)SiteIsolationPolicy::RequestIdToMetaDataMap* 574424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)SiteIsolationPolicy::GetRequestIdToMetaDataMap() { 575424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) CR_DEFINE_STATIC_LOCAL(RequestIdToMetaDataMap, metadata_map_, ()); 576424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return &metadata_map_; 577424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 578424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 579424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)SiteIsolationPolicy::RequestIdToResultMap* 580424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)SiteIsolationPolicy::GetRequestIdToResultMap() { 581424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) CR_DEFINE_STATIC_LOCAL(RequestIdToResultMap, result_map_, ()); 582424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return &result_map_; 583424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 584424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 585424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} // namespace content 586