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 // When a frame is local, use its full URL to represent the main |
| 51 // resource. When the frame is remote, the full URL isn't accessible, so |
| 52 // use the origin. This function is used, for example, to determine the |
| 53 // URL to show in console messages about mixed content. |
| 54 KURL mainResourceUrlForFrame(Frame* frame) |
| 55 { |
| 56 if (frame->isRemoteFrame()) |
| 57 return KURL(KURL(), frame->securityContext()->securityOrigin()->toString
()); |
| 58 return toLocalFrame(frame)->document()->url(); |
| 59 } |
| 60 |
| 61 } // namespace |
| 62 |
| 63 static void measureStricterVersionOfIsMixedContent(Frame* frame, const KURL& url
) |
48 { | 64 { |
49 // We're currently only checking for mixed content in `https://*` contexts. | 65 // We're currently only checking for mixed content in `https://*` contexts. |
50 // What about other "secure" contexts the SchemeRegistry knows about? We'll | 66 // 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 | 67 // 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. | 68 // make sure we're not breaking the world without realizing it. |
53 SecurityOrigin* origin = frame->document()->securityOrigin(); | 69 SecurityOrigin* origin = frame->securityContext()->securityOrigin(); |
54 if (MixedContentChecker::isMixedContent(origin, url)) { | 70 if (MixedContentChecker::isMixedContent(origin, url)) { |
55 if (frame->document()->securityOrigin()->protocol() != "https") | 71 if (origin->protocol() != "https") |
56 UseCounter::count(frame, UseCounter::MixedContentInNonHTTPSFrameThat
RestrictsMixedContent); | 72 UseCounter::count(frame, UseCounter::MixedContentInNonHTTPSFrameThat
RestrictsMixedContent); |
57 } else if (!SecurityOrigin::isSecure(url) && SchemeRegistry::shouldTreatURLS
chemeAsSecure(origin->protocol())) { | 73 } else if (!SecurityOrigin::isSecure(url) && SchemeRegistry::shouldTreatURLS
chemeAsSecure(origin->protocol())) { |
58 UseCounter::count(frame, UseCounter::MixedContentInSecureFrameThatDoesNo
tRestrictMixedContent); | 74 UseCounter::count(frame, UseCounter::MixedContentInSecureFrameThatDoesNo
tRestrictMixedContent); |
59 } | 75 } |
60 } | 76 } |
61 | 77 |
62 bool requestIsSubframeSubresource(LocalFrame* frame, WebURLRequest::FrameType fr
ameType) | 78 bool requestIsSubframeSubresource(Frame* frame, WebURLRequest::FrameType frameTy
pe) |
63 { | 79 { |
64 return (frame && frame != frame->tree().top() && frameType != WebURLRequest:
:FrameTypeNested); | 80 return (frame && frame != frame->tree().top() && frameType != WebURLRequest:
:FrameTypeNested); |
65 } | 81 } |
66 | 82 |
67 // static | 83 // static |
68 bool MixedContentChecker::isMixedContent(SecurityOrigin* securityOrigin, const K
URL& url) | 84 bool MixedContentChecker::isMixedContent(SecurityOrigin* securityOrigin, const K
URL& url) |
69 { | 85 { |
70 if (!SchemeRegistry::shouldTreatURLSchemeAsRestrictingMixedContent(securityO
rigin->protocol())) | 86 if (!SchemeRegistry::shouldTreatURLSchemeAsRestrictingMixedContent(securityO
rigin->protocol())) |
71 return false; | 87 return false; |
72 | 88 |
73 // We're in a secure context, so |url| is mixed content if it's insecure. | 89 // We're in a secure context, so |url| is mixed content if it's insecure. |
74 return !SecurityOrigin::isSecure(url); | 90 return !SecurityOrigin::isSecure(url); |
75 } | 91 } |
76 | 92 |
77 // static | 93 // static |
78 LocalFrame* MixedContentChecker::inWhichFrameIsContentMixed(LocalFrame* frame, W
ebURLRequest::FrameType frameType, const KURL& url) | 94 Frame* MixedContentChecker::inWhichFrameIsContentMixed(Frame* frame, WebURLReque
st::FrameType frameType, const KURL& url) |
79 { | 95 { |
80 // We only care about subresource loads; top-level navigations cannot be mix
ed content. Neither can frameless requests. | 96 // We only care about subresource loads; top-level navigations cannot be mix
ed content. Neither can frameless requests. |
81 if (frameType == WebURLRequest::FrameTypeTopLevel || !frame) | 97 if (frameType == WebURLRequest::FrameTypeTopLevel || !frame) |
82 return nullptr; | 98 return nullptr; |
83 | 99 |
84 // Check the top frame first. | 100 // Check the top frame first. |
85 if (Frame* top = frame->tree().top()) { | 101 if (Frame* top = frame->tree().top()) { |
86 // FIXME: We need a way to access the top-level frame's SecurityOrigin w
hen that frame | 102 measureStricterVersionOfIsMixedContent(top, url); |
87 // is in a different process from the current frame. Until that is done,
we bail out. | 103 if (isMixedContent(top->securityContext()->securityOrigin(), url)) |
88 if (!top->isLocalFrame()) | 104 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 } | 105 } |
96 | 106 |
97 measureStricterVersionOfIsMixedContent(frame, url); | 107 measureStricterVersionOfIsMixedContent(frame, url); |
98 if (isMixedContent(frame->document()->securityOrigin(), url)) | 108 if (isMixedContent(frame->securityContext()->securityOrigin(), url)) |
99 return frame; | 109 return frame; |
100 | 110 |
101 // No mixed content, no problem. | 111 // No mixed content, no problem. |
102 return nullptr; | 112 return nullptr; |
103 } | 113 } |
104 | 114 |
105 // static | 115 // static |
106 MixedContentChecker::ContextType MixedContentChecker::contextTypeFromContext(Web
URLRequest::RequestContext context, LocalFrame* frame) | 116 MixedContentChecker::ContextType MixedContentChecker::contextTypeFromContext(Web
URLRequest::RequestContext context, Frame* frame) |
107 { | 117 { |
108 switch (context) { | 118 switch (context) { |
109 // "Optionally-blockable" mixed content | 119 // "Optionally-blockable" mixed content |
110 case WebURLRequest::RequestContextAudio: | 120 case WebURLRequest::RequestContextAudio: |
111 case WebURLRequest::RequestContextFavicon: | 121 case WebURLRequest::RequestContextFavicon: |
112 case WebURLRequest::RequestContextImage: | 122 case WebURLRequest::RequestContextImage: |
113 case WebURLRequest::RequestContextVideo: | 123 case WebURLRequest::RequestContextVideo: |
114 return ContextTypeOptionallyBlockable; | 124 return ContextTypeOptionallyBlockable; |
115 | 125 |
116 // Plugins! Oh how dearly we love plugin-loaded content! | 126 // 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: | 241 case WebURLRequest::RequestContextXMLHttpRequest: |
232 return "XMLHttpRequest endpoint"; | 242 return "XMLHttpRequest endpoint"; |
233 case WebURLRequest::RequestContextXSLT: | 243 case WebURLRequest::RequestContextXSLT: |
234 return "XSLT"; | 244 return "XSLT"; |
235 } | 245 } |
236 ASSERT_NOT_REACHED(); | 246 ASSERT_NOT_REACHED(); |
237 return "resource"; | 247 return "resource"; |
238 } | 248 } |
239 | 249 |
240 // static | 250 // static |
241 void MixedContentChecker::logToConsoleAboutFetch(LocalFrame* frame, const KURL&
url, WebURLRequest::RequestContext requestContext, bool allowed) | 251 void MixedContentChecker::logToConsoleAboutFetch(LocalFrame* frame, const KURL&
mainResourceUrl, const KURL& url, WebURLRequest::RequestContext requestContext,
bool allowed) |
242 { | 252 { |
243 String message = String::format( | 253 String message = String::format( |
244 "Mixed Content: The page at '%s' was loaded over HTTPS, but requested an
insecure %s '%s'. %s", | 254 "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(), | 255 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."); | 256 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; | 257 MessageLevel messageLevel = allowed ? WarningMessageLevel : ErrorMessageLeve
l; |
248 frame->document()->addConsoleMessage(ConsoleMessage::create(SecurityMessageS
ource, messageLevel, message)); | 258 frame->document()->addConsoleMessage(ConsoleMessage::create(SecurityMessageS
ource, messageLevel, message)); |
249 } | 259 } |
250 | 260 |
251 // static | 261 // static |
252 void MixedContentChecker::count(LocalFrame* frame, WebURLRequest::RequestContext
requestContext) | 262 void MixedContentChecker::count(Frame* frame, WebURLRequest::RequestContext requ
estContext) |
253 { | 263 { |
254 UseCounter::count(frame, UseCounter::MixedContentPresent); | 264 UseCounter::count(frame, UseCounter::MixedContentPresent); |
255 | 265 |
256 // Roll blockable content up into a single counter, count unblocked types in
dividually so we | 266 // 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: | 267 // can determine when they can be safely moved to the blockable category: |
258 ContextType contextType = contextTypeFromContext(requestContext, frame); | 268 ContextType contextType = contextTypeFromContext(requestContext, frame); |
259 if (contextType == ContextTypeBlockable) { | 269 if (contextType == ContextTypeBlockable) { |
260 UseCounter::count(frame, UseCounter::MixedContentBlockable); | 270 UseCounter::count(frame, UseCounter::MixedContentBlockable); |
261 return; | 271 return; |
262 } | 272 } |
(...skipping 28 matching lines...) Expand all Loading... |
291 default: | 301 default: |
292 ASSERT_NOT_REACHED(); | 302 ASSERT_NOT_REACHED(); |
293 return; | 303 return; |
294 } | 304 } |
295 UseCounter::count(frame, feature); | 305 UseCounter::count(frame, feature); |
296 } | 306 } |
297 | 307 |
298 // static | 308 // static |
299 bool MixedContentChecker::shouldBlockFetch(LocalFrame* frame, WebURLRequest::Req
uestContext requestContext, WebURLRequest::FrameType frameType, const KURL& url,
MixedContentChecker::ReportingStatus reportingStatus) | 309 bool MixedContentChecker::shouldBlockFetch(LocalFrame* frame, WebURLRequest::Req
uestContext requestContext, WebURLRequest::FrameType frameType, const KURL& url,
MixedContentChecker::ReportingStatus reportingStatus) |
300 { | 310 { |
301 LocalFrame* mixedFrame = inWhichFrameIsContentMixed(frame, frameType, url); | 311 Frame* effectiveFrame = effectiveFrameForFrameType(frame, frameType); |
| 312 Frame* mixedFrame = inWhichFrameIsContentMixed(effectiveFrame, frameType, ur
l); |
302 if (!mixedFrame) | 313 if (!mixedFrame) |
303 return false; | 314 return false; |
304 | 315 |
305 MixedContentChecker::count(mixedFrame, requestContext); | 316 MixedContentChecker::count(mixedFrame, requestContext); |
306 | 317 |
307 Settings* settings = mixedFrame->settings(); | 318 Settings* settings = mixedFrame->settings(); |
308 FrameLoaderClient* client = mixedFrame->loader().client(); | 319 // Use the current local frame's client; the embedder doesn't |
309 SecurityOrigin* securityOrigin = mixedFrame->document()->securityOrigin(); | 320 // distinguish mixed content signals from different frames on the |
| 321 // same page. |
| 322 FrameLoaderClient* client = frame->loader().client(); |
| 323 SecurityOrigin* securityOrigin = mixedFrame->securityContext()->securityOrig
in(); |
310 bool allowed = false; | 324 bool allowed = false; |
311 | 325 |
312 // If we're in strict mode, we'll automagically fail everything, and intenti
onally skip | 326 // 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. | 327 // the client checks in order to prevent degrading the site's security UI. |
314 bool strictMode = mixedFrame->securityContext()->shouldEnforceStrictMixedCon
tentChecking() || settings->strictMixedContentChecking(); | 328 bool strictMode = mixedFrame->securityContext()->shouldEnforceStrictMixedCon
tentChecking() || settings->strictMixedContentChecking(); |
315 | 329 |
316 ContextType contextType = contextTypeFromContext(requestContext, mixedFrame)
; | 330 ContextType contextType = contextTypeFromContext(requestContext, mixedFrame)
; |
317 | 331 |
318 // If we're loading the main resource of a subframe, we need to take a close
look at the loaded URL. | 332 // 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, | 333 // If we're dealing with a CORS-enabled scheme, then block mixed frames as a
ctive content. Otherwise, |
320 // treat frames as passive content. | 334 // treat frames as passive content. |
321 // | 335 // |
322 // FIXME: Remove this temporary hack once we have a reasonable API for launc
hing external applications | 336 // 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 | 337 // via URLs. http://crbug.com/318788 and https://crbug.com/393481 |
324 if (frameType == WebURLRequest::FrameTypeNested && !SchemeRegistry::shouldTr
eatURLSchemeAsCORSEnabled(url.protocol())) | 338 if (frameType == WebURLRequest::FrameTypeNested && !SchemeRegistry::shouldTr
eatURLSchemeAsCORSEnabled(url.protocol())) |
325 contextType = ContextTypeOptionallyBlockable; | 339 contextType = ContextTypeOptionallyBlockable; |
326 | 340 |
327 switch (contextType) { | 341 switch (contextType) { |
328 case ContextTypeOptionallyBlockable: | 342 case ContextTypeOptionallyBlockable: |
329 allowed = !strictMode && client->allowDisplayingInsecureContent(settings
&& settings->allowDisplayOfInsecureContent(), url); | 343 allowed = !strictMode && client->allowDisplayingInsecureContent(settings
&& settings->allowDisplayOfInsecureContent(), url); |
330 if (allowed) | 344 if (allowed) |
331 client->didDisplayInsecureContent(); | 345 client->didDisplayInsecureContent(); |
332 break; | 346 break; |
333 | 347 |
334 case ContextTypeBlockable: { | 348 case ContextTypeBlockable: { |
335 // Strictly block subresources in subframes, unless all insecure | 349 // Strictly block subresources in subframes, unless all insecure |
336 // content is allowed. | 350 // content is allowed. |
337 if (!settings->allowRunningOfInsecureContent() && requestIsSubframeSubre
source(frame, frameType)) { | 351 if (!settings->allowRunningOfInsecureContent() && requestIsSubframeSubre
source(effectiveFrame, frameType)) { |
338 UseCounter::count(mixedFrame, UseCounter::BlockableMixedContentInSub
frameBlocked); | 352 UseCounter::count(mixedFrame, UseCounter::BlockableMixedContentInSub
frameBlocked); |
339 allowed = false; | 353 allowed = false; |
340 break; | 354 break; |
341 } | 355 } |
342 | 356 |
343 bool shouldAskEmbedder = !strictMode && settings && (!settings->strictly
BlockBlockableMixedContent() || settings->allowRunningOfInsecureContent()); | 357 bool shouldAskEmbedder = !strictMode && settings && (!settings->strictly
BlockBlockableMixedContent() || settings->allowRunningOfInsecureContent()); |
344 allowed = shouldAskEmbedder && client->allowRunningInsecureContent(setti
ngs && settings->allowRunningOfInsecureContent(), securityOrigin, url); | 358 allowed = shouldAskEmbedder && client->allowRunningInsecureContent(setti
ngs && settings->allowRunningOfInsecureContent(), securityOrigin, url); |
345 if (allowed) { | 359 if (allowed) { |
346 client->didRunInsecureContent(securityOrigin, url); | 360 client->didRunInsecureContent(securityOrigin, url); |
347 UseCounter::count(mixedFrame, UseCounter::MixedContentBlockableAllow
ed); | 361 UseCounter::count(mixedFrame, UseCounter::MixedContentBlockableAllow
ed); |
348 } | 362 } |
349 break; | 363 break; |
350 } | 364 } |
351 | 365 |
352 case ContextTypeShouldBeBlockable: | 366 case ContextTypeShouldBeBlockable: |
353 allowed = !strictMode; | 367 allowed = !strictMode; |
354 if (allowed) | 368 if (allowed) |
355 client->didDisplayInsecureContent(); | 369 client->didDisplayInsecureContent(); |
356 break; | 370 break; |
357 case ContextTypeNotMixedContent: | 371 case ContextTypeNotMixedContent: |
358 ASSERT_NOT_REACHED(); | 372 ASSERT_NOT_REACHED(); |
359 break; | 373 break; |
360 }; | 374 }; |
361 | 375 |
362 if (reportingStatus == SendReport) | 376 if (reportingStatus == SendReport) |
363 logToConsoleAboutFetch(frame, url, requestContext, allowed); | 377 logToConsoleAboutFetch(frame, mainResourceUrlForFrame(mixedFrame), url,
requestContext, allowed); |
364 return !allowed; | 378 return !allowed; |
365 } | 379 } |
366 | 380 |
367 // static | 381 // static |
368 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) |
369 { | 383 { |
370 String message = String::format( | 384 String message = String::format( |
371 "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", |
372 frame->document()->url().elidedString().utf8().data(), url.elidedString(
).utf8().data(), | 386 mainResourceUrl.elidedString().utf8().data(), url.elidedString().utf8().
data(), |
373 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."); |
374 MessageLevel messageLevel = allowed ? WarningMessageLevel : ErrorMessageLeve
l; | 388 MessageLevel messageLevel = allowed ? WarningMessageLevel : ErrorMessageLeve
l; |
375 frame->document()->addConsoleMessage(ConsoleMessage::create(SecurityMessageS
ource, messageLevel, message)); | 389 frame->document()->addConsoleMessage(ConsoleMessage::create(SecurityMessageS
ource, messageLevel, message)); |
376 } | 390 } |
377 | 391 |
378 // static | 392 // static |
379 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) |
380 { | 394 { |
381 LocalFrame* mixedFrame = inWhichFrameIsContentMixed(frame, WebURLRequest::Fr
ameTypeNone, url); | 395 Frame* mixedFrame = inWhichFrameIsContentMixed(frame, WebURLRequest::FrameTy
peNone, url); |
382 if (!mixedFrame) | 396 if (!mixedFrame) |
383 return false; | 397 return false; |
384 | 398 |
385 UseCounter::count(mixedFrame, UseCounter::MixedContentPresent); | 399 UseCounter::count(mixedFrame, UseCounter::MixedContentPresent); |
386 UseCounter::count(mixedFrame, UseCounter::MixedContentWebSocket); | 400 UseCounter::count(mixedFrame, UseCounter::MixedContentWebSocket); |
387 | 401 |
388 Settings* settings = mixedFrame->settings(); | 402 Settings* settings = mixedFrame->settings(); |
389 FrameLoaderClient* client = mixedFrame->loader().client(); | 403 // Use the current local frame's client; the embedder doesn't |
390 SecurityOrigin* securityOrigin = mixedFrame->document()->securityOrigin(); | 404 // distinguish mixed content signals from different frames on the |
| 405 // same page. |
| 406 FrameLoaderClient* client = frame->loader().client(); |
| 407 SecurityOrigin* securityOrigin = mixedFrame->securityContext()->securityOrig
in(); |
391 bool allowed = false; | 408 bool allowed = false; |
392 | 409 |
393 // If we're in strict mode, we'll automagically fail everything, and intenti
onally skip | 410 // If we're in strict mode, we'll automagically fail everything, and intenti
onally skip |
394 // the client checks in order to prevent degrading the site's security UI. | 411 // the client checks in order to prevent degrading the site's security UI. |
395 bool strictMode = mixedFrame->document()->shouldEnforceStrictMixedContentChe
cking() || settings->strictMixedContentChecking(); | 412 bool strictMode = mixedFrame->securityContext()->shouldEnforceStrictMixedCon
tentChecking() || settings->strictMixedContentChecking(); |
396 if (!strictMode) { | 413 if (!strictMode) { |
397 bool allowedPerSettings = settings && settings->allowRunningOfInsecureCo
ntent(); | 414 bool allowedPerSettings = settings && settings->allowRunningOfInsecureCo
ntent(); |
398 allowed = client->allowRunningInsecureContent(allowedPerSettings, securi
tyOrigin, url); | 415 allowed = client->allowRunningInsecureContent(allowedPerSettings, securi
tyOrigin, url); |
399 } | 416 } |
400 | 417 |
401 if (allowed) | 418 if (allowed) |
402 client->didRunInsecureContent(securityOrigin, url); | 419 client->didRunInsecureContent(securityOrigin, url); |
403 | 420 |
404 if (reportingStatus == SendReport) | 421 if (reportingStatus == SendReport) |
405 logToConsoleAboutWebSocket(frame, url, allowed); | 422 logToConsoleAboutWebSocket(frame, mainResourceUrlForFrame(mixedFrame), u
rl, allowed); |
406 return !allowed; | 423 return !allowed; |
407 } | 424 } |
408 | 425 |
409 bool MixedContentChecker::isMixedFormAction(LocalFrame* frame, const KURL& url,
ReportingStatus reportingStatus) | 426 bool MixedContentChecker::isMixedFormAction(LocalFrame* frame, const KURL& url,
ReportingStatus reportingStatus) |
410 { | 427 { |
411 // For whatever reason, some folks handle forms via JavaScript, and submit t
o `javascript:void(0)` | 428 // For whatever reason, some folks handle forms via JavaScript, and submit t
o `javascript:void(0)` |
412 // rather than calling `preventDefault()`. We special-case `javascript:` URL
s here, as they don't | 429 // rather than calling `preventDefault()`. We special-case `javascript:` URL
s here, as they don't |
413 // introduce MixedContent for form submissions. | 430 // introduce MixedContent for form submissions. |
414 if (url.protocolIs("javascript")) | 431 if (url.protocolIs("javascript")) |
415 return false; | 432 return false; |
416 | 433 |
417 LocalFrame* mixedFrame = inWhichFrameIsContentMixed(frame, WebURLRequest::Fr
ameTypeNone, url); | 434 Frame* mixedFrame = inWhichFrameIsContentMixed(frame, WebURLRequest::FrameTy
peNone, url); |
418 if (!mixedFrame) | 435 if (!mixedFrame) |
419 return false; | 436 return false; |
420 | 437 |
421 UseCounter::count(mixedFrame, UseCounter::MixedContentPresent); | 438 UseCounter::count(mixedFrame, UseCounter::MixedContentPresent); |
422 | 439 |
423 mixedFrame->loader().client()->didDisplayInsecureContent(); | 440 // Use the current local frame's client; the embedder doesn't |
| 441 // distinguish mixed content signals from different frames on the |
| 442 // same page. |
| 443 frame->loader().client()->didDisplayInsecureContent(); |
424 | 444 |
425 if (reportingStatus == SendReport) { | 445 if (reportingStatus == SendReport) { |
426 String message = String::format( | 446 String message = String::format( |
427 "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.", | 447 "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.", |
428 frame->document()->url().elidedString().utf8().data(), url.elidedStr
ing().utf8().data()); | 448 mainResourceUrlForFrame(mixedFrame).elidedString().utf8().data(), ur
l.elidedString().utf8().data()); |
429 mixedFrame->document()->addConsoleMessage(ConsoleMessage::create(Securit
yMessageSource, WarningMessageLevel, message)); | 449 frame->document()->addConsoleMessage(ConsoleMessage::create(SecurityMess
ageSource, WarningMessageLevel, message)); |
430 } | 450 } |
431 | 451 |
432 return true; | 452 return true; |
433 } | 453 } |
434 | 454 |
435 void MixedContentChecker::checkMixedPrivatePublic(LocalFrame* frame, const Atomi
cString& resourceIPAddress) | 455 void MixedContentChecker::checkMixedPrivatePublic(LocalFrame* frame, const Atomi
cString& resourceIPAddress) |
436 { | 456 { |
437 if (!frame || !frame->document() || !frame->document()->loader()) | 457 if (!frame || !frame->document() || !frame->document()->loader()) |
438 return; | 458 return; |
439 | 459 |
440 // Just count these for the moment, don't block them. | 460 // Just count these for the moment, don't block them. |
441 if (Platform::current()->isReservedIPAddress(resourceIPAddress) && !frame->d
ocument()->isHostedInReservedIPRange()) | 461 if (Platform::current()->isReservedIPAddress(resourceIPAddress) && !frame->d
ocument()->isHostedInReservedIPRange()) |
442 UseCounter::count(frame->document(), UseCounter::MixedContentPrivateHost
nameInPublicHostname); | 462 UseCounter::count(frame->document(), UseCounter::MixedContentPrivateHost
nameInPublicHostname); |
443 } | 463 } |
444 | 464 |
445 LocalFrame* MixedContentChecker::effectiveFrameForFrameType(LocalFrame* frame, W
ebURLRequest::FrameType frameType) | 465 Frame* MixedContentChecker::effectiveFrameForFrameType(LocalFrame* frame, WebURL
Request::FrameType frameType) |
446 { | 466 { |
447 // If we're loading the main resource of a subframe, ensure that we check | 467 // If we're loading the main resource of a subframe, ensure that we check |
448 // against the parent of the active frame, rather than the frame itself. | 468 // against the parent of the active frame, rather than the frame itself. |
449 LocalFrame* effectiveFrame = frame; | 469 if (frameType != WebURLRequest::FrameTypeNested) |
450 if (frameType == WebURLRequest::FrameTypeNested) { | 470 return frame; |
451 // FIXME: Deal with RemoteFrames. | 471 |
452 Frame* parentFrame = effectiveFrame->tree().parent(); | 472 Frame* parentFrame = frame->tree().parent(); |
453 ASSERT(parentFrame); | 473 ASSERT(parentFrame); |
454 if (parentFrame->isLocalFrame()) | 474 return parentFrame; |
455 effectiveFrame = toLocalFrame(parentFrame); | |
456 } | |
457 return effectiveFrame; | |
458 } | 475 } |
459 | 476 |
460 void MixedContentChecker::handleCertificateError(LocalFrame* frame, const Resour
ceRequest& request, const ResourceResponse& response) | 477 void MixedContentChecker::handleCertificateError(LocalFrame* frame, const Resour
ceRequest& request, const ResourceResponse& response) |
461 { | 478 { |
462 WebURLRequest::FrameType frameType = request.frameType(); | 479 WebURLRequest::FrameType frameType = request.frameType(); |
463 LocalFrame* effectiveFrame = effectiveFrameForFrameType(frame, frameType); | 480 Frame* effectiveFrame = effectiveFrameForFrameType(frame, frameType); |
464 if (frameType == WebURLRequest::FrameTypeTopLevel || !effectiveFrame) | 481 if (frameType == WebURLRequest::FrameTypeTopLevel || !effectiveFrame) |
465 return; | 482 return; |
466 | 483 |
467 FrameLoaderClient* client = effectiveFrame->loader().client(); | 484 // TODO(estark): handle remote frames, perhaps by omitting security info whe
n the effective frame is remote. |
| 485 if (!effectiveFrame->isLocalFrame()) |
| 486 return; |
| 487 |
| 488 LocalFrame* localEffectiveFrame = toLocalFrame(effectiveFrame); |
| 489 |
| 490 // Use the current local frame's client; the embedder doesn't |
| 491 // distinguish mixed content signals from different frames on the |
| 492 // same page. |
| 493 FrameLoaderClient* client = frame->loader().client(); |
468 WebURLRequest::RequestContext requestContext = request.requestContext(); | 494 WebURLRequest::RequestContext requestContext = request.requestContext(); |
469 ContextType contextType = MixedContentChecker::contextTypeFromContext(reques
tContext, frame); | 495 ContextType contextType = MixedContentChecker::contextTypeFromContext(reques
tContext, effectiveFrame); |
470 if (contextType == ContextTypeBlockable) { | 496 if (contextType == ContextTypeBlockable) { |
471 client->didRunContentWithCertificateErrors(response.url(), response.getS
ecurityInfo(), effectiveFrame->document()->url(), effectiveFrame->loader().docum
entLoader()->response().getSecurityInfo()); | 497 client->didRunContentWithCertificateErrors(response.url(), response.getS
ecurityInfo(), mainResourceUrlForFrame(effectiveFrame), localEffectiveFrame->loa
der().documentLoader()->response().getSecurityInfo()); |
472 } else { | 498 } else { |
473 // contextTypeFromContext() never returns NotMixedContent (it | 499 // contextTypeFromContext() never returns NotMixedContent (it |
474 // computes the type of mixed content, given that the content is | 500 // computes the type of mixed content, given that the content is |
475 // mixed). | 501 // mixed). |
476 ASSERT(contextType != ContextTypeNotMixedContent); | 502 ASSERT(contextType != ContextTypeNotMixedContent); |
477 client->didDisplayContentWithCertificateErrors(response.url(), response.
getSecurityInfo(), effectiveFrame->document()->url(), effectiveFrame->loader().d
ocumentLoader()->response().getSecurityInfo()); | 503 client->didDisplayContentWithCertificateErrors(response.url(), response.
getSecurityInfo(), mainResourceUrlForFrame(effectiveFrame), localEffectiveFrame-
>loader().documentLoader()->response().getSecurityInfo()); |
478 } | 504 } |
479 } | 505 } |
480 | 506 |
481 MixedContentChecker::ContextType MixedContentChecker::contextTypeForInspector(Lo
calFrame* frame, const ResourceRequest& request) | 507 MixedContentChecker::ContextType MixedContentChecker::contextTypeForInspector(Lo
calFrame* frame, const ResourceRequest& request) |
482 { | 508 { |
483 LocalFrame* effectiveFrame = effectiveFrameForFrameType(frame, request.frame
Type()); | 509 Frame* effectiveFrame = effectiveFrameForFrameType(frame, request.frameType(
)); |
484 | 510 |
485 LocalFrame* mixedFrame = inWhichFrameIsContentMixed(effectiveFrame, request.
frameType(), request.url()); | 511 Frame* mixedFrame = inWhichFrameIsContentMixed(effectiveFrame, request.frame
Type(), request.url()); |
486 if (!mixedFrame) | 512 if (!mixedFrame) |
487 return ContextTypeNotMixedContent; | 513 return ContextTypeNotMixedContent; |
488 | 514 |
489 // See comment in shouldBlockFetch() about loading the main resource of a su
bframe. | 515 // See comment in shouldBlockFetch() about loading the main resource of a su
bframe. |
490 if (request.frameType() == WebURLRequest::FrameTypeNested && !SchemeRegistry
::shouldTreatURLSchemeAsCORSEnabled(request.url().protocol())) { | 516 if (request.frameType() == WebURLRequest::FrameTypeNested && !SchemeRegistry
::shouldTreatURLSchemeAsCORSEnabled(request.url().protocol())) { |
491 return ContextTypeOptionallyBlockable; | 517 return ContextTypeOptionallyBlockable; |
492 } | 518 } |
493 | 519 |
494 return contextTypeFromContext(request.requestContext(), mixedFrame); | 520 return contextTypeFromContext(request.requestContext(), mixedFrame); |
495 } | 521 } |
496 | 522 |
497 } // namespace blink | 523 } // namespace blink |
OLD | NEW |