Chromium Code Reviews| 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 11 matching lines...) Expand all Loading... | |
| 22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
| 23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | 23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
| 24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
| 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 27 */ | 27 */ |
| 28 | 28 |
| 29 #include "core/loader/MixedContentChecker.h" | 29 #include "core/loader/MixedContentChecker.h" |
| 30 | 30 |
| 31 #include "core/dom/Document.h" | 31 #include "core/dom/Document.h" |
| 32 #include "core/frame/Frame.h" | |
| 32 #include "core/frame/LocalFrame.h" | 33 #include "core/frame/LocalFrame.h" |
| 33 #include "core/frame/Settings.h" | 34 #include "core/frame/Settings.h" |
| 34 #include "core/frame/UseCounter.h" | 35 #include "core/frame/UseCounter.h" |
| 35 #include "core/inspector/ConsoleMessage.h" | 36 #include "core/inspector/ConsoleMessage.h" |
| 36 #include "core/loader/DocumentLoader.h" | 37 #include "core/loader/DocumentLoader.h" |
| 37 #include "core/loader/FrameLoader.h" | 38 #include "core/loader/FrameLoader.h" |
| 38 #include "core/loader/FrameLoaderClient.h" | 39 #include "core/loader/FrameLoaderClient.h" |
| 39 #include "platform/RuntimeEnabledFeatures.h" | 40 #include "platform/RuntimeEnabledFeatures.h" |
| 40 #include "platform/weborigin/SchemeRegistry.h" | 41 #include "platform/weborigin/SchemeRegistry.h" |
| 41 #include "platform/weborigin/SecurityOrigin.h" | 42 #include "platform/weborigin/SecurityOrigin.h" |
| 42 #include "public/platform/Platform.h" | 43 #include "public/platform/Platform.h" |
| 43 #include "wtf/text/StringBuilder.h" | 44 #include "wtf/text/StringBuilder.h" |
| 44 | 45 |
| 45 namespace blink { | 46 namespace blink { |
| 46 | 47 |
| 47 static void measureStricterVersionOfIsMixedContent(LocalFrame* frame, const KURL & url) | 48 namespace { |
| 49 | |
| 50 KURL mainResourceUrlForConsoleLog(Frame* frame) | |
|
alexmos
2016/01/11 22:02:24
nit: comment explaining the need for this function
alexmos
2016/01/11 22:02:24
nit: no need for indent.
estark
2016/01/14 23:05:48
Hm, `git cl format` seems to undo it if I make tha
estark
2016/01/14 23:05:48
Done.
alexmos
2016/01/16 00:49:49
That's interesting/weird. The Blink coding style
estark
2016/01/20 05:56:22
Oh ok, good to know! Done.
| |
| 51 { | |
| 52 if (!frame->isLocalFrame()) | |
|
alexmos
2016/01/11 22:02:24
nit: frame->isRemoteFrame()
estark
2016/01/14 23:05:48
Done.
| |
| 53 return KURL(KURL(), frame->securityContext()->securityOrigin()->toSt ring()); | |
| 54 return toLocalFrame(frame)->document()->url(); | |
| 55 } | |
| 56 | |
| 57 } // namespace | |
| 58 | |
| 59 static void measureStricterVersionOfIsMixedContent(Frame* frame, const KURL& url ) | |
| 48 { | 60 { |
| 49 // We're currently only checking for mixed content in `https://*` contexts. | 61 // We're currently only checking for mixed content in `https://*` contexts. |
| 50 // What about other "secure" contexts the SchemeRegistry knows about? We'll | 62 // What about other "secure" contexts the SchemeRegistry knows about? We'll |
| 51 // use this method to measure the occurance of non-webby mixed content to | 63 // use this method to measure the occurance of non-webby mixed content to |
| 52 // make sure we're not breaking the world without realizing it. | 64 // make sure we're not breaking the world without realizing it. |
| 53 SecurityOrigin* origin = frame->document()->securityOrigin(); | 65 SecurityOrigin* origin = frame->securityContext()->securityOrigin(); |
| 54 if (MixedContentChecker::isMixedContent(origin, url)) { | 66 if (MixedContentChecker::isMixedContent(origin, url)) { |
| 55 if (frame->document()->securityOrigin()->protocol() != "https") | 67 if (origin->protocol() != "https") |
| 56 UseCounter::count(frame, UseCounter::MixedContentInNonHTTPSFrameThat RestrictsMixedContent); | 68 UseCounter::count(frame, UseCounter::MixedContentInNonHTTPSFrameThat RestrictsMixedContent); |
| 57 } else if (!SecurityOrigin::isSecure(url) && SchemeRegistry::shouldTreatURLS chemeAsSecure(origin->protocol())) { | 69 } else if (!SecurityOrigin::isSecure(url) && SchemeRegistry::shouldTreatURLS chemeAsSecure(origin->protocol())) { |
| 58 UseCounter::count(frame, UseCounter::MixedContentInSecureFrameThatDoesNo tRestrictMixedContent); | 70 UseCounter::count(frame, UseCounter::MixedContentInSecureFrameThatDoesNo tRestrictMixedContent); |
| 59 } | 71 } |
| 60 } | 72 } |
| 61 | 73 |
| 62 bool requestIsSubframeSubresource(LocalFrame* frame, WebURLRequest::FrameType fr ameType) | 74 bool requestIsSubframeSubresource(Frame* frame, WebURLRequest::FrameType frameTy pe) |
| 63 { | 75 { |
| 64 return (frame && frame != frame->tree().top() && frameType != WebURLRequest: :FrameTypeNested); | 76 return (frame && frame != frame->tree().top() && frameType != WebURLRequest: :FrameTypeNested); |
| 65 } | 77 } |
| 66 | 78 |
| 67 // static | 79 // static |
| 68 bool MixedContentChecker::isMixedContent(SecurityOrigin* securityOrigin, const K URL& url) | 80 bool MixedContentChecker::isMixedContent(SecurityOrigin* securityOrigin, const K URL& url) |
|
alexmos
2016/01/11 22:02:24
This is used in DOMWindow::postMessage, which has
estark
2016/01/14 23:05:48
To me it looks like everything should be fine ther
alexmos
2016/01/16 00:49:49
Yes, let's remove it.
estark
2016/01/20 05:56:22
Done.
| |
| 69 { | 81 { |
| 70 if (!SchemeRegistry::shouldTreatURLSchemeAsRestrictingMixedContent(securityO rigin->protocol())) | 82 if (!SchemeRegistry::shouldTreatURLSchemeAsRestrictingMixedContent(securityO rigin->protocol())) |
| 71 return false; | 83 return false; |
| 72 | 84 |
| 73 // We're in a secure context, so |url| is mixed content if it's insecure. | 85 // We're in a secure context, so |url| is mixed content if it's insecure. |
| 74 return !SecurityOrigin::isSecure(url); | 86 return !SecurityOrigin::isSecure(url); |
| 75 } | 87 } |
| 76 | 88 |
| 77 // static | 89 // static |
| 78 LocalFrame* MixedContentChecker::inWhichFrameIsContentMixed(LocalFrame* frame, W ebURLRequest::FrameType frameType, const KURL& url) | 90 Frame* MixedContentChecker::inWhichFrameIsContentMixed(Frame* frame, WebURLReque st::FrameType frameType, const KURL& url) |
| 79 { | 91 { |
| 80 // We only care about subresource loads; top-level navigations cannot be mix ed content. Neither can frameless requests. | 92 // We only care about subresource loads; top-level navigations cannot be mix ed content. Neither can frameless requests. |
| 81 if (frameType == WebURLRequest::FrameTypeTopLevel || !frame) | 93 if (frameType == WebURLRequest::FrameTypeTopLevel || !frame) |
| 82 return nullptr; | 94 return nullptr; |
| 83 | 95 |
| 84 // Check the top frame first. | 96 // Check the top frame first. |
| 85 if (Frame* top = frame->tree().top()) { | 97 if (Frame* top = frame->tree().top()) { |
| 86 // FIXME: We need a way to access the top-level frame's SecurityOrigin w hen that frame | 98 measureStricterVersionOfIsMixedContent(top, url); |
| 87 // is in a different process from the current frame. Until that is done, we bail out. | 99 if (isMixedContent(top->securityContext()->securityOrigin(), url)) |
| 88 if (!top->isLocalFrame()) | 100 return top; |
| 89 return nullptr; | |
| 90 | |
| 91 LocalFrame* localTop = toLocalFrame(top); | |
| 92 measureStricterVersionOfIsMixedContent(localTop, url); | |
| 93 if (isMixedContent(localTop->document()->securityOrigin(), url)) | |
| 94 return localTop; | |
| 95 } | 101 } |
| 96 | 102 |
| 97 measureStricterVersionOfIsMixedContent(frame, url); | 103 measureStricterVersionOfIsMixedContent(frame, url); |
| 98 if (isMixedContent(frame->document()->securityOrigin(), url)) | 104 if (isMixedContent(frame->securityContext()->securityOrigin(), url)) |
| 99 return frame; | 105 return frame; |
| 100 | 106 |
| 101 // No mixed content, no problem. | 107 // No mixed content, no problem. |
| 102 return nullptr; | 108 return nullptr; |
| 103 } | 109 } |
| 104 | 110 |
| 105 // static | 111 // static |
| 106 MixedContentChecker::ContextType MixedContentChecker::contextTypeFromContext(Web URLRequest::RequestContext context, LocalFrame* frame) | 112 MixedContentChecker::ContextType MixedContentChecker::contextTypeFromContext(Web URLRequest::RequestContext context, Frame* frame) |
| 107 { | 113 { |
| 108 switch (context) { | 114 switch (context) { |
| 109 // "Optionally-blockable" mixed content | 115 // "Optionally-blockable" mixed content |
| 110 case WebURLRequest::RequestContextAudio: | 116 case WebURLRequest::RequestContextAudio: |
| 111 case WebURLRequest::RequestContextFavicon: | 117 case WebURLRequest::RequestContextFavicon: |
| 112 case WebURLRequest::RequestContextImage: | 118 case WebURLRequest::RequestContextImage: |
| 113 case WebURLRequest::RequestContextVideo: | 119 case WebURLRequest::RequestContextVideo: |
| 114 return ContextTypeOptionallyBlockable; | 120 return ContextTypeOptionallyBlockable; |
| 115 | 121 |
| 116 // Plugins! Oh how dearly we love plugin-loaded content! | 122 // Plugins! Oh how dearly we love plugin-loaded content! |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 231 case WebURLRequest::RequestContextXMLHttpRequest: | 237 case WebURLRequest::RequestContextXMLHttpRequest: |
| 232 return "XMLHttpRequest endpoint"; | 238 return "XMLHttpRequest endpoint"; |
| 233 case WebURLRequest::RequestContextXSLT: | 239 case WebURLRequest::RequestContextXSLT: |
| 234 return "XSLT"; | 240 return "XSLT"; |
| 235 } | 241 } |
| 236 ASSERT_NOT_REACHED(); | 242 ASSERT_NOT_REACHED(); |
| 237 return "resource"; | 243 return "resource"; |
| 238 } | 244 } |
| 239 | 245 |
| 240 // static | 246 // static |
| 241 void MixedContentChecker::logToConsoleAboutFetch(LocalFrame* frame, const KURL& url, WebURLRequest::RequestContext requestContext, bool allowed) | 247 void MixedContentChecker::logToConsoleAboutFetch(LocalFrame* frame, const KURL& mainResourceUrl, const KURL& url, WebURLRequest::RequestContext requestContext, bool allowed) |
| 242 { | 248 { |
| 243 String message = String::format( | 249 String message = String::format( |
| 244 "Mixed Content: The page at '%s' was loaded over HTTPS, but requested an insecure %s '%s'. %s", | 250 "Mixed Content: The page at '%s' was loaded over HTTPS, but requested an insecure %s '%s'. %s", |
| 245 frame->document()->url().elidedString().utf8().data(), typeNameFromConte xt(requestContext), url.elidedString().utf8().data(), | 251 mainResourceUrl.elidedString().utf8().data(), typeNameFromContext(reques tContext), url.elidedString().utf8().data(), |
| 246 allowed ? "This content should also be served over HTTPS." : "This reque st has been blocked; the content must be served over HTTPS."); | 252 allowed ? "This content should also be served over HTTPS." : "This reque st has been blocked; the content must be served over HTTPS."); |
| 247 MessageLevel messageLevel = allowed ? WarningMessageLevel : ErrorMessageLeve l; | 253 MessageLevel messageLevel = allowed ? WarningMessageLevel : ErrorMessageLeve l; |
| 248 frame->document()->addConsoleMessage(ConsoleMessage::create(SecurityMessageS ource, messageLevel, message)); | 254 frame->document()->addConsoleMessage(ConsoleMessage::create(SecurityMessageS ource, messageLevel, message)); |
| 249 } | 255 } |
| 250 | 256 |
| 251 // static | 257 // static |
| 252 void MixedContentChecker::count(LocalFrame* frame, WebURLRequest::RequestContext requestContext) | 258 void MixedContentChecker::count(Frame* frame, WebURLRequest::RequestContext requ estContext) |
| 253 { | 259 { |
| 254 UseCounter::count(frame, UseCounter::MixedContentPresent); | 260 UseCounter::count(frame, UseCounter::MixedContentPresent); |
| 255 | 261 |
| 256 // Roll blockable content up into a single counter, count unblocked types in dividually so we | 262 // Roll blockable content up into a single counter, count unblocked types in dividually so we |
| 257 // can determine when they can be safely moved to the blockable category: | 263 // can determine when they can be safely moved to the blockable category: |
| 258 ContextType contextType = contextTypeFromContext(requestContext, frame); | 264 ContextType contextType = contextTypeFromContext(requestContext, frame); |
| 259 if (contextType == ContextTypeBlockable) { | 265 if (contextType == ContextTypeBlockable) { |
| 260 UseCounter::count(frame, UseCounter::MixedContentBlockable); | 266 UseCounter::count(frame, UseCounter::MixedContentBlockable); |
| 261 return; | 267 return; |
| 262 } | 268 } |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 291 default: | 297 default: |
| 292 ASSERT_NOT_REACHED(); | 298 ASSERT_NOT_REACHED(); |
| 293 return; | 299 return; |
| 294 } | 300 } |
| 295 UseCounter::count(frame, feature); | 301 UseCounter::count(frame, feature); |
| 296 } | 302 } |
| 297 | 303 |
| 298 // static | 304 // static |
| 299 bool MixedContentChecker::shouldBlockFetch(LocalFrame* frame, WebURLRequest::Req uestContext requestContext, WebURLRequest::FrameType frameType, const KURL& url, MixedContentChecker::ReportingStatus reportingStatus) | 305 bool MixedContentChecker::shouldBlockFetch(LocalFrame* frame, WebURLRequest::Req uestContext requestContext, WebURLRequest::FrameType frameType, const KURL& url, MixedContentChecker::ReportingStatus reportingStatus) |
| 300 { | 306 { |
| 301 LocalFrame* mixedFrame = inWhichFrameIsContentMixed(frame, frameType, url); | 307 Frame* effectiveFrame = effectiveFrameForFrameType(frame, frameType); |
|
alexmos
2016/01/11 22:02:24
Do you know why this didn't call effectiveFrameFor
estark
2016/01/14 23:05:48
The callsite (in FrameFetchContext.cpp) used to ca
alexmos
2016/01/16 00:49:50
Ah yes, for FrameFetchContext that makes sense, bu
estark
2016/01/20 05:56:22
Ahh, I missed that one, thanks. (I think it should
alexmos
2016/01/20 22:43:55
Sounds good.
| |
| 308 Frame* mixedFrame = inWhichFrameIsContentMixed(effectiveFrame, frameType, ur l); | |
| 302 if (!mixedFrame) | 309 if (!mixedFrame) |
| 303 return false; | 310 return false; |
| 304 | 311 |
| 305 MixedContentChecker::count(mixedFrame, requestContext); | 312 MixedContentChecker::count(mixedFrame, requestContext); |
| 306 | 313 |
| 307 Settings* settings = mixedFrame->settings(); | 314 Settings* settings = mixedFrame->settings(); |
| 315 // Use the current local frame's client; the embedder doesn't | |
| 316 // distinguish mixed content signals from different frames on the | |
| 317 // same page. | |
| 308 FrameLoaderClient* client = frame->loader().client(); | 318 FrameLoaderClient* client = frame->loader().client(); |
| 309 SecurityOrigin* securityOrigin = mixedFrame->document()->securityOrigin(); | 319 SecurityOrigin* securityOrigin = mixedFrame->securityContext()->securityOrig in(); |
| 310 bool allowed = false; | 320 bool allowed = false; |
| 311 | 321 |
| 312 // If we're in strict mode, we'll automagically fail everything, and intenti onally skip | 322 // If we're in strict mode, we'll automagically fail everything, and intenti onally skip |
| 313 // the client checks in order to prevent degrading the site's security UI. | 323 // the client checks in order to prevent degrading the site's security UI. |
| 314 bool strictMode = mixedFrame->securityContext()->shouldEnforceStrictMixedCon tentChecking() || settings->strictMixedContentChecking(); | 324 bool strictMode = mixedFrame->securityContext()->shouldEnforceStrictMixedCon tentChecking() || settings->strictMixedContentChecking(); |
| 315 | 325 |
| 316 ContextType contextType = contextTypeFromContext(requestContext, mixedFrame) ; | 326 ContextType contextType = contextTypeFromContext(requestContext, mixedFrame) ; |
| 317 | 327 |
| 318 // If we're loading the main resource of a subframe, we need to take a close look at the loaded URL. | 328 // If we're loading the main resource of a subframe, we need to take a close look at the loaded URL. |
| 319 // If we're dealing with a CORS-enabled scheme, then block mixed frames as a ctive content. Otherwise, | 329 // If we're dealing with a CORS-enabled scheme, then block mixed frames as a ctive content. Otherwise, |
| 320 // treat frames as passive content. | 330 // treat frames as passive content. |
| 321 // | 331 // |
| 322 // FIXME: Remove this temporary hack once we have a reasonable API for launc hing external applications | 332 // FIXME: Remove this temporary hack once we have a reasonable API for launc hing external applications |
| 323 // via URLs. http://crbug.com/318788 and https://crbug.com/393481 | 333 // via URLs. http://crbug.com/318788 and https://crbug.com/393481 |
| 324 if (frameType == WebURLRequest::FrameTypeNested && !SchemeRegistry::shouldTr eatURLSchemeAsCORSEnabled(url.protocol())) | 334 if (frameType == WebURLRequest::FrameTypeNested && !SchemeRegistry::shouldTr eatURLSchemeAsCORSEnabled(url.protocol())) |
| 325 contextType = ContextTypeOptionallyBlockable; | 335 contextType = ContextTypeOptionallyBlockable; |
| 326 | 336 |
| 327 switch (contextType) { | 337 switch (contextType) { |
| 328 case ContextTypeOptionallyBlockable: | 338 case ContextTypeOptionallyBlockable: |
| 329 if (!strictMode) | 339 if (!strictMode) |
| 330 mixedFrame->client()->triedDisplayingInsecureContent(securityOrigin, url); | 340 mixedFrame->client()->triedDisplayingInsecureContent(securityOrigin, url); |
| 331 allowed = !strictMode && client->allowDisplayingInsecureContent(settings && settings->allowDisplayOfInsecureContent(), securityOrigin, url); | 341 allowed = !strictMode && client->allowDisplayingInsecureContent(settings && settings->allowDisplayOfInsecureContent(), securityOrigin, url); |
| 332 if (allowed) | 342 if (allowed) |
| 333 client->didDisplayInsecureContent(); | 343 client->didDisplayInsecureContent(); |
| 334 break; | 344 break; |
| 335 | 345 |
| 336 case ContextTypeBlockable: { | 346 case ContextTypeBlockable: { |
| 337 // Strictly block subresources in subframes, unless all insecure | 347 // Strictly block subresources in subframes, unless all insecure |
| 338 // content is allowed. | 348 // content is allowed. |
| 339 if (!settings->allowRunningOfInsecureContent() && requestIsSubframeSubre source(frame, frameType)) { | 349 if (!settings->allowRunningOfInsecureContent() && requestIsSubframeSubre source(effectiveFrame, frameType)) { |
| 340 UseCounter::count(mixedFrame, UseCounter::BlockableMixedContentInSub frameBlocked); | 350 UseCounter::count(mixedFrame, UseCounter::BlockableMixedContentInSub frameBlocked); |
| 341 allowed = false; | 351 allowed = false; |
| 342 break; | 352 break; |
| 343 } | 353 } |
| 344 | 354 |
| 345 bool shouldAskEmbedder = !strictMode && settings && (!settings->strictly BlockBlockableMixedContent() || settings->allowRunningOfInsecureContent()); | 355 bool shouldAskEmbedder = !strictMode && settings && (!settings->strictly BlockBlockableMixedContent() || settings->allowRunningOfInsecureContent()); |
| 346 if (shouldAskEmbedder) | 356 if (shouldAskEmbedder) |
| 347 mixedFrame->client()->triedRunningInsecureContent(securityOrigin, ur l); | 357 mixedFrame->client()->triedRunningInsecureContent(securityOrigin, ur l); |
| 348 allowed = shouldAskEmbedder && client->allowRunningInsecureContent(setti ngs && settings->allowRunningOfInsecureContent(), securityOrigin, url); | 358 allowed = shouldAskEmbedder && client->allowRunningInsecureContent(setti ngs && settings->allowRunningOfInsecureContent(), securityOrigin, url); |
| 349 if (allowed) { | 359 if (allowed) { |
| 350 client->didRunInsecureContent(securityOrigin, url); | 360 client->didRunInsecureContent(securityOrigin, url); |
| 351 UseCounter::count(mixedFrame, UseCounter::MixedContentBlockableAllow ed); | 361 UseCounter::count(mixedFrame, UseCounter::MixedContentBlockableAllow ed); |
| 352 } | 362 } |
| 353 break; | 363 break; |
| 354 } | 364 } |
| 355 | 365 |
| 356 case ContextTypeShouldBeBlockable: | 366 case ContextTypeShouldBeBlockable: |
| 357 allowed = !strictMode; | 367 allowed = !strictMode; |
| 358 if (allowed) | 368 if (allowed) |
| 359 client->didDisplayInsecureContent(); | 369 client->didDisplayInsecureContent(); |
| 360 break; | 370 break; |
| 361 case ContextTypeNotMixedContent: | 371 case ContextTypeNotMixedContent: |
| 362 ASSERT_NOT_REACHED(); | 372 ASSERT_NOT_REACHED(); |
| 363 break; | 373 break; |
| 364 }; | 374 }; |
| 365 | 375 |
| 366 if (reportingStatus == SendReport) | 376 if (reportingStatus == SendReport) |
| 367 logToConsoleAboutFetch(frame, url, requestContext, allowed); | 377 logToConsoleAboutFetch(effectiveFrame->isLocalFrame() ? toLocalFrame(eff ectiveFrame) : frame, mainResourceUrlForConsoleLog(mixedFrame), url, requestCont ext, allowed); |
|
alexmos
2016/01/11 22:02:24
This feels a bit weird, in that the sometimes the
estark
2016/01/14 23:05:48
I suppose always using |frame| makes sense, but it
alexmos
2016/01/16 00:49:49
Ah, I see. It would be nice if the test expectati
estark
2016/01/20 05:56:22
Ok, yeah, I agree that it would be nice if the tes
alexmos
2016/01/20 22:43:55
Acknowledged.
| |
| 368 return !allowed; | 378 return !allowed; |
| 369 } | 379 } |
| 370 | 380 |
| 371 // static | 381 // static |
| 372 void MixedContentChecker::logToConsoleAboutWebSocket(LocalFrame* frame, const KU RL& url, bool allowed) | 382 void MixedContentChecker::logToConsoleAboutWebSocket(LocalFrame* frame, const KU RL& mainResourceUrl, const KURL& url, bool allowed) |
| 373 { | 383 { |
| 374 String message = String::format( | 384 String message = String::format( |
| 375 "Mixed Content: The page at '%s' was loaded over HTTPS, but attempted to connect to the insecure WebSocket endpoint '%s'. %s", | 385 "Mixed Content: The page at '%s' was loaded over HTTPS, but attempted to connect to the insecure WebSocket endpoint '%s'. %s", |
| 376 frame->document()->url().elidedString().utf8().data(), url.elidedString( ).utf8().data(), | 386 mainResourceUrl.elidedString().utf8().data(), url.elidedString().utf8(). data(), |
| 377 allowed ? "This endpoint should be available via WSS. Insecure access is deprecated." : "This request has been blocked; this endpoint must be available over WSS."); | 387 allowed ? "This endpoint should be available via WSS. Insecure access is deprecated." : "This request has been blocked; this endpoint must be available over WSS."); |
| 378 MessageLevel messageLevel = allowed ? WarningMessageLevel : ErrorMessageLeve l; | 388 MessageLevel messageLevel = allowed ? WarningMessageLevel : ErrorMessageLeve l; |
| 379 frame->document()->addConsoleMessage(ConsoleMessage::create(SecurityMessageS ource, messageLevel, message)); | 389 frame->document()->addConsoleMessage(ConsoleMessage::create(SecurityMessageS ource, messageLevel, message)); |
| 380 } | 390 } |
| 381 | 391 |
| 382 // static | 392 // static |
| 383 bool MixedContentChecker::shouldBlockWebSocket(LocalFrame* frame, const KURL& ur l, MixedContentChecker::ReportingStatus reportingStatus) | 393 bool MixedContentChecker::shouldBlockWebSocket(LocalFrame* frame, const KURL& ur l, MixedContentChecker::ReportingStatus reportingStatus) |
| 384 { | 394 { |
| 385 LocalFrame* mixedFrame = inWhichFrameIsContentMixed(frame, WebURLRequest::Fr ameTypeNone, url); | 395 Frame* mixedFrame = inWhichFrameIsContentMixed(frame, WebURLRequest::FrameTy peNone, url); |
| 386 if (!mixedFrame) | 396 if (!mixedFrame) |
| 387 return false; | 397 return false; |
| 388 | 398 |
| 389 UseCounter::count(mixedFrame, UseCounter::MixedContentPresent); | 399 UseCounter::count(mixedFrame, UseCounter::MixedContentPresent); |
| 390 UseCounter::count(mixedFrame, UseCounter::MixedContentWebSocket); | 400 UseCounter::count(mixedFrame, UseCounter::MixedContentWebSocket); |
| 391 | 401 |
| 392 Settings* settings = mixedFrame->settings(); | 402 Settings* settings = mixedFrame->settings(); |
| 393 FrameLoaderClient* client = mixedFrame->loader().client(); | 403 FrameLoaderClient* client = frame->loader().client(); |
| 394 SecurityOrigin* securityOrigin = mixedFrame->document()->securityOrigin(); | 404 SecurityOrigin* securityOrigin = mixedFrame->securityContext()->securityOrig in(); |
| 395 bool allowed = false; | 405 bool allowed = false; |
| 396 | 406 |
| 397 // If we're in strict mode, we'll automagically fail everything, and intenti onally skip | 407 // If we're in strict mode, we'll automagically fail everything, and intenti onally skip |
| 398 // the client checks in order to prevent degrading the site's security UI. | 408 // the client checks in order to prevent degrading the site's security UI. |
| 399 bool strictMode = mixedFrame->document()->shouldEnforceStrictMixedContentChe cking() || settings->strictMixedContentChecking(); | 409 bool strictMode = mixedFrame->securityContext()->shouldEnforceStrictMixedCon tentChecking() || settings->strictMixedContentChecking(); |
| 400 if (!strictMode) { | 410 if (!strictMode) { |
| 401 bool allowedPerSettings = settings && settings->allowRunningOfInsecureCo ntent(); | 411 bool allowedPerSettings = settings && settings->allowRunningOfInsecureCo ntent(); |
| 402 mixedFrame->client()->triedRunningInsecureContent(securityOrigin, url); | 412 mixedFrame->client()->triedRunningInsecureContent(securityOrigin, url); |
| 403 allowed = client->allowRunningInsecureContent(allowedPerSettings, securi tyOrigin, url); | 413 allowed = client->allowRunningInsecureContent(allowedPerSettings, securi tyOrigin, url); |
| 404 } | 414 } |
| 405 | 415 |
| 406 if (allowed) | 416 if (allowed) |
| 407 client->didRunInsecureContent(securityOrigin, url); | 417 client->didRunInsecureContent(securityOrigin, url); |
| 408 | 418 |
| 409 if (reportingStatus == SendReport) | 419 if (reportingStatus == SendReport) |
| 410 logToConsoleAboutWebSocket(frame, url, allowed); | 420 logToConsoleAboutWebSocket(frame, mainResourceUrlForConsoleLog(mixedFram e), url, allowed); |
| 411 return !allowed; | 421 return !allowed; |
| 412 } | 422 } |
| 413 | 423 |
| 414 bool MixedContentChecker::isMixedFormAction(LocalFrame* frame, const KURL& url, ReportingStatus reportingStatus) | 424 bool MixedContentChecker::isMixedFormAction(LocalFrame* frame, const KURL& url, ReportingStatus reportingStatus) |
| 415 { | 425 { |
| 416 // For whatever reason, some folks handle forms via JavaScript, and submit t o `javascript:void(0)` | 426 // For whatever reason, some folks handle forms via JavaScript, and submit t o `javascript:void(0)` |
| 417 // rather than calling `preventDefault()`. We special-case `javascript:` URL s here, as they don't | 427 // rather than calling `preventDefault()`. We special-case `javascript:` URL s here, as they don't |
| 418 // introduce MixedContent for form submissions. | 428 // introduce MixedContent for form submissions. |
| 419 if (url.protocolIs("javascript")) | 429 if (url.protocolIs("javascript")) |
| 420 return false; | 430 return false; |
| 421 | 431 |
| 422 LocalFrame* mixedFrame = inWhichFrameIsContentMixed(frame, WebURLRequest::Fr ameTypeNone, url); | 432 Frame* mixedFrame = inWhichFrameIsContentMixed(frame, WebURLRequest::FrameTy peNone, url); |
| 423 if (!mixedFrame) | 433 if (!mixedFrame) |
| 424 return false; | 434 return false; |
| 425 | 435 |
| 426 UseCounter::count(mixedFrame, UseCounter::MixedContentPresent); | 436 UseCounter::count(mixedFrame, UseCounter::MixedContentPresent); |
| 427 | 437 |
| 428 mixedFrame->loader().client()->didDisplayInsecureContent(); | 438 frame->loader().client()->didDisplayInsecureContent(); |
| 429 | 439 |
| 430 if (reportingStatus == SendReport) { | 440 if (reportingStatus == SendReport) { |
| 431 String message = String::format( | 441 String message = String::format( |
| 432 "Mixed Content: The page at '%s' was loaded over a secure connection , but contains a form which targets an insecure endpoint '%s'. This endpoint sho uld be made available over a secure connection.", | 442 "Mixed Content: The page at '%s' was loaded over a secure connection , but contains a form which targets an insecure endpoint '%s'. This endpoint sho uld be made available over a secure connection.", |
| 433 frame->document()->url().elidedString().utf8().data(), url.elidedStr ing().utf8().data()); | 443 mainResourceUrlForConsoleLog(mixedFrame).elidedString().utf8().data( ), url.elidedString().utf8().data()); |
| 434 mixedFrame->document()->addConsoleMessage(ConsoleMessage::create(Securit yMessageSource, WarningMessageLevel, message)); | 444 frame->document()->addConsoleMessage(ConsoleMessage::create(SecurityMess ageSource, WarningMessageLevel, message)); |
| 435 } | 445 } |
| 436 | 446 |
| 437 return true; | 447 return true; |
| 438 } | 448 } |
| 439 | 449 |
| 440 void MixedContentChecker::checkMixedPrivatePublic(LocalFrame* frame, const Atomi cString& resourceIPAddress) | 450 void MixedContentChecker::checkMixedPrivatePublic(LocalFrame* frame, const Atomi cString& resourceIPAddress) |
| 441 { | 451 { |
| 442 if (!frame || !frame->document() || !frame->document()->loader()) | 452 if (!frame || !frame->document() || !frame->document()->loader()) |
| 443 return; | 453 return; |
| 444 | 454 |
| 445 // Just count these for the moment, don't block them. | 455 // Just count these for the moment, don't block them. |
| 446 if (Platform::current()->isReservedIPAddress(resourceIPAddress) && !frame->d ocument()->isHostedInReservedIPRange()) | 456 if (Platform::current()->isReservedIPAddress(resourceIPAddress) && !frame->d ocument()->isHostedInReservedIPRange()) |
| 447 UseCounter::count(frame->document(), UseCounter::MixedContentPrivateHost nameInPublicHostname); | 457 UseCounter::count(frame->document(), UseCounter::MixedContentPrivateHost nameInPublicHostname); |
| 448 } | 458 } |
| 449 | 459 |
| 450 LocalFrame* MixedContentChecker::effectiveFrameForFrameType(LocalFrame* frame, W ebURLRequest::FrameType frameType) | 460 Frame* MixedContentChecker::effectiveFrameForFrameType(LocalFrame* frame, WebURL Request::FrameType frameType) |
| 451 { | 461 { |
| 452 // If we're loading the main resource of a subframe, ensure that we check | 462 // If we're loading the main resource of a subframe, ensure that we check |
| 453 // against the parent of the active frame, rather than the frame itself. | 463 // against the parent of the active frame, rather than the frame itself. |
| 454 LocalFrame* effectiveFrame = frame; | 464 if (frameType != WebURLRequest::FrameTypeNested) |
| 455 if (frameType == WebURLRequest::FrameTypeNested) { | 465 return frame; |
| 456 // FIXME: Deal with RemoteFrames. | 466 |
| 457 Frame* parentFrame = effectiveFrame->tree().parent(); | 467 Frame* parentFrame = frame->tree().parent(); |
| 458 ASSERT(parentFrame); | 468 ASSERT(parentFrame); |
| 459 if (parentFrame->isLocalFrame()) | 469 return parentFrame; |
| 460 effectiveFrame = toLocalFrame(parentFrame); | |
| 461 } | |
| 462 return effectiveFrame; | |
| 463 } | 470 } |
| 464 | 471 |
| 465 void MixedContentChecker::handleCertificateError(LocalFrame* frame, const Resour ceRequest& request, const ResourceResponse& response) | 472 void MixedContentChecker::handleCertificateError(LocalFrame* frame, const Resour ceRequest& request, const ResourceResponse& response) |
| 466 { | 473 { |
| 467 WebURLRequest::FrameType frameType = request.frameType(); | 474 WebURLRequest::FrameType frameType = request.frameType(); |
| 468 LocalFrame* effectiveFrame = effectiveFrameForFrameType(frame, frameType); | 475 Frame* effectiveFrame = effectiveFrameForFrameType(frame, frameType); |
| 469 if (frameType == WebURLRequest::FrameTypeTopLevel || !effectiveFrame) | 476 if (frameType == WebURLRequest::FrameTypeTopLevel || !effectiveFrame) |
| 470 return; | 477 return; |
| 471 | 478 |
| 472 FrameLoaderClient* client = effectiveFrame->loader().client(); | 479 // TODO(estark): handle remote frames, perhaps by omitting security info whe n the effective frame is remote. |
| 480 if (!effectiveFrame->isLocalFrame()) | |
| 481 return; | |
| 482 | |
| 483 LocalFrame* localEffectiveFrame = toLocalFrame(effectiveFrame); | |
| 484 | |
| 485 FrameLoaderClient* client = frame->loader().client(); | |
|
alexmos
2016/01/11 22:02:24
nit: comment about why this changed from effective
estark
2016/01/14 23:05:48
Done.
| |
| 473 WebURLRequest::RequestContext requestContext = request.requestContext(); | 486 WebURLRequest::RequestContext requestContext = request.requestContext(); |
| 474 ContextType contextType = MixedContentChecker::contextTypeFromContext(reques tContext, frame); | 487 ContextType contextType = MixedContentChecker::contextTypeFromContext(reques tContext, effectiveFrame); |
| 475 if (contextType == ContextTypeBlockable) { | 488 if (contextType == ContextTypeBlockable) { |
| 476 client->didRunContentWithCertificateErrors(response.url(), response.getS ecurityInfo(), effectiveFrame->document()->url(), effectiveFrame->loader().docum entLoader()->response().getSecurityInfo()); | 489 client->didRunContentWithCertificateErrors(response.url(), response.getS ecurityInfo(), KURL(KURL(), effectiveFrame->securityContext()->securityOrigin()- >toString()), localEffectiveFrame->loader().documentLoader()->response().getSecu rityInfo()); |
|
alexmos
2016/01/11 22:02:24
Is it possible to reuse mainResourceUrlForConsoleL
estark
2016/01/14 23:05:48
Done.
| |
| 477 } else { | 490 } else { |
| 478 // contextTypeFromContext() never returns NotMixedContent (it | 491 // contextTypeFromContext() never returns NotMixedContent (it |
| 479 // computes the type of mixed content, given that the content is | 492 // computes the type of mixed content, given that the content is |
| 480 // mixed). | 493 // mixed). |
| 481 ASSERT(contextType != ContextTypeNotMixedContent); | 494 ASSERT(contextType != ContextTypeNotMixedContent); |
| 482 client->didDisplayContentWithCertificateErrors(response.url(), response. getSecurityInfo(), effectiveFrame->document()->url(), effectiveFrame->loader().d ocumentLoader()->response().getSecurityInfo()); | 495 client->didDisplayContentWithCertificateErrors(response.url(), response. getSecurityInfo(), KURL(KURL(), effectiveFrame->securityContext()->securityOrigi n()->toString()), localEffectiveFrame->loader().documentLoader()->response().get SecurityInfo()); |
|
alexmos
2016/01/11 22:02:24
Ditto
estark
2016/01/14 23:05:48
Done.
| |
| 483 } | 496 } |
| 484 } | 497 } |
| 485 | 498 |
| 486 MixedContentChecker::ContextType MixedContentChecker::contextTypeForInspector(Lo calFrame* frame, const ResourceRequest& request) | 499 MixedContentChecker::ContextType MixedContentChecker::contextTypeForInspector(Lo calFrame* frame, const ResourceRequest& request) |
| 487 { | 500 { |
| 488 LocalFrame* effectiveFrame = effectiveFrameForFrameType(frame, request.frame Type()); | 501 Frame* effectiveFrame = effectiveFrameForFrameType(frame, request.frameType( )); |
| 489 | 502 |
| 490 LocalFrame* mixedFrame = inWhichFrameIsContentMixed(effectiveFrame, request. frameType(), request.url()); | 503 Frame* mixedFrame = inWhichFrameIsContentMixed(effectiveFrame, request.frame Type(), request.url()); |
| 491 if (!mixedFrame) | 504 if (!mixedFrame) |
| 492 return ContextTypeNotMixedContent; | 505 return ContextTypeNotMixedContent; |
| 493 | 506 |
| 494 // See comment in shouldBlockFetch() about loading the main resource of a su bframe. | 507 // See comment in shouldBlockFetch() about loading the main resource of a su bframe. |
| 495 if (request.frameType() == WebURLRequest::FrameTypeNested && !SchemeRegistry ::shouldTreatURLSchemeAsCORSEnabled(request.url().protocol())) { | 508 if (request.frameType() == WebURLRequest::FrameTypeNested && !SchemeRegistry ::shouldTreatURLSchemeAsCORSEnabled(request.url().protocol())) { |
| 496 return ContextTypeOptionallyBlockable; | 509 return ContextTypeOptionallyBlockable; |
| 497 } | 510 } |
| 498 | 511 |
| 499 return contextTypeFromContext(request.requestContext(), mixedFrame); | 512 return contextTypeFromContext(request.requestContext(), mixedFrame); |
| 500 } | 513 } |
| 501 | 514 |
| 502 } // namespace blink | 515 } // namespace blink |
| OLD | NEW |