OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2012 Google Inc. All rights reserved. | 2 * Copyright (C) 2012 Google Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
6 * are met: | 6 * are met: |
7 * | 7 * |
8 * 1. Redistributions of source code must retain the above copyright | 8 * 1. Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * 2. Redistributions in binary form must reproduce the above copyright | 10 * 2. Redistributions in binary form must reproduce the above copyright |
(...skipping 25 matching lines...) Expand all Loading... |
36 #include "core/inspector/ConsoleMessage.h" | 36 #include "core/inspector/ConsoleMessage.h" |
37 #include "core/loader/DocumentLoader.h" | 37 #include "core/loader/DocumentLoader.h" |
38 #include "core/loader/FrameLoader.h" | 38 #include "core/loader/FrameLoader.h" |
39 #include "core/loader/FrameLoaderClient.h" | 39 #include "core/loader/FrameLoaderClient.h" |
40 #include "platform/RuntimeEnabledFeatures.h" | 40 #include "platform/RuntimeEnabledFeatures.h" |
41 #include "platform/network/NetworkUtils.h" | 41 #include "platform/network/NetworkUtils.h" |
42 #include "platform/weborigin/SchemeRegistry.h" | 42 #include "platform/weborigin/SchemeRegistry.h" |
43 #include "platform/weborigin/SecurityOrigin.h" | 43 #include "platform/weborigin/SecurityOrigin.h" |
44 #include "public/platform/WebAddressSpace.h" | 44 #include "public/platform/WebAddressSpace.h" |
45 #include "public/platform/WebInsecureRequestPolicy.h" | 45 #include "public/platform/WebInsecureRequestPolicy.h" |
| 46 #include "public/platform/WebMixedContent.h" |
46 #include "wtf/text/StringBuilder.h" | 47 #include "wtf/text/StringBuilder.h" |
47 | 48 |
48 namespace blink { | 49 namespace blink { |
49 | 50 |
50 namespace { | 51 namespace { |
51 | 52 |
52 // When a frame is local, use its full URL to represent the main resource. When | 53 // When a frame is local, use its full URL to represent the main resource. When |
53 // the frame is remote, the full URL isn't accessible, so use the origin. This | 54 // the frame is remote, the full URL isn't accessible, so use the origin. This |
54 // function is used, for example, to determine the URL to show in console | 55 // function is used, for example, to determine the URL to show in console |
55 // messages about mixed content. | 56 // messages about mixed content. |
56 KURL mainResourceUrlForFrame(Frame* frame) { | 57 KURL mainResourceUrlForFrame(Frame* frame) { |
57 if (frame->isRemoteFrame()) { | 58 if (frame->isRemoteFrame()) { |
58 return KURL(KURL(), | 59 return KURL(KURL(), |
59 frame->securityContext()->getSecurityOrigin()->toString()); | 60 frame->securityContext()->getSecurityOrigin()->toString()); |
60 } | 61 } |
61 return toLocalFrame(frame)->document()->url(); | 62 return toLocalFrame(frame)->document()->url(); |
62 } | 63 } |
63 | 64 |
| 65 const char* requestContextName(WebURLRequest::RequestContext context) { |
| 66 switch (context) { |
| 67 case WebURLRequest::RequestContextAudio: |
| 68 return "audio file"; |
| 69 case WebURLRequest::RequestContextBeacon: |
| 70 return "Beacon endpoint"; |
| 71 case WebURLRequest::RequestContextCSPReport: |
| 72 return "Content Security Policy reporting endpoint"; |
| 73 case WebURLRequest::RequestContextDownload: |
| 74 return "download"; |
| 75 case WebURLRequest::RequestContextEmbed: |
| 76 return "plugin resource"; |
| 77 case WebURLRequest::RequestContextEventSource: |
| 78 return "EventSource endpoint"; |
| 79 case WebURLRequest::RequestContextFavicon: |
| 80 return "favicon"; |
| 81 case WebURLRequest::RequestContextFetch: |
| 82 return "resource"; |
| 83 case WebURLRequest::RequestContextFont: |
| 84 return "font"; |
| 85 case WebURLRequest::RequestContextForm: |
| 86 return "form action"; |
| 87 case WebURLRequest::RequestContextFrame: |
| 88 return "frame"; |
| 89 case WebURLRequest::RequestContextHyperlink: |
| 90 return "resource"; |
| 91 case WebURLRequest::RequestContextIframe: |
| 92 return "frame"; |
| 93 case WebURLRequest::RequestContextImage: |
| 94 return "image"; |
| 95 case WebURLRequest::RequestContextImageSet: |
| 96 return "image"; |
| 97 case WebURLRequest::RequestContextImport: |
| 98 return "HTML Import"; |
| 99 case WebURLRequest::RequestContextInternal: |
| 100 return "resource"; |
| 101 case WebURLRequest::RequestContextLocation: |
| 102 return "resource"; |
| 103 case WebURLRequest::RequestContextManifest: |
| 104 return "manifest"; |
| 105 case WebURLRequest::RequestContextObject: |
| 106 return "plugin resource"; |
| 107 case WebURLRequest::RequestContextPing: |
| 108 return "hyperlink auditing endpoint"; |
| 109 case WebURLRequest::RequestContextPlugin: |
| 110 return "plugin data"; |
| 111 case WebURLRequest::RequestContextPrefetch: |
| 112 return "prefetch resource"; |
| 113 case WebURLRequest::RequestContextScript: |
| 114 return "script"; |
| 115 case WebURLRequest::RequestContextServiceWorker: |
| 116 return "Service Worker script"; |
| 117 case WebURLRequest::RequestContextSharedWorker: |
| 118 return "Shared Worker script"; |
| 119 case WebURLRequest::RequestContextStyle: |
| 120 return "stylesheet"; |
| 121 case WebURLRequest::RequestContextSubresource: |
| 122 return "resource"; |
| 123 case WebURLRequest::RequestContextTrack: |
| 124 return "Text Track"; |
| 125 case WebURLRequest::RequestContextUnspecified: |
| 126 return "resource"; |
| 127 case WebURLRequest::RequestContextVideo: |
| 128 return "video"; |
| 129 case WebURLRequest::RequestContextWorker: |
| 130 return "Worker script"; |
| 131 case WebURLRequest::RequestContextXMLHttpRequest: |
| 132 return "XMLHttpRequest endpoint"; |
| 133 case WebURLRequest::RequestContextXSLT: |
| 134 return "XSLT"; |
| 135 } |
| 136 NOTREACHED(); |
| 137 return "resource"; |
| 138 } |
| 139 |
64 } // namespace | 140 } // namespace |
65 | 141 |
66 static void measureStricterVersionOfIsMixedContent(Frame* frame, | 142 static void measureStricterVersionOfIsMixedContent(Frame* frame, |
67 const KURL& url) { | 143 const KURL& url) { |
68 // We're currently only checking for mixed content in `https://*` contexts. | 144 // We're currently only checking for mixed content in `https://*` contexts. |
69 // What about other "secure" contexts the SchemeRegistry knows about? We'll | 145 // What about other "secure" contexts the SchemeRegistry knows about? We'll |
70 // use this method to measure the occurance of non-webby mixed content to make | 146 // use this method to measure the occurance of non-webby mixed content to make |
71 // sure we're not breaking the world without realizing it. | 147 // sure we're not breaking the world without realizing it. |
72 SecurityOrigin* origin = frame->securityContext()->getSecurityOrigin(); | 148 SecurityOrigin* origin = frame->securityContext()->getSecurityOrigin(); |
73 if (MixedContentChecker::isMixedContent(origin, url)) { | 149 if (MixedContentChecker::isMixedContent(origin, url)) { |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
143 void MixedContentChecker::logToConsoleAboutFetch( | 219 void MixedContentChecker::logToConsoleAboutFetch( |
144 LocalFrame* frame, | 220 LocalFrame* frame, |
145 const KURL& mainResourceUrl, | 221 const KURL& mainResourceUrl, |
146 const KURL& url, | 222 const KURL& url, |
147 WebURLRequest::RequestContext requestContext, | 223 WebURLRequest::RequestContext requestContext, |
148 bool allowed) { | 224 bool allowed) { |
149 String message = String::format( | 225 String message = String::format( |
150 "Mixed Content: The page at '%s' was loaded over HTTPS, but requested an " | 226 "Mixed Content: The page at '%s' was loaded over HTTPS, but requested an " |
151 "insecure %s '%s'. %s", | 227 "insecure %s '%s'. %s", |
152 mainResourceUrl.elidedString().utf8().data(), | 228 mainResourceUrl.elidedString().utf8().data(), |
153 WebMixedContent::requestContextName(requestContext), | 229 requestContextName(requestContext), url.elidedString().utf8().data(), |
154 url.elidedString().utf8().data(), | |
155 allowed ? "This content should also be served over HTTPS." | 230 allowed ? "This content should also be served over HTTPS." |
156 : "This request has been blocked; the content must be served " | 231 : "This request has been blocked; the content must be served " |
157 "over HTTPS."); | 232 "over HTTPS."); |
158 MessageLevel messageLevel = allowed ? WarningMessageLevel : ErrorMessageLevel; | 233 MessageLevel messageLevel = allowed ? WarningMessageLevel : ErrorMessageLevel; |
159 frame->document()->addConsoleMessage( | 234 frame->document()->addConsoleMessage( |
160 ConsoleMessage::create(SecurityMessageSource, messageLevel, message)); | 235 ConsoleMessage::create(SecurityMessageSource, messageLevel, message)); |
161 } | 236 } |
162 | 237 |
163 // static | 238 // static |
164 void MixedContentChecker::count(Frame* frame, | 239 void MixedContentChecker::count(Frame* frame, |
165 WebURLRequest::RequestContext requestContext) { | 240 WebURLRequest::RequestContext requestContext) { |
166 UseCounter::count(frame, UseCounter::MixedContentPresent); | 241 UseCounter::count(frame, UseCounter::MixedContentPresent); |
167 | 242 |
168 // Roll blockable content up into a single counter, count unblocked types | 243 // Roll blockable content up into a single counter, count unblocked types |
169 // individually so we can determine when they can be safely moved to the | 244 // individually so we can determine when they can be safely moved to the |
170 // blockable category: | 245 // blockable category: |
171 WebMixedContent::ContextType contextType = | 246 WebMixedContentContextType contextType = |
172 WebMixedContent::contextTypeFromRequestContext( | 247 WebMixedContent::contextTypeFromRequestContext( |
173 requestContext, | 248 requestContext, |
174 frame->settings()->getStrictMixedContentCheckingForPlugin()); | 249 frame->settings()->getStrictMixedContentCheckingForPlugin()); |
175 if (contextType == WebMixedContent::ContextType::Blockable) { | 250 if (contextType == WebMixedContentContextType::Blockable) { |
176 UseCounter::count(frame, UseCounter::MixedContentBlockable); | 251 UseCounter::count(frame, UseCounter::MixedContentBlockable); |
177 return; | 252 return; |
178 } | 253 } |
179 | 254 |
180 UseCounter::Feature feature; | 255 UseCounter::Feature feature; |
181 switch (requestContext) { | 256 switch (requestContext) { |
182 case WebURLRequest::RequestContextAudio: | 257 case WebURLRequest::RequestContextAudio: |
183 feature = UseCounter::MixedContentAudio; | 258 feature = UseCounter::MixedContentAudio; |
184 break; | 259 break; |
185 case WebURLRequest::RequestContextDownload: | 260 case WebURLRequest::RequestContextDownload: |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
238 mixedFrame->securityContext()->getSecurityOrigin(); | 313 mixedFrame->securityContext()->getSecurityOrigin(); |
239 bool allowed = false; | 314 bool allowed = false; |
240 | 315 |
241 // If we're in strict mode, we'll automagically fail everything, and | 316 // If we're in strict mode, we'll automagically fail everything, and |
242 // intentionally skip the client checks in order to prevent degrading the | 317 // intentionally skip the client checks in order to prevent degrading the |
243 // site's security UI. | 318 // site's security UI. |
244 bool strictMode = mixedFrame->securityContext()->getInsecureRequestPolicy() & | 319 bool strictMode = mixedFrame->securityContext()->getInsecureRequestPolicy() & |
245 kBlockAllMixedContent || | 320 kBlockAllMixedContent || |
246 settings->getStrictMixedContentChecking(); | 321 settings->getStrictMixedContentChecking(); |
247 | 322 |
248 WebMixedContent::ContextType contextType = | 323 WebMixedContentContextType contextType = |
249 WebMixedContent::contextTypeFromRequestContext( | 324 WebMixedContent::contextTypeFromRequestContext( |
250 requestContext, settings->getStrictMixedContentCheckingForPlugin()); | 325 requestContext, settings->getStrictMixedContentCheckingForPlugin()); |
251 | 326 |
252 // If we're loading the main resource of a subframe, we need to take a close | 327 // If we're loading the main resource of a subframe, we need to take a close |
253 // look at the loaded URL. If we're dealing with a CORS-enabled scheme, then | 328 // look at the loaded URL. If we're dealing with a CORS-enabled scheme, then |
254 // block mixed frames as active content. Otherwise, treat frames as passive | 329 // block mixed frames as active content. Otherwise, treat frames as passive |
255 // content. | 330 // content. |
256 // | 331 // |
257 // FIXME: Remove this temporary hack once we have a reasonable API for | 332 // FIXME: Remove this temporary hack once we have a reasonable API for |
258 // launching external applications via URLs. http://crbug.com/318788 and | 333 // launching external applications via URLs. http://crbug.com/318788 and |
259 // https://crbug.com/393481 | 334 // https://crbug.com/393481 |
260 if (frameType == WebURLRequest::FrameTypeNested && | 335 if (frameType == WebURLRequest::FrameTypeNested && |
261 !SchemeRegistry::shouldTreatURLSchemeAsCORSEnabled(url.protocol())) | 336 !SchemeRegistry::shouldTreatURLSchemeAsCORSEnabled(url.protocol())) |
262 contextType = WebMixedContent::ContextType::OptionallyBlockable; | 337 contextType = WebMixedContentContextType::OptionallyBlockable; |
263 | 338 |
264 switch (contextType) { | 339 switch (contextType) { |
265 case WebMixedContent::ContextType::OptionallyBlockable: | 340 case WebMixedContentContextType::OptionallyBlockable: |
266 allowed = !strictMode; | 341 allowed = !strictMode; |
267 if (allowed) { | 342 if (allowed) { |
268 client->passiveInsecureContentFound(url); | 343 client->passiveInsecureContentFound(url); |
269 client->didDisplayInsecureContent(); | 344 client->didDisplayInsecureContent(); |
270 } | 345 } |
271 break; | 346 break; |
272 | 347 |
273 case WebMixedContent::ContextType::Blockable: { | 348 case WebMixedContentContextType::Blockable: { |
274 // Strictly block subresources that are mixed with respect to their | 349 // Strictly block subresources that are mixed with respect to their |
275 // subframes, unless all insecure content is allowed. This is to avoid the | 350 // subframes, unless all insecure content is allowed. This is to avoid the |
276 // following situation: https://a.com embeds https://b.com, which loads a | 351 // following situation: https://a.com embeds https://b.com, which loads a |
277 // script over insecure HTTP. The user opts to allow the insecure content, | 352 // script over insecure HTTP. The user opts to allow the insecure content, |
278 // thinking that they are allowing an insecure script to run on | 353 // thinking that they are allowing an insecure script to run on |
279 // https://a.com and not realizing that they are in fact allowing an | 354 // https://a.com and not realizing that they are in fact allowing an |
280 // insecure script on https://b.com. | 355 // insecure script on https://b.com. |
281 if (!settings->getAllowRunningOfInsecureContent() && | 356 if (!settings->getAllowRunningOfInsecureContent() && |
282 requestIsSubframeSubresource(effectiveFrame, frameType) && | 357 requestIsSubframeSubresource(effectiveFrame, frameType) && |
283 isMixedContent(frame->securityContext()->getSecurityOrigin(), url)) { | 358 isMixedContent(frame->securityContext()->getSecurityOrigin(), url)) { |
(...skipping 11 matching lines...) Expand all Loading... |
295 client->allowRunningInsecureContent( | 370 client->allowRunningInsecureContent( |
296 settings && settings->getAllowRunningOfInsecureContent(), | 371 settings && settings->getAllowRunningOfInsecureContent(), |
297 securityOrigin, url); | 372 securityOrigin, url); |
298 if (allowed) { | 373 if (allowed) { |
299 client->didRunInsecureContent(securityOrigin, url); | 374 client->didRunInsecureContent(securityOrigin, url); |
300 UseCounter::count(mixedFrame, UseCounter::MixedContentBlockableAllowed); | 375 UseCounter::count(mixedFrame, UseCounter::MixedContentBlockableAllowed); |
301 } | 376 } |
302 break; | 377 break; |
303 } | 378 } |
304 | 379 |
305 case WebMixedContent::ContextType::ShouldBeBlockable: | 380 case WebMixedContentContextType::ShouldBeBlockable: |
306 allowed = !strictMode; | 381 allowed = !strictMode; |
307 if (allowed) | 382 if (allowed) |
308 client->didDisplayInsecureContent(); | 383 client->didDisplayInsecureContent(); |
309 break; | 384 break; |
310 case WebMixedContent::ContextType::NotMixedContent: | 385 case WebMixedContentContextType::NotMixedContent: |
311 NOTREACHED(); | 386 NOTREACHED(); |
312 break; | 387 break; |
313 }; | 388 }; |
314 | 389 |
315 if (reportingStatus == SendReport) { | 390 if (reportingStatus == SendReport) { |
316 logToConsoleAboutFetch(frame, mainResourceUrlForFrame(mixedFrame), url, | 391 logToConsoleAboutFetch(frame, mainResourceUrlForFrame(mixedFrame), url, |
317 requestContext, allowed); | 392 requestContext, allowed); |
318 } | 393 } |
319 return !allowed; | 394 return !allowed; |
320 } | 395 } |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
468 Frame* effectiveFrame = effectiveFrameForFrameType(frame, frameType); | 543 Frame* effectiveFrame = effectiveFrameForFrameType(frame, frameType); |
469 if (frameType == WebURLRequest::FrameTypeTopLevel || !effectiveFrame) | 544 if (frameType == WebURLRequest::FrameTypeTopLevel || !effectiveFrame) |
470 return; | 545 return; |
471 | 546 |
472 // Use the current local frame's client; the embedder doesn't distinguish | 547 // Use the current local frame's client; the embedder doesn't distinguish |
473 // mixed content signals from different frames on the same page. | 548 // mixed content signals from different frames on the same page. |
474 FrameLoaderClient* client = frame->loader().client(); | 549 FrameLoaderClient* client = frame->loader().client(); |
475 bool strictMixedContentCheckingForPlugin = | 550 bool strictMixedContentCheckingForPlugin = |
476 effectiveFrame->settings() && | 551 effectiveFrame->settings() && |
477 effectiveFrame->settings()->getStrictMixedContentCheckingForPlugin(); | 552 effectiveFrame->settings()->getStrictMixedContentCheckingForPlugin(); |
478 WebMixedContent::ContextType contextType = | 553 WebMixedContentContextType contextType = |
479 WebMixedContent::contextTypeFromRequestContext( | 554 WebMixedContent::contextTypeFromRequestContext( |
480 requestContext, strictMixedContentCheckingForPlugin); | 555 requestContext, strictMixedContentCheckingForPlugin); |
481 if (contextType == WebMixedContent::ContextType::Blockable) { | 556 if (contextType == WebMixedContentContextType::Blockable) { |
482 client->didRunContentWithCertificateErrors(response.url()); | 557 client->didRunContentWithCertificateErrors(response.url()); |
483 } else { | 558 } else { |
484 // contextTypeFromRequestContext() never returns NotMixedContent (it | 559 // contextTypeFromRequestContext() never returns NotMixedContent (it |
485 // computes the type of mixed content, given that the content is mixed). | 560 // computes the type of mixed content, given that the content is mixed). |
486 DCHECK_NE(contextType, WebMixedContent::ContextType::NotMixedContent); | 561 DCHECK_NE(contextType, WebMixedContentContextType::NotMixedContent); |
487 client->didDisplayContentWithCertificateErrors(response.url()); | 562 client->didDisplayContentWithCertificateErrors(response.url()); |
488 } | 563 } |
489 } | 564 } |
490 | 565 |
491 WebMixedContent::ContextType MixedContentChecker::contextTypeForInspector( | 566 WebMixedContentContextType MixedContentChecker::contextTypeForInspector( |
492 LocalFrame* frame, | 567 LocalFrame* frame, |
493 const ResourceRequest& request) { | 568 const ResourceRequest& request) { |
494 Frame* effectiveFrame = | 569 Frame* effectiveFrame = |
495 effectiveFrameForFrameType(frame, request.frameType()); | 570 effectiveFrameForFrameType(frame, request.frameType()); |
496 | 571 |
497 Frame* mixedFrame = inWhichFrameIsContentMixed( | 572 Frame* mixedFrame = inWhichFrameIsContentMixed( |
498 effectiveFrame, request.frameType(), request.url()); | 573 effectiveFrame, request.frameType(), request.url()); |
499 if (!mixedFrame) | 574 if (!mixedFrame) |
500 return WebMixedContent::ContextType::NotMixedContent; | 575 return WebMixedContentContextType::NotMixedContent; |
501 | 576 |
502 // See comment in shouldBlockFetch() about loading the main resource of a | 577 // See comment in shouldBlockFetch() about loading the main resource of a |
503 // subframe. | 578 // subframe. |
504 if (request.frameType() == WebURLRequest::FrameTypeNested && | 579 if (request.frameType() == WebURLRequest::FrameTypeNested && |
505 !SchemeRegistry::shouldTreatURLSchemeAsCORSEnabled( | 580 !SchemeRegistry::shouldTreatURLSchemeAsCORSEnabled( |
506 request.url().protocol())) { | 581 request.url().protocol())) { |
507 return WebMixedContent::ContextType::OptionallyBlockable; | 582 return WebMixedContentContextType::OptionallyBlockable; |
508 } | 583 } |
509 | 584 |
510 bool strictMixedContentCheckingForPlugin = | 585 bool strictMixedContentCheckingForPlugin = |
511 mixedFrame->settings() && | 586 mixedFrame->settings() && |
512 mixedFrame->settings()->getStrictMixedContentCheckingForPlugin(); | 587 mixedFrame->settings()->getStrictMixedContentCheckingForPlugin(); |
513 return WebMixedContent::contextTypeFromRequestContext( | 588 return WebMixedContent::contextTypeFromRequestContext( |
514 request.requestContext(), strictMixedContentCheckingForPlugin); | 589 request.requestContext(), strictMixedContentCheckingForPlugin); |
515 } | 590 } |
516 | 591 |
517 } // namespace blink | 592 } // namespace blink |
OLD | NEW |