| 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 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 47 | 47 |
| 48 namespace blink { | 48 namespace blink { |
| 49 | 49 |
| 50 namespace { | 50 namespace { |
| 51 | 51 |
| 52 // When a frame is local, use its full URL to represent the main resource. When | 52 // When a frame is local, use its full URL to represent the main resource. When |
| 53 // the frame is remote, the full URL isn't accessible, so use the origin. This | 53 // the frame is remote, the full URL isn't accessible, so use the origin. This |
| 54 // function is used, for example, to determine the URL to show in console | 54 // function is used, for example, to determine the URL to show in console |
| 55 // messages about mixed content. | 55 // messages about mixed content. |
| 56 KURL mainResourceUrlForFrame(Frame* frame) { | 56 KURL mainResourceUrlForFrame(Frame* frame) { |
| 57 if (frame->isRemoteFrame()) | 57 if (frame->isRemoteFrame()) { |
| 58 return KURL(KURL(), | 58 return KURL(KURL(), |
| 59 frame->securityContext()->getSecurityOrigin()->toString()); | 59 frame->securityContext()->getSecurityOrigin()->toString()); |
| 60 } |
| 60 return toLocalFrame(frame)->document()->url(); | 61 return toLocalFrame(frame)->document()->url(); |
| 61 } | 62 } |
| 62 | 63 |
| 63 } // namespace | 64 } // namespace |
| 64 | 65 |
| 65 static void measureStricterVersionOfIsMixedContent(Frame* frame, | 66 static void measureStricterVersionOfIsMixedContent(Frame* frame, |
| 66 const KURL& url) { | 67 const KURL& url) { |
| 67 // We're currently only checking for mixed content in `https://*` contexts. | 68 // We're currently only checking for mixed content in `https://*` contexts. |
| 68 // What about other "secure" contexts the SchemeRegistry knows about? We'll | 69 // What about other "secure" contexts the SchemeRegistry knows about? We'll |
| 69 // use this method to measure the occurance of non-webby mixed content to make | 70 // use this method to measure the occurance of non-webby mixed content to make |
| 70 // sure we're not breaking the world without realizing it. | 71 // sure we're not breaking the world without realizing it. |
| 71 SecurityOrigin* origin = frame->securityContext()->getSecurityOrigin(); | 72 SecurityOrigin* origin = frame->securityContext()->getSecurityOrigin(); |
| 72 if (MixedContentChecker::isMixedContent(origin, url)) { | 73 if (MixedContentChecker::isMixedContent(origin, url)) { |
| 73 if (origin->protocol() != "https") | 74 if (origin->protocol() != "https") { |
| 74 UseCounter::count( | 75 UseCounter::count( |
| 75 frame, | 76 frame, |
| 76 UseCounter::MixedContentInNonHTTPSFrameThatRestrictsMixedContent); | 77 UseCounter::MixedContentInNonHTTPSFrameThatRestrictsMixedContent); |
| 78 } |
| 77 } else if (!SecurityOrigin::isSecure(url) && | 79 } else if (!SecurityOrigin::isSecure(url) && |
| 78 SchemeRegistry::shouldTreatURLSchemeAsSecure(origin->protocol())) { | 80 SchemeRegistry::shouldTreatURLSchemeAsSecure(origin->protocol())) { |
| 79 UseCounter::count( | 81 UseCounter::count( |
| 80 frame, | 82 frame, |
| 81 UseCounter::MixedContentInSecureFrameThatDoesNotRestrictMixedContent); | 83 UseCounter::MixedContentInSecureFrameThatDoesNotRestrictMixedContent); |
| 82 } | 84 } |
| 83 } | 85 } |
| 84 | 86 |
| 85 bool requestIsSubframeSubresource(Frame* frame, | 87 bool requestIsSubframeSubresource(Frame* frame, |
| 86 WebURLRequest::FrameType frameType) { | 88 WebURLRequest::FrameType frameType) { |
| (...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 299 case WebMixedContent::ContextType::ShouldBeBlockable: | 301 case WebMixedContent::ContextType::ShouldBeBlockable: |
| 300 allowed = !strictMode; | 302 allowed = !strictMode; |
| 301 if (allowed) | 303 if (allowed) |
| 302 client->didDisplayInsecureContent(); | 304 client->didDisplayInsecureContent(); |
| 303 break; | 305 break; |
| 304 case WebMixedContent::ContextType::NotMixedContent: | 306 case WebMixedContent::ContextType::NotMixedContent: |
| 305 NOTREACHED(); | 307 NOTREACHED(); |
| 306 break; | 308 break; |
| 307 }; | 309 }; |
| 308 | 310 |
| 309 if (reportingStatus == SendReport) | 311 if (reportingStatus == SendReport) { |
| 310 logToConsoleAboutFetch(frame, mainResourceUrlForFrame(mixedFrame), url, | 312 logToConsoleAboutFetch(frame, mainResourceUrlForFrame(mixedFrame), url, |
| 311 requestContext, allowed); | 313 requestContext, allowed); |
| 314 } |
| 312 return !allowed; | 315 return !allowed; |
| 313 } | 316 } |
| 314 | 317 |
| 315 // static | 318 // static |
| 316 void MixedContentChecker::logToConsoleAboutWebSocket( | 319 void MixedContentChecker::logToConsoleAboutWebSocket( |
| 317 LocalFrame* frame, | 320 LocalFrame* frame, |
| 318 const KURL& mainResourceUrl, | 321 const KURL& mainResourceUrl, |
| 319 const KURL& url, | 322 const KURL& url, |
| 320 bool allowed) { | 323 bool allowed) { |
| 321 String message = String::format( | 324 String message = String::format( |
| (...skipping 16 matching lines...) Expand all Loading... |
| 338 const KURL& url, | 341 const KURL& url, |
| 339 MixedContentChecker::ReportingStatus reportingStatus) { | 342 MixedContentChecker::ReportingStatus reportingStatus) { |
| 340 Frame* mixedFrame = | 343 Frame* mixedFrame = |
| 341 inWhichFrameIsContentMixed(frame, WebURLRequest::FrameTypeNone, url); | 344 inWhichFrameIsContentMixed(frame, WebURLRequest::FrameTypeNone, url); |
| 342 if (!mixedFrame) | 345 if (!mixedFrame) |
| 343 return false; | 346 return false; |
| 344 | 347 |
| 345 UseCounter::count(mixedFrame, UseCounter::MixedContentPresent); | 348 UseCounter::count(mixedFrame, UseCounter::MixedContentPresent); |
| 346 UseCounter::count(mixedFrame, UseCounter::MixedContentWebSocket); | 349 UseCounter::count(mixedFrame, UseCounter::MixedContentWebSocket); |
| 347 if (ContentSecurityPolicy* policy = | 350 if (ContentSecurityPolicy* policy = |
| 348 frame->securityContext()->contentSecurityPolicy()) | 351 frame->securityContext()->contentSecurityPolicy()) { |
| 349 policy->reportMixedContent(url, | 352 policy->reportMixedContent(url, |
| 350 ResourceRequest::RedirectStatus::NoRedirect); | 353 ResourceRequest::RedirectStatus::NoRedirect); |
| 354 } |
| 351 | 355 |
| 352 Settings* settings = mixedFrame->settings(); | 356 Settings* settings = mixedFrame->settings(); |
| 353 // Use the current local frame's client; the embedder doesn't distinguish | 357 // Use the current local frame's client; the embedder doesn't distinguish |
| 354 // mixed content signals from different frames on the same page. | 358 // mixed content signals from different frames on the same page. |
| 355 FrameLoaderClient* client = frame->loader().client(); | 359 FrameLoaderClient* client = frame->loader().client(); |
| 356 SecurityOrigin* securityOrigin = | 360 SecurityOrigin* securityOrigin = |
| 357 mixedFrame->securityContext()->getSecurityOrigin(); | 361 mixedFrame->securityContext()->getSecurityOrigin(); |
| 358 bool allowed = false; | 362 bool allowed = false; |
| 359 | 363 |
| 360 // If we're in strict mode, we'll automagically fail everything, and | 364 // If we're in strict mode, we'll automagically fail everything, and |
| 361 // intentionally skip the client checks in order to prevent degrading the | 365 // intentionally skip the client checks in order to prevent degrading the |
| 362 // site's security UI. | 366 // site's security UI. |
| 363 bool strictMode = mixedFrame->securityContext()->getInsecureRequestPolicy() & | 367 bool strictMode = mixedFrame->securityContext()->getInsecureRequestPolicy() & |
| 364 kBlockAllMixedContent || | 368 kBlockAllMixedContent || |
| 365 settings->strictMixedContentChecking(); | 369 settings->strictMixedContentChecking(); |
| 366 if (!strictMode) { | 370 if (!strictMode) { |
| 367 bool allowedPerSettings = | 371 bool allowedPerSettings = |
| 368 settings && settings->allowRunningOfInsecureContent(); | 372 settings && settings->allowRunningOfInsecureContent(); |
| 369 allowed = client->allowRunningInsecureContent(allowedPerSettings, | 373 allowed = client->allowRunningInsecureContent(allowedPerSettings, |
| 370 securityOrigin, url); | 374 securityOrigin, url); |
| 371 } | 375 } |
| 372 | 376 |
| 373 if (allowed) | 377 if (allowed) |
| 374 client->didRunInsecureContent(securityOrigin, url); | 378 client->didRunInsecureContent(securityOrigin, url); |
| 375 | 379 |
| 376 if (reportingStatus == SendReport) | 380 if (reportingStatus == SendReport) { |
| 377 logToConsoleAboutWebSocket(frame, mainResourceUrlForFrame(mixedFrame), url, | 381 logToConsoleAboutWebSocket(frame, mainResourceUrlForFrame(mixedFrame), url, |
| 378 allowed); | 382 allowed); |
| 383 } |
| 379 return !allowed; | 384 return !allowed; |
| 380 } | 385 } |
| 381 | 386 |
| 382 bool MixedContentChecker::isMixedFormAction(LocalFrame* frame, | 387 bool MixedContentChecker::isMixedFormAction(LocalFrame* frame, |
| 383 const KURL& url, | 388 const KURL& url, |
| 384 ReportingStatus reportingStatus) { | 389 ReportingStatus reportingStatus) { |
| 385 // For whatever reason, some folks handle forms via JavaScript, and submit to | 390 // For whatever reason, some folks handle forms via JavaScript, and submit to |
| 386 // `javascript:void(0)` rather than calling `preventDefault()`. We | 391 // `javascript:void(0)` rather than calling `preventDefault()`. We |
| 387 // special-case `javascript:` URLs here, as they don't introduce MixedContent | 392 // special-case `javascript:` URLs here, as they don't introduce MixedContent |
| 388 // for form submissions. | 393 // for form submissions. |
| (...skipping 26 matching lines...) Expand all Loading... |
| 415 } | 420 } |
| 416 | 421 |
| 417 void MixedContentChecker::checkMixedPrivatePublic( | 422 void MixedContentChecker::checkMixedPrivatePublic( |
| 418 LocalFrame* frame, | 423 LocalFrame* frame, |
| 419 const AtomicString& resourceIPAddress) { | 424 const AtomicString& resourceIPAddress) { |
| 420 if (!frame || !frame->document() || !frame->document()->loader()) | 425 if (!frame || !frame->document() || !frame->document()->loader()) |
| 421 return; | 426 return; |
| 422 | 427 |
| 423 // Just count these for the moment, don't block them. | 428 // Just count these for the moment, don't block them. |
| 424 if (NetworkUtils::isReservedIPAddress(resourceIPAddress) && | 429 if (NetworkUtils::isReservedIPAddress(resourceIPAddress) && |
| 425 frame->document()->addressSpace() == WebAddressSpacePublic) | 430 frame->document()->addressSpace() == WebAddressSpacePublic) { |
| 426 UseCounter::count(frame->document(), | 431 UseCounter::count(frame->document(), |
| 427 UseCounter::MixedContentPrivateHostnameInPublicHostname); | 432 UseCounter::MixedContentPrivateHostnameInPublicHostname); |
| 433 } |
| 428 } | 434 } |
| 429 | 435 |
| 430 Frame* MixedContentChecker::effectiveFrameForFrameType( | 436 Frame* MixedContentChecker::effectiveFrameForFrameType( |
| 431 LocalFrame* frame, | 437 LocalFrame* frame, |
| 432 WebURLRequest::FrameType frameType) { | 438 WebURLRequest::FrameType frameType) { |
| 433 // If we're loading the main resource of a subframe, ensure that we check | 439 // If we're loading the main resource of a subframe, ensure that we check |
| 434 // against the parent of the active frame, rather than the frame itself. | 440 // against the parent of the active frame, rather than the frame itself. |
| 435 if (frameType != WebURLRequest::FrameTypeNested) | 441 if (frameType != WebURLRequest::FrameTypeNested) |
| 436 return frame; | 442 return frame; |
| 437 | 443 |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 488 } | 494 } |
| 489 | 495 |
| 490 bool strictMixedContentCheckingForPlugin = | 496 bool strictMixedContentCheckingForPlugin = |
| 491 mixedFrame->settings() && | 497 mixedFrame->settings() && |
| 492 mixedFrame->settings()->strictMixedContentCheckingForPlugin(); | 498 mixedFrame->settings()->strictMixedContentCheckingForPlugin(); |
| 493 return WebMixedContent::contextTypeFromRequestContext( | 499 return WebMixedContent::contextTypeFromRequestContext( |
| 494 request.requestContext(), strictMixedContentCheckingForPlugin); | 500 request.requestContext(), strictMixedContentCheckingForPlugin); |
| 495 } | 501 } |
| 496 | 502 |
| 497 } // namespace blink | 503 } // namespace blink |
| OLD | NEW |