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 |