OLD | NEW |
---|---|
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "content/child/site_isolation_policy.h" | 5 #include "content/child/site_isolation_policy.h" |
6 | 6 |
7 #include "base/basictypes.h" | 7 #include "base/basictypes.h" |
8 #include "base/command_line.h" | 8 #include "base/command_line.h" |
9 #include "base/lazy_instance.h" | 9 #include "base/lazy_instance.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
11 #include "base/metrics/histogram.h" | 11 #include "base/metrics/histogram.h" |
12 #include "base/strings/string_piece.h" | |
13 #include "base/strings/string_util.h" | 12 #include "base/strings/string_util.h" |
14 #include "content/child/child_thread.h" | |
15 #include "content/public/common/content_switches.h" | 13 #include "content/public/common/content_switches.h" |
16 #include "net/base/registry_controlled_domains/registry_controlled_domain.h" | 14 #include "net/base/registry_controlled_domains/registry_controlled_domain.h" |
17 #include "net/http/http_response_headers.h" | 15 #include "net/http/http_response_headers.h" |
18 #include "third_party/WebKit/public/platform/WebHTTPHeaderVisitor.h" | 16 #include "webkit/common/resource_response_info.h" |
19 #include "third_party/WebKit/public/platform/WebString.h" | |
20 #include "third_party/WebKit/public/platform/WebURL.h" | |
21 #include "third_party/WebKit/public/platform/WebURLRequest.h" | |
22 #include "third_party/WebKit/public/platform/WebURLResponse.h" | |
23 #include "third_party/WebKit/public/web/WebDocument.h" | |
24 #include "third_party/WebKit/public/web/WebFrame.h" | |
25 #include "third_party/WebKit/public/web/WebFrameClient.h" | |
26 #include "third_party/WebKit/public/web/WebSecurityOrigin.h" | |
27 | 17 |
28 using base::StringPiece; | 18 using base::StringPiece; |
29 using blink::WebDocument; | |
30 using blink::WebString; | |
31 using blink::WebURL; | |
32 using blink::WebURLResponse; | |
33 using blink::WebURLRequest; | |
34 | 19 |
35 namespace content { | 20 namespace content { |
36 | 21 |
37 namespace { | 22 namespace { |
38 | 23 |
39 // Maintain the bookkeeping data between OnReceivedResponse and | |
40 // OnReceivedData. The key is a request id maintained by ResourceDispatcher. | |
41 static base::LazyInstance<SiteIsolationPolicy::RequestIdToMetaDataMap> | |
42 g_metadata_map = LAZY_INSTANCE_INITIALIZER; | |
43 | |
44 // Maintain the bookkeeping data for OnReceivedData. Blocking decision is made | |
45 // when OnReceivedData is called for the first time for a request, and the | |
46 // decision will remain the same for following data. This map maintains the | |
47 // decision. The key is a request id maintained by ResourceDispatcher. | |
48 static base::LazyInstance<SiteIsolationPolicy::RequestIdToResultMap> | |
49 g_result_map = LAZY_INSTANCE_INITIALIZER; | |
50 | |
51 // The cross-site document blocking/UMA data collection is deactivated by | 24 // The cross-site document blocking/UMA data collection is deactivated by |
52 // default, and only activated in renderer processes. | 25 // default, and only activated in renderer processes. |
53 static bool g_policy_enabled = false; | 26 static bool g_policy_enabled = false; |
54 | 27 |
55 // MIME types | 28 // MIME types |
56 const char kTextHtml[] = "text/html"; | 29 const char kTextHtml[] = "text/html"; |
57 const char kTextXml[] = "text/xml"; | 30 const char kTextXml[] = "text/xml"; |
58 const char xAppRssXml[] = "application/rss+xml"; | 31 const char xAppRssXml[] = "application/rss+xml"; |
59 const char kAppXml[] = "application/xml"; | 32 const char kAppXml[] = "application/xml"; |
60 const char kAppJson[] = "application/json"; | 33 const char kAppJson[] = "application/json"; |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
116 name, | 89 name, |
117 1, | 90 1, |
118 boundary_value, | 91 boundary_value, |
119 boundary_value + 1, | 92 boundary_value + 1, |
120 base::HistogramBase::kUmaTargetedHistogramFlag); | 93 base::HistogramBase::kUmaTargetedHistogramFlag); |
121 histogram_pointer->Add(sample); | 94 histogram_pointer->Add(sample); |
122 } | 95 } |
123 | 96 |
124 void HistogramCountBlockedResponse( | 97 void HistogramCountBlockedResponse( |
125 const std::string& bucket_prefix, | 98 const std::string& bucket_prefix, |
126 const SiteIsolationPolicy::ResponseMetaData& resp_data, | 99 linked_ptr<SiteIsolationResponseMetaData>& resp_data, |
127 bool nosniff_block) { | 100 bool nosniff_block) { |
128 std::string block_label(nosniff_block ? ".NoSniffBlocked" : ".Blocked"); | 101 std::string block_label(nosniff_block ? ".NoSniffBlocked" : ".Blocked"); |
129 IncrementHistogramCount(bucket_prefix + block_label); | 102 IncrementHistogramCount(bucket_prefix + block_label); |
130 | 103 |
131 // The content is blocked if it is sniffed as HTML/JSON/XML. When | 104 // The content is blocked if it is sniffed as HTML/JSON/XML. When |
132 // the blocked response is with an error status code, it is not | 105 // the blocked response is with an error status code, it is not |
133 // disruptive for the following reasons : 1) the blocked content is | 106 // disruptive for the following reasons : 1) the blocked content is |
134 // not a binary object (such as an image) since it is sniffed as | 107 // not a binary object (such as an image) since it is sniffed as |
135 // text; 2) then, this blocking only breaks the renderer behavior | 108 // text; 2) then, this blocking only breaks the renderer behavior |
136 // only if it is either JavaScript or CSS. However, the renderer | 109 // only if it is either JavaScript or CSS. However, the renderer |
137 // doesn't use the contents of JS/CSS with unaffected status code | 110 // doesn't use the contents of JS/CSS with unaffected status code |
138 // (e.g, 404). 3) the renderer is expected not to use the cross-site | 111 // (e.g, 404). 3) the renderer is expected not to use the cross-site |
139 // document content for purposes other than JS/CSS (e.g, XHR). | 112 // document content for purposes other than JS/CSS (e.g, XHR). |
140 bool renderable_status_code = | 113 bool renderable_status_code = |
141 IsRenderableStatusCode(resp_data.http_status_code); | 114 IsRenderableStatusCode(resp_data->http_status_code); |
142 | 115 |
143 if (renderable_status_code) { | 116 if (renderable_status_code) { |
144 IncrementHistogramEnum( | 117 IncrementHistogramEnum( |
145 bucket_prefix + block_label + ".RenderableStatusCode", | 118 bucket_prefix + block_label + ".RenderableStatusCode", |
146 resp_data.resource_type, | 119 resp_data->resource_type, |
147 ResourceType::LAST_TYPE); | 120 ResourceType::LAST_TYPE); |
148 } else { | 121 } else { |
149 IncrementHistogramCount(bucket_prefix + block_label + | 122 IncrementHistogramCount(bucket_prefix + block_label + |
150 ".NonRenderableStatusCode"); | 123 ".NonRenderableStatusCode"); |
151 } | 124 } |
152 } | 125 } |
153 | 126 |
154 void HistogramCountNotBlockedResponse(const std::string& bucket_prefix, | 127 void HistogramCountNotBlockedResponse(const std::string& bucket_prefix, |
155 bool sniffed_as_js) { | 128 bool sniffed_as_js) { |
156 IncrementHistogramCount(bucket_prefix + ".NotBlocked"); | 129 IncrementHistogramCount(bucket_prefix + ".NotBlocked"); |
157 if (sniffed_as_js) | 130 if (sniffed_as_js) |
158 IncrementHistogramCount(bucket_prefix + ".NotBlocked.MaybeJS"); | 131 IncrementHistogramCount(bucket_prefix + ".NotBlocked.MaybeJS"); |
159 } | 132 } |
160 | 133 |
161 } // namespace | 134 } // namespace |
162 | 135 |
163 SiteIsolationPolicy::ResponseMetaData::ResponseMetaData() {} | 136 SiteIsolationResponseMetaData::SiteIsolationResponseMetaData() {} |
164 | 137 |
165 void SiteIsolationPolicy::SetPolicyEnabled(bool enabled) { | 138 void SiteIsolationPolicy::SetPolicyEnabled(bool enabled) { |
166 g_policy_enabled = enabled; | 139 g_policy_enabled = enabled; |
167 } | 140 } |
168 | 141 |
169 void SiteIsolationPolicy::OnReceivedResponse( | 142 linked_ptr<SiteIsolationResponseMetaData> |
170 int request_id, | 143 SiteIsolationPolicy::OnReceivedResponse( |
171 const GURL& frame_origin, | 144 const GURL& frame_origin, |
172 const GURL& response_url, | 145 const GURL& response_url, |
173 ResourceType::Type resource_type, | 146 ResourceType::Type resource_type, |
174 int origin_pid, | 147 int origin_pid, |
175 const webkit_glue::ResourceResponseInfo& info) { | 148 const webkit_glue::ResourceResponseInfo& info) { |
176 if (!g_policy_enabled) | 149 if (!g_policy_enabled) |
177 return; | 150 return linked_ptr<SiteIsolationResponseMetaData>(); |
178 | 151 |
179 // if |origin_pid| is non-zero, it means that this response is for a plugin | 152 // if |origin_pid| is non-zero, it means that this response is for a plugin |
180 // spawned from this renderer process. We exclude responses for plugins for | 153 // spawned from this renderer process. We exclude responses for plugins for |
181 // now, but eventually, we're going to make plugin processes directly talk to | 154 // now, but eventually, we're going to make plugin processes directly talk to |
182 // the browser process so that we don't apply cross-site document blocking to | 155 // the browser process so that we don't apply cross-site document blocking to |
183 // them. | 156 // them. |
184 if (origin_pid) | 157 if (origin_pid) |
185 return; | 158 return linked_ptr<SiteIsolationResponseMetaData>(); |
186 | 159 |
187 UMA_HISTOGRAM_COUNTS("SiteIsolation.AllResponses", 1); | 160 UMA_HISTOGRAM_COUNTS("SiteIsolation.AllResponses", 1); |
188 | 161 |
189 // See if this is for navigation. If it is, don't block it, under the | 162 // See if this is for navigation. If it is, don't block it, under the |
190 // assumption that we will put it in an appropriate process. | 163 // assumption that we will put it in an appropriate process. |
191 if (ResourceType::IsFrame(resource_type)) | 164 if (ResourceType::IsFrame(resource_type)) |
192 return; | 165 return linked_ptr<SiteIsolationResponseMetaData>(); |
193 | 166 |
194 if (!IsBlockableScheme(response_url)) | 167 if (!IsBlockableScheme(response_url)) |
195 return; | 168 return linked_ptr<SiteIsolationResponseMetaData>(); |
196 | 169 |
197 if (IsSameSite(frame_origin, response_url)) | 170 if (IsSameSite(frame_origin, response_url)) |
198 return; | 171 return linked_ptr<SiteIsolationResponseMetaData>(); |
199 | 172 |
200 SiteIsolationPolicy::ResponseMetaData::CanonicalMimeType canonical_mime_type = | 173 SiteIsolationResponseMetaData::CanonicalMimeType canonical_mime_type = |
201 GetCanonicalMimeType(info.mime_type); | 174 GetCanonicalMimeType(info.mime_type); |
202 | 175 |
203 if (canonical_mime_type == SiteIsolationPolicy::ResponseMetaData::Others) | 176 if (canonical_mime_type == SiteIsolationResponseMetaData::Others) |
204 return; | 177 return linked_ptr<SiteIsolationResponseMetaData>(); |
205 | 178 |
206 // Every CORS request should have the Access-Control-Allow-Origin header even | 179 // Every CORS request should have the Access-Control-Allow-Origin header even |
207 // if it is preceded by a pre-flight request. Therefore, if this is a CORS | 180 // if it is preceded by a pre-flight request. Therefore, if this is a CORS |
208 // request, it has this header. response.httpHeaderField() internally uses | 181 // request, it has this header. response.httpHeaderField() internally uses |
209 // case-insensitive matching for the header name. | 182 // case-insensitive matching for the header name. |
210 std::string access_control_origin; | 183 std::string access_control_origin; |
211 | 184 |
212 // We can use a case-insensitive header name for EnumerateHeader(). | 185 // We can use a case-insensitive header name for EnumerateHeader(). |
213 info.headers->EnumerateHeader( | 186 info.headers->EnumerateHeader( |
214 NULL, "access-control-allow-origin", &access_control_origin); | 187 NULL, "access-control-allow-origin", &access_control_origin); |
215 if (IsValidCorsHeaderSet(frame_origin, response_url, access_control_origin)) | 188 if (IsValidCorsHeaderSet(frame_origin, response_url, access_control_origin)) |
216 return; | 189 return linked_ptr<SiteIsolationResponseMetaData>(); |
217 | 190 |
218 // Real XSD data collection starts from here. | 191 // Real XSD data collection starts from here. |
219 std::string no_sniff; | 192 std::string no_sniff; |
220 info.headers->EnumerateHeader(NULL, "x-content-type-options", &no_sniff); | 193 info.headers->EnumerateHeader(NULL, "x-content-type-options", &no_sniff); |
221 | 194 |
222 ResponseMetaData resp_data; | 195 linked_ptr<SiteIsolationResponseMetaData> resp_data( |
223 resp_data.frame_origin = frame_origin.spec(); | 196 new SiteIsolationResponseMetaData); |
224 resp_data.response_url = response_url; | 197 resp_data->frame_origin = frame_origin.spec(); |
225 resp_data.resource_type = resource_type; | 198 resp_data->response_url = response_url; |
226 resp_data.canonical_mime_type = canonical_mime_type; | 199 resp_data->resource_type = resource_type; |
227 resp_data.http_status_code = info.headers->response_code(); | 200 resp_data->canonical_mime_type = canonical_mime_type; |
228 resp_data.no_sniff = LowerCaseEqualsASCII(no_sniff, "nosniff"); | 201 resp_data->http_status_code = info.headers->response_code(); |
202 resp_data->no_sniff = LowerCaseEqualsASCII(no_sniff, "nosniff"); | |
229 | 203 |
230 (g_metadata_map.Get())[request_id] = resp_data; | 204 |
Charlie Reis
2014/03/05 18:22:44
nit: Remove extra line.
oystein (OOO til 10th of July)
2014/03/05 19:23:39
Done.
| |
205 return resp_data; | |
231 } | 206 } |
232 | 207 |
233 bool SiteIsolationPolicy::ShouldBlockResponse( | 208 bool SiteIsolationPolicy::ShouldBlockResponse( |
234 int request_id, | 209 linked_ptr<SiteIsolationResponseMetaData>& resp_data, |
235 const char* raw_data, | 210 const char* raw_data, |
236 int raw_length, | 211 int raw_length, |
237 std::string* alternative_data) { | 212 std::string* alternative_data) { |
238 if (!g_policy_enabled) | 213 if (!g_policy_enabled) |
239 return false; | 214 return false; |
240 | 215 |
241 RequestIdToMetaDataMap& metadata_map = g_metadata_map.Get(); | 216 DCHECK(resp_data.get()); |
242 RequestIdToResultMap& result_map = g_result_map.Get(); | |
243 | |
244 // If there's an entry for |request_id| in blocked_map, this request's first | |
245 // data packet has already been examined. We can return the result here. | |
246 if (result_map.count(request_id) != 0) { | |
247 if (result_map[request_id]) { | |
248 // Here, the blocking result has been set for the previous run of | |
249 // ShouldBlockResponse(), so we set alternative data to an empty string so | |
250 // that ResourceDispatcher doesn't call its peer's onReceivedData() with | |
251 // the alternative data. | |
252 alternative_data->erase(); | |
253 return true; | |
254 } | |
255 return false; | |
256 } | |
257 | |
258 // If result_map doesn't have an entry for |request_id|, we're receiving the | |
259 // first data packet for request_id. If request_id is not registered, this | |
260 // request is identified as a non-target of our policy. So we return true. | |
261 if (metadata_map.count(request_id) == 0) { | |
262 // We set request_id to true so that we always return true for this request. | |
263 result_map[request_id] = false; | |
264 return false; | |
265 } | |
266 | 217 |
267 StringPiece data(raw_data, raw_length); | 218 StringPiece data(raw_data, raw_length); |
268 | 219 |
269 // We now look at the first data packet received for request_id. | |
270 ResponseMetaData resp_data = metadata_map[request_id]; | |
271 metadata_map.erase(request_id); | |
272 | |
273 // Record the length of the first received network packet to see if it's | 220 // Record the length of the first received network packet to see if it's |
274 // enough for sniffing. | 221 // enough for sniffing. |
275 UMA_HISTOGRAM_COUNTS("SiteIsolation.XSD.DataLength", raw_length); | 222 UMA_HISTOGRAM_COUNTS("SiteIsolation.XSD.DataLength", raw_length); |
276 | 223 |
277 // Record the number of cross-site document responses with a specific mime | 224 // Record the number of cross-site document responses with a specific mime |
278 // type (text/html, text/xml, etc). | 225 // type (text/html, text/xml, etc). |
279 UMA_HISTOGRAM_ENUMERATION( | 226 UMA_HISTOGRAM_ENUMERATION( |
280 "SiteIsolation.XSD.MimeType", | 227 "SiteIsolation.XSD.MimeType", |
281 resp_data.canonical_mime_type, | 228 resp_data->canonical_mime_type, |
282 SiteIsolationPolicy::ResponseMetaData::MaxCanonicalMimeType); | 229 SiteIsolationResponseMetaData::MaxCanonicalMimeType); |
283 | 230 |
284 // Store the result of cross-site document blocking analysis. | 231 // Store the result of cross-site document blocking analysis. |
285 bool is_blocked = false; | 232 bool is_blocked = false; |
286 bool sniffed_as_js = SniffForJS(data); | 233 bool sniffed_as_js = SniffForJS(data); |
287 | 234 |
288 // Record the number of responses whose content is sniffed for what its mime | 235 // Record the number of responses whose content is sniffed for what its mime |
289 // type claims it to be. For example, we apply a HTML sniffer for a document | 236 // type claims it to be. For example, we apply a HTML sniffer for a document |
290 // tagged with text/html here. Whenever this check becomes true, we'll block | 237 // tagged with text/html here. Whenever this check becomes true, we'll block |
291 // the response. | 238 // the response. |
292 if (resp_data.canonical_mime_type != | 239 if (resp_data->canonical_mime_type != |
293 SiteIsolationPolicy::ResponseMetaData::Plain) { | 240 SiteIsolationResponseMetaData::Plain) { |
294 std::string bucket_prefix; | 241 std::string bucket_prefix; |
295 bool sniffed_as_target_document = false; | 242 bool sniffed_as_target_document = false; |
296 if (resp_data.canonical_mime_type == | 243 if (resp_data->canonical_mime_type == |
297 SiteIsolationPolicy::ResponseMetaData::HTML) { | 244 SiteIsolationResponseMetaData::HTML) { |
298 bucket_prefix = "SiteIsolation.XSD.HTML"; | 245 bucket_prefix = "SiteIsolation.XSD.HTML"; |
299 sniffed_as_target_document = SniffForHTML(data); | 246 sniffed_as_target_document = SniffForHTML(data); |
300 } else if (resp_data.canonical_mime_type == | 247 } else if (resp_data->canonical_mime_type == |
301 SiteIsolationPolicy::ResponseMetaData::XML) { | 248 SiteIsolationResponseMetaData::XML) { |
302 bucket_prefix = "SiteIsolation.XSD.XML"; | 249 bucket_prefix = "SiteIsolation.XSD.XML"; |
303 sniffed_as_target_document = SniffForXML(data); | 250 sniffed_as_target_document = SniffForXML(data); |
304 } else if (resp_data.canonical_mime_type == | 251 } else if (resp_data->canonical_mime_type == |
305 SiteIsolationPolicy::ResponseMetaData::JSON) { | 252 SiteIsolationResponseMetaData::JSON) { |
306 bucket_prefix = "SiteIsolation.XSD.JSON"; | 253 bucket_prefix = "SiteIsolation.XSD.JSON"; |
307 sniffed_as_target_document = SniffForJSON(data); | 254 sniffed_as_target_document = SniffForJSON(data); |
308 } else { | 255 } else { |
309 NOTREACHED() << "Not a blockable mime type: " | 256 NOTREACHED() << "Not a blockable mime type: " |
310 << resp_data.canonical_mime_type; | 257 << resp_data->canonical_mime_type; |
311 } | 258 } |
312 | 259 |
313 if (sniffed_as_target_document) { | 260 if (sniffed_as_target_document) { |
314 is_blocked = true; | 261 is_blocked = true; |
315 HistogramCountBlockedResponse(bucket_prefix, resp_data, false); | 262 HistogramCountBlockedResponse(bucket_prefix, resp_data, false); |
316 } else { | 263 } else { |
317 if (resp_data.no_sniff) { | 264 if (resp_data->no_sniff) { |
318 is_blocked = true; | 265 is_blocked = true; |
319 HistogramCountBlockedResponse(bucket_prefix, resp_data, true); | 266 HistogramCountBlockedResponse(bucket_prefix, resp_data, true); |
320 } else { | 267 } else { |
321 HistogramCountNotBlockedResponse(bucket_prefix, sniffed_as_js); | 268 HistogramCountNotBlockedResponse(bucket_prefix, sniffed_as_js); |
322 } | 269 } |
323 } | 270 } |
324 } else { | 271 } else { |
325 // This block is for plain text documents. We apply our HTML, XML, | 272 // This block is for plain text documents. We apply our HTML, XML, |
326 // and JSON sniffer to a text document in the order, and block it | 273 // and JSON sniffer to a text document in the order, and block it |
327 // if any of them succeeds in sniffing. | 274 // if any of them succeeds in sniffing. |
328 std::string bucket_prefix; | 275 std::string bucket_prefix; |
329 if (SniffForHTML(data)) | 276 if (SniffForHTML(data)) |
330 bucket_prefix = "SiteIsolation.XSD.Plain.HTML"; | 277 bucket_prefix = "SiteIsolation.XSD.Plain.HTML"; |
331 else if (SniffForXML(data)) | 278 else if (SniffForXML(data)) |
332 bucket_prefix = "SiteIsolation.XSD.Plain.XML"; | 279 bucket_prefix = "SiteIsolation.XSD.Plain.XML"; |
333 else if (SniffForJSON(data)) | 280 else if (SniffForJSON(data)) |
334 bucket_prefix = "SiteIsolation.XSD.Plain.JSON"; | 281 bucket_prefix = "SiteIsolation.XSD.Plain.JSON"; |
335 | 282 |
336 if (bucket_prefix.size() > 0) { | 283 if (bucket_prefix.size() > 0) { |
337 is_blocked = true; | 284 is_blocked = true; |
338 HistogramCountBlockedResponse(bucket_prefix, resp_data, false); | 285 HistogramCountBlockedResponse(bucket_prefix, resp_data, false); |
339 } else if (resp_data.no_sniff) { | 286 } else if (resp_data->no_sniff) { |
340 is_blocked = true; | 287 is_blocked = true; |
341 HistogramCountBlockedResponse("SiteIsolation.XSD.Plain", resp_data, true); | 288 HistogramCountBlockedResponse("SiteIsolation.XSD.Plain", resp_data, true); |
342 } else { | 289 } else { |
343 HistogramCountNotBlockedResponse("SiteIsolation.XSD.Plain", | 290 HistogramCountNotBlockedResponse("SiteIsolation.XSD.Plain", |
344 sniffed_as_js); | 291 sniffed_as_js); |
345 } | 292 } |
346 } | 293 } |
347 | 294 |
348 if (!CommandLine::ForCurrentProcess()->HasSwitch( | 295 if (!CommandLine::ForCurrentProcess()->HasSwitch( |
349 switches::kBlockCrossSiteDocuments)) | 296 switches::kBlockCrossSiteDocuments)) |
350 is_blocked = false; | 297 is_blocked = false; |
351 result_map[request_id] = is_blocked; | |
352 | 298 |
353 if (is_blocked) { | 299 if (is_blocked) { |
354 alternative_data->erase(); | 300 alternative_data->erase(); |
355 alternative_data->insert(0, " "); | 301 alternative_data->insert(0, " "); |
356 LOG(ERROR) << resp_data.response_url | 302 LOG(ERROR) << resp_data->response_url |
357 << " is blocked as an illegal cross-site document from " | 303 << " is blocked as an illegal cross-site document from " |
358 << resp_data.frame_origin; | 304 << resp_data->frame_origin; |
359 } | 305 } |
360 return is_blocked; | 306 return is_blocked; |
361 } | 307 } |
362 | 308 |
363 void SiteIsolationPolicy::OnRequestComplete(int request_id) { | 309 SiteIsolationResponseMetaData::CanonicalMimeType |
364 if (!g_policy_enabled) | |
365 return; | |
366 g_metadata_map.Get().erase(request_id); | |
367 g_result_map.Get().erase(request_id); | |
368 } | |
369 | |
370 SiteIsolationPolicy::ResponseMetaData::CanonicalMimeType | |
371 SiteIsolationPolicy::GetCanonicalMimeType(const std::string& mime_type) { | 310 SiteIsolationPolicy::GetCanonicalMimeType(const std::string& mime_type) { |
372 if (LowerCaseEqualsASCII(mime_type, kTextHtml)) { | 311 if (LowerCaseEqualsASCII(mime_type, kTextHtml)) { |
373 return SiteIsolationPolicy::ResponseMetaData::HTML; | 312 return SiteIsolationResponseMetaData::HTML; |
374 } | 313 } |
375 | 314 |
376 if (LowerCaseEqualsASCII(mime_type, kTextPlain)) { | 315 if (LowerCaseEqualsASCII(mime_type, kTextPlain)) { |
377 return SiteIsolationPolicy::ResponseMetaData::Plain; | 316 return SiteIsolationResponseMetaData::Plain; |
378 } | 317 } |
379 | 318 |
380 if (LowerCaseEqualsASCII(mime_type, kAppJson) || | 319 if (LowerCaseEqualsASCII(mime_type, kAppJson) || |
381 LowerCaseEqualsASCII(mime_type, kTextJson) || | 320 LowerCaseEqualsASCII(mime_type, kTextJson) || |
382 LowerCaseEqualsASCII(mime_type, kTextXjson)) { | 321 LowerCaseEqualsASCII(mime_type, kTextXjson)) { |
383 return SiteIsolationPolicy::ResponseMetaData::JSON; | 322 return SiteIsolationResponseMetaData::JSON; |
384 } | 323 } |
385 | 324 |
386 if (LowerCaseEqualsASCII(mime_type, kTextXml) || | 325 if (LowerCaseEqualsASCII(mime_type, kTextXml) || |
387 LowerCaseEqualsASCII(mime_type, xAppRssXml) || | 326 LowerCaseEqualsASCII(mime_type, xAppRssXml) || |
388 LowerCaseEqualsASCII(mime_type, kAppXml)) { | 327 LowerCaseEqualsASCII(mime_type, kAppXml)) { |
389 return SiteIsolationPolicy::ResponseMetaData::XML; | 328 return SiteIsolationResponseMetaData::XML; |
390 } | 329 } |
391 | 330 |
392 return SiteIsolationPolicy::ResponseMetaData::Others; | 331 return SiteIsolationResponseMetaData::Others; |
393 } | 332 } |
394 | 333 |
395 bool SiteIsolationPolicy::IsBlockableScheme(const GURL& url) { | 334 bool SiteIsolationPolicy::IsBlockableScheme(const GURL& url) { |
396 // We exclude ftp:// from here. FTP doesn't provide a Content-Type | 335 // We exclude ftp:// from here. FTP doesn't provide a Content-Type |
397 // header which our policy depends on, so we cannot protect any | 336 // header which our policy depends on, so we cannot protect any |
398 // document from FTP servers. | 337 // document from FTP servers. |
399 return url.SchemeIs("http") || url.SchemeIs("https"); | 338 return url.SchemeIs("http") || url.SchemeIs("https"); |
400 } | 339 } |
401 | 340 |
402 bool SiteIsolationPolicy::IsSameSite(const GURL& frame_origin, | 341 bool SiteIsolationPolicy::IsSameSite(const GURL& frame_origin, |
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
567 // TODO(dsjang): This is a real hack. The only purpose of this function is to | 506 // TODO(dsjang): This is a real hack. The only purpose of this function is to |
568 // try to see if there's any possibility that this data can be JavaScript | 507 // try to see if there's any possibility that this data can be JavaScript |
569 // (superset of JS). This function will be removed once UMA stats are | 508 // (superset of JS). This function will be removed once UMA stats are |
570 // gathered. | 509 // gathered. |
571 | 510 |
572 // Search for "var " for JS detection. | 511 // Search for "var " for JS detection. |
573 return data.find("var ") != base::StringPiece::npos; | 512 return data.find("var ") != base::StringPiece::npos; |
574 } | 513 } |
575 | 514 |
576 } // namespace content | 515 } // namespace content |
OLD | NEW |