| 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 |